[Struts] rozwijana lista za pomoca html:optionsCollection
pjotr - 06-01-2007 00:03
[Struts] rozwijana lista za pomoca html:optionsCollection
Witam wszystkich,
jestem poczatkujacy w Struts i mam problem ze zrobieniem rozwijanej listy (chcialbym skorzystac z tagu <html:options> lub <html:optionsColletion>) produktow.
Klasa produktow: public class Produkt {
private String grupa,symbol,nazwa,cena; private int ilosc,idProd,idGrupy;
/* + metody getXXX i setXX */
}
i formularz:
public class ZamowienieForm extends org.apache.struts.action.ActionForm {
private ArrayList products; private ArrayList selectedProducts;
public void setProducts(ArrayList l){ this.products=l;
} public ArrayList getProducts(){ return (this.products); } public void setSelectedProducts(ArrayList l){ this.selectedProducts=l; } public ArrayList getSelectedProducts(){ return this.selectedProducts; } /*
liste produktow pobieram z bazy danych i zapelniam w konstruktorze formularza - czy to jest poprawny sposob?
*/ }
Chodzi mi o zrobienie listy rozwijanej, w ktorej beda znajdowac sie dane produktow (id, symbol,nazwa,cena etc) np. pooddzielane przecinkeim lub innym znakiem, z ktorej uzytkownik wybiera sobie produkty do koszyka. Cos w stylu:
<html:select name="ZamowienieForm" property="selectedProducts"> <html:optionsCollection name="ZamowienieForm" property="products"/> </html:select>
Nie moge jakos w tym sie polapac-czy ktos moglby mi pomoc? Z gory dziekuje za wszelkie sugestie..
Pozdrawiam PT
Mikolaj Rydzewski - 06-01-2007 00:03
pjotr <pjotr@o2.pl> wrote:
> Chodzi mi o zrobienie listy rozwijanej, w ktorej beda znajdowac sie > dane produktow (id, symbol,nazwa,cena etc) np. pooddzielane przecinkeim > lub innym znakiem, z ktorej uzytkownik wybiera sobie produkty do > koszyka. Cos w stylu:
Do klasy Produkt dodajesz metode zwracajaca pozadany tekst, np:
public String getSelectLabel() { return grupa + ", " + symbol; }
W formularzu zmieniasz typ selectedProducts na tablice stringow (no i oczywiscie settery/gettery):
private String[] selectedProducts;
I pokrywasz metode reset wg opisu na http://struts.apache.org/1.3.5/strut...ml/select.html
A na stronie jsp:
<html:select name="ZamowienieForm" property="selectedProducts" multiple="true"> <html:optionsCollection name="ZamowienieForm" property="products" value="symbol" label="selectLabel"/> </html:select>
I po submicie w selectedProducts bedziesz mial tablice symboli wybranych produktow.
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women, and unix.
pjotr - 06-01-2007 00:03
Mikolaj Rydzewski napisał(a): > > Do klasy Produkt dodajesz metode zwracajaca pozadany tekst, np: > > public String getSelectLabel() { > return grupa + ", " + symbol; > }
tak zrobilem. Zrobilem tez setSelectLabel (wyluskuje wartosci po ',' i wrzucam do odpowiednich pol w klasie Produkt)
> > W formularzu zmieniasz typ selectedProducts na tablice stringow (no i > oczywiscie settery/gettery): > > private String[] selectedProducts; >
public void setSelectedProducts(String s){ int index=this.selectedProducts.length; this.selectedProducts[index]=s; } public String[] getSelectedProducts(){ return this.selectedProducts; }
Czy moze getSelectedProducts() powinno zwracas pojedynczego Stringa (chociaz to sie wydaje bez sensu) ?
> I pokrywasz metode reset wg opisu na > http://struts.apache.org/1.3.5/strut...ml/select.html >
public void reset(ActionMapping mapping, HttpServletRequest request) { this.products=null; this.selectedProducts=null; }
> A na stronie jsp: > > <html:select name="ZamowienieForm" property="selectedProducts" > multiple="true"> > <html:optionsCollection name="ZamowienieForm" property="products" > value="symbol" label="selectLabel"/> > </html:select>
tutaj zmienilem 'value' na 'idProd':
<html:optionsCollection name="ZamowienieForm" property="products" value="idProd" label="selectLabel"/>
Pytanie: czy gettery i settery w klasie Produkt powinny operowac wylacznie na Stringach (w przypadku setIdProd i getIdProd potrzebna konwersja do/z int) ?
> > I po submicie w selectedProducts bedziesz mial tablice symboli wybranych > produktow.
wywala mi sie wyjatek:
javax.servlet.jsp.JspException: Failed to obtain specified collection org.apache.struts.taglib.html.OptionsCollectionTag .doStartTag(OptionsCollectionTag.java:176) org.apache.jsp.edycjaZamowienia_jsp._jspx_meth_htm l_optionsCollection_0(edycjaZamowienia_jsp.java:27 6) org.apache.jsp.edycjaZamowienia_jsp._jspx_meth_htm l_select_0(edycjaZamowienia_jsp.java:244) org.apache.jsp.edycjaZamowienia_jsp._jspService(ed ycjaZamowienia_jsp.java:106)
Co dalej? Pozdrawiam PT
Mikolaj Rydzewski - 06-01-2007 00:03
pjotr <pjotr@o2.pl> wrote: > Mikolaj Rydzewski napisał(a): >> >> Do klasy Produkt dodajesz metode zwracajaca pozadany tekst, np: >> >> public String getSelectLabel() { >> return grupa + ", " + symbol; >> } > > tak zrobilem. Zrobilem tez setSelectLabel (wyluskuje wartosci po ',' i > wrzucam do odpowiednich pol w klasie Produkt)
Nie ma potrzeby. Tylko getter.
>> W formularzu zmieniasz typ selectedProducts na tablice stringow (no i >> oczywiscie settery/gettery): >> >> private String[] selectedProducts; >> > > public void setSelectedProducts(String s){ > int index=this.selectedProducts.length; > this.selectedProducts[index]=s; > }
Eeee, no co ty ;-) Najzwyklejszy setter dla calej tablicy, analogiczny do gettera ktorego zrobiles.
>> I pokrywasz metode reset wg opisu na >> http://struts.apache.org/1.3.5/strut...ml/select.html >> > > public void reset(ActionMapping mapping, HttpServletRequest request) { > this.products=null; > this.selectedProducts=null;
Tam raczej chodzilo o cos takiego:
this.selectedProducts = new String[0];
Bo tablica o rozmiarze 0 to nie jest to samo co brak tablicy.
> Pytanie: czy gettery i settery w klasie Produkt powinny operowac > wylacznie na Stringach (w przypadku setIdProd i getIdProd potrzebna > konwersja do/z int) ?
No to juz zalezy tylko od ciebie i twoich potrzeb ;-)
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women, and unix.
pjotr - 07-01-2007 00:11
Mikolaj Rydzewski napisał(a):
> Tam raczej chodzilo o cos takiego: > > this.selectedProducts = new String[0]; > > Bo tablica o rozmiarze 0 to nie jest to samo co brak tablicy. > > > Pytanie: czy gettery i settery w klasie Produkt powinny operowac > > wylacznie na Stringach (w przypadku setIdProd i getIdProd potrzebna > > konwersja do/z int) ? > > No to juz zalezy tylko od ciebie i twoich potrzeb ;-) >
Nie dostaje juz wyjatkow ale po przejsciu na strone lista wyboru jest pusta! Wyglada na to ze cala lista produktow jest pusta gdyz:
<logic:iterate id="prod" name="ZamowienieForm" property="products" type="com.myapp.struts.ZamowienieForm"> <b>bee</b> </logic:iterate>
nie wyswietla mi nic. Moze cos pomieszalem ze scopem? W Akcji w metodzie execute() jest co prawda:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session=request.getSession(true); ZamowienieForm zamowienieForm=(ZamowienieForm)form; session.setAttribute("ZamowienieForm",zamowienieFo rm); /* ... */ }
a liste produktow wypelniam w konstruktorze Formularza - w ktorym miejscu lista jest gubiona?
=?ISO-8859-2?Q?Miko=B3aj_Rydzewski?= - 07-01-2007 00:11
pjotr wrote:
> nie wyswietla mi nic. Moze cos pomieszalem ze scopem? W Akcji w > metodzie execute() jest co prawda: > > public ActionForward execute(ActionMapping mapping, ActionForm form, > HttpServletRequest request, HttpServletResponse response) > throws Exception { > > HttpSession session=request.getSession(true); > ZamowienieForm zamowienieForm=(ZamowienieForm)form; > session.setAttribute("ZamowienieForm",zamowienieFo rm); > /* ... */ > } > > a liste produktow wypelniam w konstruktorze Formularza - w ktorym > miejscu lista jest gubiona?
Pokaz jeszcze jaka masz definicje akcji w struts-config. Z tego co piszesz, to robisz calosc zupelnie nie tak jak trzeba. W tutorialu wszystko jest opisane: http://struts.apache.org/1.3.5/userGuide/
Z grubsza trzeba robic tak:
Definiujesz formularz w sekcji form-beans. Definiujac akcje jako wartosc atrybutu 'name' podajesz wartosc atrybutu 'name' z definicji odpowiedniego formularza. Konstruktora formularza wogole nie ruszasz. A potem w kodzie akcji:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ZamowienieForm zamowienieForm=(ZamowienieForm)form; zamowienieForm.setProducts(<tutaj kod pobierajacy produkty>); return mapping.findForward(<nazwa>); }
Strutsy same utworza nowy obiekt formularza, badz pobiora juz istniejacy, w zaleznosci do scope podanego w definicji akcji.
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women and unix.
pjotr - 07-01-2007 00:11
Mikołaj Rydzewski napisał(a): > > Pokaz jeszcze jaka masz definicje akcji w struts-config. Z tego co > piszesz, to robisz calosc zupelnie nie tak jak trzeba. W tutorialu > wszystko jest opisane: http://struts.apache.org/1.3.5/userGuide/ >
<form-beans> <form-bean name="ZamowienieForm" type="com.myapp.struts.ZamowienieForm"> <form-property initial="" name="ZamowieneBean" type="com.myapp.struts.ZamowienieBean"/> </form-bean>
[...]
<action input="/index.jsp" name="ZamowienieForm" path="/noweZamowienie" scope="session" type="com.myapp.struts.noweZamowienieAction" validate="false"> <forward name="success" path="/edycjaZamowienia.jsp"/> <forward name="fail" path="/index.jsp"/> </action>
<action input="/edycjaZamowienia.jsp" name="ZamowienieForm" path="/AddSelectedProduct" scope="session" type="com.myapp.struts.AddSelectedProductAction" validate="false"> <forward name="success" path="/edycjaZamowienia.jsp"/> </action>
> Z grubsza trzeba robic tak: > > public ActionForward execute(ActionMapping mapping, ActionForm form, > HttpServletRequest request, HttpServletResponse response) > throws Exception { > ZamowienieForm zamowienieForm=(ZamowienieForm)form; > zamowienieForm.setProducts(<tutaj kod pobierajacy produkty>); > return mapping.findForward(<nazwa>); > } >
Wyswietlanie juz mi dziala, dane produktow przenioslem do nowej klasy (ktora ma reprezentowac 'business logic': dodawanie/usuwanie zamowien do/z bazy, edycja itd - czy slusznie?):
public class ZamowienieBean implements java.io.Serializable {
private int nr_zam; private ArrayList products=null; private String[] selectedProducts=null; private String nazwa,adres=null;
public ZamowienieBean(){ this.nr_zam=0; this.products=new ArrayList(); this.addProductsToBean();
/*tutaj lacze sie z baza i wrzucam liste produktow */
this.nazwa=this.adres=""; this.selectedProducts = new String[0]; } /* +settery i gettery dla pol */
public void setSelectedProducts(String[] s){ this.selectedProducts=s; } public String[] getSelectedProducts(){ if(this.selectedProducts.length==0) return null;
/*to dodalem zeby moc skorzystac z <logic:iterate> */
else return this.selectedProducts; } }
w Formularzu mam tylko:
public class ZamowienieForm extends org.apache.struts.action.ActionForm {
private Produkt prod=null; private ZamowienieBean zamowienieBean=null;
[...] public ZamowienieForm() { super(); this.init();
} public void init(){
this.prod=new Produkt(); this.zamowienieBean=new ZamowienieBean(); } public void reset(ActionMapping mapping, HttpServletRequest request) {
this.prod=new Produkt();
/* tutaj celowo nie resetuje ZamowienieBean zeby nie ladowac listy produktow za kazdym razem*/
}
a na stronie JSP:
<html:form action="AddSelectedProduct"> <html:select name="ZamowienieBean" property="selectedProducts" multiple="true"> <html:optionsCollection property="products" name="ZamowienieBean" value="symbol" label="selectLabel"/> </html:select> <html:submit value="Go!"/> </html:form>
i jeszcza akcja AddSelectedProducts:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session=request.getSession(true); ZamowienieForm zamowienieForm=(ZamowienieForm)form; session.setAttribute("ZamowienieForm",zamowienieFo rm);
session.setAttribute("ZamowienieBean",zamowienieFo rm.getZamowienieBean());
if(zamowienieForm.getZamowienieBean().getSelectedP roducts()==null){ throw new Exception("Lista wybranych produktow jest pusta."); } return mapping.findForward(SUCCESS); }
i wlasnie tuaj mi wyrzuca wyjatek:
java.lang.Exception: Lista wybranych produktow jest pusta. com.myapp.struts.AddSelectedProductAction.execute( AddSelectedProductAction..java:47)
Nie wiem w jaki sposob trace liste wybranych produktow - czy znacznik <html:select name="ZamowienieBean" property="selectedProducts" multiple="true"> nie wrzuci mi automatycznie wybranych Stringow do selectedProducts w ZamowienieBean wewnatrz ZamowienieForm ?
Nie wiem czy robie slusznie, ze mam jedna strone do edycji i wyswietlania zamowienia-po wybraniu produktow chce zeby obok byla wyswietlana tabelka z produktami (w ktorej mozna zmieniac ilosc produktow i je usuwac):
<logic:present name="ZamowienieBean" property="selectedProducts">
<table>
<tutaj jakas petla w ktorej wyswietlane sa selectedProducts + formularze do zmiany ilosci i usuwania>
</table>
</logic:present>
=?ISO-8859-2?Q?Miko=B3aj_Rydzewski?= - 07-01-2007 00:11
pjotr wrote: > w Formularzu mam tylko: > > public class ZamowienieForm extends org.apache.struts.action.ActionForm > { > > private Produkt prod=null; > private ZamowienieBean zamowienieBean=null; > > [...] > public ZamowienieForm() { > super(); > this.init(); > > } > public void init(){ > > this.prod=new Produkt(); > this.zamowienieBean=new ZamowienieBean(); > } > public void reset(ActionMapping mapping, HttpServletRequest request) { > > this.prod=new Produkt(); > > /* tutaj celowo nie resetuje ZamowienieBean zeby nie ladowac listy > produktow za kazdym razem*/ > > }
Powiedz, dlaczego tak kombinujesz a nie zrobisz tak jak mowilem i jak jest w docach? Kod ladujacy dane do formularzy umiesc w akcjach. Sam formularz ma nic nie robic (wyjatkiem jak walidacja jesli trzeba), on tylko przechowuje dane.
Strutsy daja akcji wlasciwy formularz 'na talerzu'. Tylko trzeba ustawic mu wlasciwe dane i przekazac do jspa.
Form-bean - model, akcja - kontroler, jsp - widok. Model tylko przechowuje dane (a u ciebie samodzielnie laduje je z bazy), kontroler zawiera cala logike, widok zajmuje sie prezentacja. Nie staraj sie tego obchodzic na okolo ;-)
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women and unix.
pjotr - 09-01-2007 00:02
Mikołaj Rydzewski napisał(a): > > Form-bean - model, akcja - kontroler, jsp - widok. Model tylko > przechowuje dane (a u ciebie samodzielnie laduje je z bazy), kontroler > zawiera cala logike, widok zajmuje sie prezentacja. Nie staraj sie tego > obchodzic na okolo ;-) >
no wlasnie wydawalo mi sie ze nie nalezy tego robic w konstruktorze beana - nie rozwiales moich watpliwosci na samym poczatku :) Wielke dzieki za pomoc, wyswietlanie i wybieranie produktow juz dziala, teraz mecze sie z polem do zmiany ilosci produktow, wycinek z JSP:
<logic:iterate id="prod" name="zamowienieBean" property="selectedProductsList" indexId="index"> <tr>
<td> <html:form action="ChangeSelProdQty"> <html:hidden name="zamowienieBean.prod" property="idProd" value="${prod.idProd}"/> <bean:write name="prod" property="idProd"/> </td> <td> <html:hidden name="zamowienieBean" property="prod.symbol" value="${prod.symbol}"/><bean:write name="prod" property="symbol"/> </td> <td> <html:hidden name="zamowienieBean" property="prod.nazwa" value="${prod.nazwa}"/><bean:write name="prod" property="nazwa"/> </td> <td> <html:hidden name="zamowienieBean" property="prod.cena" value="${prod.cena}"/><bean:write name="prod" property="cena"/> </td> <td> <html:text name="zamowienieBean" property="prod.ilosc" value="${prod.ilosc}"/> </td> <td><html:submit value="Ustaw ilosc"/></html:form></td> </td> </tr> </logic:iterate>
w Akcji ChangeSelProdQty wywoluje metode:
public void changeProdQty(Produkt p)throws Exception{ //Produkt pr=(Produkt)selectedProductsList.get(selectedProdu ctsList.indexOf(p));
if(((Produkt)selectedProductsList.get(selectedProd uctsList.indexOf(p))).getIlosc()=="0"){ selectedProductsList.remove(p); } else{
((Produkt)selectedProductsList.get(selectedProduct sList.indexOf(p))).setIlosc(p.getIlosc()); }
}
ktora znajduje odpowiedni produkt na liscie i ustawia mu pole ilosc lub usuwa go z listy gdy wpisze sie 0. Wywala mi taki wyjatek:
java.lang.ArrayIndexOutOfBoundsException: -1 java.util.ArrayList.get(ArrayList.java:323) com.myapp.struts.ZamowienieBean.changeProdQty(Zamo wienieBean.java:166) com.myapp.struts.ChangeSelProdQtyAction.execute(Ch angeSelProdQtyAction.java:43)
z czego wynika, ze selectedProductsList.indexOf(p) zwraca mi -1, czyli nie moze znalezc tego produktu. Czy <logic:iterate> tworzy tymczasowe obiekty na podstawie id (u mnie 'prod' w zamowienieBean) po czym je usuwa jak wychodzi z petli? W razie czego dodalem <html:hidden> zeby struts wrzucil mi dane produktu - ale chyba tez sa tracone. Co z tym zrobic? Czy sensowniejsze byloby zapisywanie np. trzymanie licznika petli (np. jakies <% int count=0; %> i odczytanie go (jesli tak, to gdzie?)
=?ISO-8859-2?Q?Miko=B3aj_Rydzewski?= - 09-01-2007 00:02
pjotr wrote:
> no wlasnie wydawalo mi sie ze nie nalezy tego robic w konstruktorze > beana - nie rozwiales moich watpliwosci na samym poczatku :) Wielke > dzieki za pomoc, wyswietlanie i wybieranie produktow juz dziala, teraz > mecze sie z polem do zmiany ilosci produktow, wycinek z JSP:
Troche to zakrecone no i nie podales calego kodu akcji. Proponuje zebys dodal sobie do projektu biblioteke jakarta-commons-lang, a do formbeana metode:
public void toString() { return ToStringBuilder.reflectionToString(this); }
A nastepnie w akcji zrobil:
System.out.println(form);
Zobaczysz co i jak jest ustawiane.
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women and unix.
pjotr - 10-01-2007 00:15
Mikołaj Rydzewski napisał(a): > > Troche to zakrecone no i nie podales calego kodu akcji. Proponuje zebys > dodal sobie do projektu biblioteke jakarta-commons-lang, a do formbeana > metode: >
oto akcja:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ZamowienieForm zf=(ZamowienieForm)form; HttpSession session=request.getSession(true);
zf.getZamowienieBean().changeProdQty(zf.getZamowie nieBean().getProd()); session.setAttribute("ZamowienieForm",zf); session.setAttribute("zamowienieBean",zf.getZamowi enieBean()); return mapping.findForward(SUCCESS); }
Dlaczego nie da sie tego zrobic w jakis prosty sposob-myslalem ze po to sa dodatkowe tagi zeby wszystko latwo sie robilo :/ Mysle jeszcze o tym zeby wykorzystac atrybut indexId tagu <logic:iterate> i w <html:hidden> ustawic indexed="true" z tym ze atrybut property dla tego tagu musi byc typu String (a potrzebuje Produkt). Czy moze lepiej jest uzyc <bean:define id="prod"> tylko tez nie wiem jak tego uzyc w petli bo wydaje mi sie, ze z kazda iteracja ten bean bedzie nadpisywany.
Mikolaj Rydzewski - 10-01-2007 00:15
pjotr <pjotr@o2.pl> wrote:
> public ActionForward execute(ActionMapping mapping, ActionForm form, > HttpServletRequest request, HttpServletResponse response) > throws Exception { > > ZamowienieForm zf=(ZamowienieForm)form; > HttpSession session=request.getSession(true); > > zf.getZamowienieBean().changeProdQty(zf.getZamowie nieBean().getProd()); > session.setAttribute("ZamowienieForm",zf); > session.setAttribute("zamowienieBean",zf.getZamowi enieBean()); > return mapping.findForward(SUCCESS); > }
Nie nadazam co sie kryje pod nazwa zamowienieBean. Widze, ze jednak dalej usilujesz z modelem robic cos czego nie powinienes. Z formularza pobierasz jakiegos beana i wywolujesz jego metody. Formularz, jak pisalem, tylko przenosi dane z warstwy http (czyli pola z formularza html, stringi, longi, inty, itd.) do warstwy aplikacji. W innych klasach powinienes miec logike przetwarzajaca te dane.
Po co na koncu akcji ustawiasz zmienne w kontekscie sesji? Z pierwszej linijki widac, ze 'zamowienieform' juz jest dla tej akcji ustawiony. Nadpisujesz obiekt nim samym?
Dodaj sobie wypisywanie zawartosci formularza jak sugerowalem, moze cos ci sie wyjasni.
> Dlaczego nie da sie tego zrobic w jakis prosty sposob-myslalem ze po to > sa dodatkowe tagi zeby wszystko latwo sie robilo :/ Mysle jeszcze o tym > zeby wykorzystac atrybut indexId tagu <logic:iterate> i w <html:hidden> > ustawic indexed="true" z tym ze atrybut property dla tego tagu musi byc > typu String (a potrzebuje Produkt). Czy moze lepiej jest uzyc > <bean:define id="prod"> tylko tez nie wiem jak tego uzyc w petli bo > wydaje mi sie, ze z kazda iteracja ten bean bedzie nadpisywany.
To wszystko robi sie bardzo prosto gdy grasz wg odpowiednich zasad ;-) Moze powiedz lepiej co chcesz osiagnac tym formularzem. Wygenerowany html wyglada w porzadku? Wszystkie pola formularza maja odpowiednie wartosci? No to zobaczy czy akcja dostaje formularz z takimi wartosciami jakie miales na stronie.
Formularz z poprzedniego postu wysyla 5 pol: idProd, prod.symbol, prod.nazwa, prod.cena i prod.ilosc. Musisz takie miec w formularzu podpietym do tej akcji. Nie prosciej miec tylko dwa pola: id produktu oraz ilosc?
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women, and unix.
pjotr - 11-01-2007 00:09
On 9 Sty, 15:25, Mikolaj Rydzewski <m...@ceti.pl> wrote: > > > }Nie nadazam co sie kryje pod nazwa zamowienieBean. Widze, ze jednak > dalej usilujesz z modelem robic cos czego nie powinienes. Z formularza > pobierasz jakiegos beana i wywolujesz jego metody. Formularz, jak > pisalem, tylko przenosi dane z warstwy http (czyli pola z formularza > html, stringi, longi, inty, itd.) do warstwy aplikacji. W innych klasach > powinienes miec logike przetwarzajaca te dane. >
zamowienieBean to obiekt w ZamowienieForm (stworzylem klase ZamowienieBean ktory ma robic za result bean i spelniac logike aplikacji - pod tym pojeciem rozumiem laczenie sie z baza i ladowanie listy produktow, zapisywanie/odczytywanie z bazy zamowien i przekazanie ich do edycji). Zeby wywolac metody tej klasy musze miec jej obiekt, umiescilem go w formularzu zeby np. nie ladowac listy produktow z bazy za kazdym razem w Action (gdybym w execute() tworzyl obiekt zamowienieBean). Czy powinienem wszystko przerzucic do ZamowienieForm (pola do imienia i nazwiska, adresu, listy produktow odczytane z bazy, listy wybranych produtkow przez użytkownika + wszystkie metody do ich obslugi)? Jesli tak, to nie za bardzo rozumiem sens istnienia result beana skoro i tak wszystko mam w form beanie?
> Po co na koncu akcji ustawiasz zmienne w kontekscie sesji? Z pierwszej > linijki widac, ze 'zamowienieform' juz jest dla tej akcji ustawiony. > Nadpisujesz obiekt nim samym? >
rzeczywiscie, myslalem ze jak w <html:hidden name="zamowienieBean" property="prod.symbol" value="${prod.symbol}"/> odwoluje sie do 'zamowienieBean' to musi byc zadeklarowany, ale to jest jednoznaczne z <html:hidden property="prod.idProd" name="ZamowienieForm" indexed="true" value="${prod.idProd}"/> (nie chcialem tworzyc dodatkowego pola w ZamowienieForm tylko od razu odwolywac sie do zamowienieBean)
> > Dodaj sobie wypisywanie zawartosci formularza jak sugerowalem, moze cos > ci sie wyjasni. >
gdzie w tomcacie mozna odczytac System.out? :)
> > > wydaje mi sie, ze z kazda iteracja ten bean bedzie nadpisywany.To wszystko robi sie bardzo prosto gdy grasz wg odpowiednich zasad ;-) > Moze powiedz lepiej co chcesz osiagnac tym formularzem. Wygenerowany > html wyglada w porzadku? Wszystkie pola formularza maja odpowiednie > wartosci? No to zobaczy czy akcja dostaje formularz z takimi wartosciami > jakie miales na stronie. >
Wygenerowany html wyglada w porzadku:
<form id="ZamowienieForm" method="post" action="/formularzeStruts/ChangeSelProdQty.do">
<input type="hidden" name="ZamowienieForm[0].prod.idProd" value="1" /> <input type="text" name="ZamowienieForm[0].prod.ilosc" value="1" />
wycinek z JSP:
<html:form action="ChangeSelProdQty"> <logic:iterate id="prod" name="ZamowienieForm" property="zamowienieBean.selectedProductsList" indexId="index"> <html:hidden property="prod.idProd" name="ZamowienieForm" indexed="true" value="${prod.idProd}"/> <html:text name="ZamowienieForm" property="prod.ilosc" indexed="true" value="${prod.ilosc}"/> <html:submit value="Ustaw ilosc" indexed="true" /> </logic:iterate> </html:form>
rozumiem ze dzieki indexed="true" strutsy tworza tablice formularzy (ZamowienieForm[i]) a Akcja w execute() dostaje ten wlasciwy formularz 'na talerzu' ?
> Formularz z poprzedniego postu wysyla 5 pol: idProd, prod.symbol, > prod.nazwa, prod.cena i prod.ilosc. Musisz takie miec w formularzu > podpietym do tej akcji. Nie prosciej miec tylko dwa pola: id produktu > oraz ilosc? >
tak, rzeczywiscie jest lepiej, juz to zmienilem. Jednak dalej produkt w ZamowienieForm jest pusty, moj Formularz
public class ZamowienieForm extends org.apache.struts.action.ActionForm {
private Produkt prod=null;
public Produkt getProd(){ return this.prod; } public void setProd(Produkt p){ this.prod=p; } }
natomiast w Akcji:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ZamowienieForm zf=(ZamowienieForm)form; String id=zf.getProd().getIdProd(); if(id!="1" || id!= "2" || id!="3"){ throw new Exception("idProd puste"); }
testuje na razie na 3 produktach i ten wyjatek mi sie pojawia czyli wychodziloby na to ze cokolwiek bym nie robil prod z ZamowienieForm jest pusty :/
Mikolaj Rydzewski - 12-01-2007 00:30
pjotr <pjotr@o2.pl> wrote:
> zamowienieBean to obiekt w ZamowienieForm (stworzylem klase > ZamowienieBean ktory ma robic za result bean i spelniac logike > aplikacji - pod tym pojeciem rozumiem laczenie sie z baza i ladowanie > listy produktow, zapisywanie/odczytywanie z bazy zamowien i przekazanie > ich do edycji). Zeby wywolac metody tej klasy musze miec jej obiekt, > umiescilem go w formularzu zeby np. nie ladowac listy produktow z bazy > za kazdym razem w Action (gdybym w execute() tworzyl obiekt > zamowienieBean). Czy powinienem wszystko przerzucic do ZamowienieForm > (pola do imienia i nazwiska, adresu, listy produktow odczytane z bazy, > listy wybranych produtkow przez użytkownika + wszystkie metody do ich > obslugi)? Jesli tak, to nie za bardzo rozumiem sens istnienia result > beana skoro i tak wszystko mam w form beanie?
Wg mnie najprosciej byloby zrobic formbean zawierajacy pola:
List<Produt> products; // lista produktow do pokazania, // zakladam, ze klasa Produkt posiada pole id String prodId; // id produktu ktorego ilosc zmieniamy Long ilosc; // nowa ilosc produktow podana w polu text, zakladam // ograniczenie na wartosci calkowite
Akcja pokazujaca dane pobiera liste produktow do pokazania:
ZamowienieForm zf = (ZamowienieForm)form; zf.setProducts( businessObject.getProducts(...) ); zf.setProdId(null); zf.setIlosc(null); return mapping.findForward(...);
Strona JSP:
<c:forEach var="prod" items="${ZamowienieForm.products}">
<html:form action="/ChangeSelProdQty"> <html:hidden property="prodId" value="${prod.id}"/> <html:text property="ilosc" /> <html:submit/> </html:form>
</c:forEach>
Akcja przetwarzajaca wyslanie formularza:
ZamowienieForm zf = (ZamowienieForm)zf; String id = zf.getProdId(); Long ilosc = zf.getIlosc(); if (id != null && ilosc != null) { businessObject.changeQuantityForProdId(id, ilosc); } return mapping.findForward(...);
Musisz dostarczy tylko dwie metody: pobieranie listy produktow do pokazania (czy to dla usera, czy to rekordy z bazy, etc), oraz zmiana ilosc produktow o okreslonym id.
W akcji pokazujacej liste ladujesz z bazy/koszyka/etc liste produktow i czyscisz pozostale pola. W akcji obslugujacej zmiane ilosci odczytujesz id produktu oraz jego nowa ilosc i odpowiednio zmieniasz zawartosc bazy, zamowienia, czy co tam jest do zmiany. Obie akcje oczywiscie musza posiadac przypisany ten sam formularz.
Formularz nawet nie musi byc w sesji trzymany.
>> Dodaj sobie wypisywanie zawartosci formularza jak sugerowalem, moze cos >> ci sie wyjasni. > > gdzie w tomcacie mozna odczytac System.out? :)
Zalezy od konfiguracji, w ktoryms z plikow logow. U mnie w catalina.out. Choc do logowania polecam raczej log4j.
> Wygenerowany html wyglada w porzadku: > > <form id="ZamowienieForm" method="post" > action="/formularzeStruts/ChangeSelProdQty.do"> > > <input type="hidden" > name="ZamowienieForm[0].prod.idProd" value="1" /> > <input type="text" name="ZamowienieForm[0].prod.ilosc" > value="1" />
Wg mnie nie za bardzo, to 'zamowienieForm[0]' mi sie nie podoba.
> rozumiem ze dzieki indexed="true" strutsy tworza tablice formularzy > (ZamowienieForm[i]) a Akcja w execute() dostaje ten wlasciwy formularz > 'na talerzu' ?
No niezupelnie to tak dziala. Atrybutu indexed uzywa sie raczej wtedy, gdy chcesz przekazac tablice elementow w jednym formularzu, a ty robisz wiele formularzy, ale i tak wysylany bedzie tylko jeden zawierajacy w zasadzie tylko dwa pola (id i ilosc).
-- Mikolaj Rydzewski <miki@ceti.pl> http://ceti.pl/~miki/ PGP KeyID: 8b12ab02 There are three kinds of people: men, women, and unix.
pjotr - 13-01-2007 00:01
Mikolaj Rydzewski napisał(a): > > > rozumiem ze dzieki indexed="true" strutsy tworza tablice formularzy > > (ZamowienieForm[i]) a Akcja w execute() dostaje ten wlasciwy formularz > > 'na talerzu' ? > > No niezupelnie to tak dziala. Atrybutu indexed uzywa sie raczej wtedy, > gdy chcesz przekazac tablice elementow w jednym formularzu, a ty robisz > wiele formularzy, ale i tak wysylany bedzie tylko jeden zawierajacy w > zasadzie tylko dwa pola (id i ilosc). >
wszystko juz dziala - jeszcze musze gdzies poustawiac odpowiedni scope dla akcji bo jak odswiezam to dzieja sie dziwne rzeczy czasami - jeszcze raz dzieki!
Pozdrawiam PT
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
sql za pomoca sql
=?iso-8859-2?q?NET_i_ODBC_-_Lista_dostawc=F3w_danych?=
Sql Serv 2000 - String z lista parametrem funkcji ?
Lista =?ISO-8859-2?Q?uporz=B1dkowana?= w relacji
Grafik ze znajomością HTML/CSS potrzebny.
OPTIMA - lista =?ISO-8859-2?Q?kontrahent=F3w?=
Lista poslow, ktorzy nie poparli zycia
Tabela stylów w kursie HTML
Cms z łatwą modyfikacja HTML
Watek - czy da sie pobrac referencje mając nazwe??
zanotowane.pldoc.pisz.plpdf.pisz.pltejsza.htw.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|