ďťż
 
[Struts] rozwijana lista za pomoca html:optionsCollection ďťż
 
[Struts] rozwijana lista za pomoca html:optionsCollection
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

[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.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    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.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • tejsza.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

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com