# ArrayList, JSTL - Verständnisproblem.



## Rumborak (2. Apr 2006)

Hallo zusammen,

ich hänge gerade an einem grundsätzlichen Problem zum Thema JSTL. Ich verwende Struts und möchte in einer JSP den Inhalt einer ArrayList ausgeben. Hierzu möchte ich gerne ein DynaActionForm benutzen.

Der entsprechende Code in der JSP:
	
	
	
	





```
<c:forEach var="item" items="${testForm.testList}">
[*]<c:out value="${item}" />
</c:forEach>
```
Definition in der struts-config.xml:
	
	
	
	





```
<form-bean name="testForm" type="org.apache.struts.action.DynaActionForm">
			<form-property name="testList" type="java.util.ArrayList" />
</form-bean>
```
In der Action steht folgender Code:
	
	
	
	





```
public class CreateProjectAction extends Action
{
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	{
		// Bean fuer Formulareingaben:
		DynaBean testForm = (DynaBean) form;

		// Liste definieren:
		ArrayList testList = new ArrayList();
		testList.add("");

		// Daten in der Bean speichern:
		testForm.set("testList", testList);

		// Aufruf der Seite:
		return mapping.findForward("showTestForm");
	}
}
```
Beim Aufruf der Seite erscheint dann folgende Fehlermeldung:
	
	
	
	





```
Unable to find a value for "testList" in object of class "org.apache.struts.action.DynaActionForm" using operator "."
```
Wahrscheinlich ist das nur ein ganz dummer Fehler - ich komme nur nicht drauf. Wäre nett, wenn  mir da jemand auf die Sprünge helfen könnte.....

Danke schonmal!

PS: Bei allen Beispielen im Netz, wird immer ein Key angegeben - meine ArrayList ist aber wie ein Array aufgebaut und enthält nur Elemente.


----------



## KSG9|sebastian (3. Apr 2006)

Warum benutzt du JSLT ? Wenn du struts benutzt dann kannst du doch gleich die Struts-Tags benutzen, oder ?

logic:iterate dürfte das richtige für dich sein...


----------



## Rumborak (3. Apr 2006)

Ja, danke für die Antwort!

Das Ganze ist eigentlich für ein Formular gedacht, in dem ich Felder dynamisch hinzufügen und entfernen möchte. Also wenn der Benutzer auf den <Plus>-Button klickt, soll am Ende des Formulars eine Zeile angehängt werden. Beim Anklicken von <Minus> wird die letzte Zeile entfernt.

Jetzt kann es aber vorkommen, daß eine Zeile zwei Textfelder oder mehr enthält, z. B. [PLZ] - [Ortsname]. Dann müßte ich ja mehrere <logic:iterate />-Tags verschachteln, oder? Ich habe mir halt gedacht, das geht mit JSTL besser - außerdem interessiert´s mich grundsätzlich...


----------



## KSG9|sebastian (3. Apr 2006)

uiui..ich hab mal eine Umfrage programmiert, dort hatte ich ein ähnliches Problem:

Anzahl der Felder und die Typen muss dynamisch sein
- recht easy zu machen
Inhalte der Felder müssen mit einem form-submit gespeichert werden
- besch****n zu machen

Ich hab das ganze so gelöst:

- XML Datei beschreibt die Form der Umfrage, z.B.


```
<umfrage>
  <name>Blah blub ?</name>
  <seite>
    <frage>Blah blub blubblub ?</frage>
    <textfeld/>
    <frage>auswahl blub ?</frage>
    <radio> 
      <auswahl>ja</auswahl>
      <auswahl>nein</auswahl>
    </radio>
  </seite>
</umfrage>
```

Das XML hab ich dann mit XSL noch ein bisschen modifiziert und dann in HTML ungewandelt.

Das was du vorhast ist ein bisschen ecklig, könntest du aber auch über ein XML lösen. Das anzeigen macht ein Servlet mit nem Xalan Transformer. Bei klick auf "+" wird der XML-Baum um ein Element erweitert, bei klick auf "-" eben verkürzt.
Und über das XML-Doc lässt du dann ein Stylesheet laufen welches XML in HTML wandelt.

Gruß


----------



## Rumborak (4. Apr 2006)

...irgendwie muß es doch möglich sein, mittels JSTL Expression-Language über eine ArrayList zu iterieren. Mit der Logic Taglibrary sieht mein Ansatz mal so aus:
	
	
	
	





```
<logic:iterate id="element" name="testBean" property="testList" indexId="counter" type="java.lang.String">
[*]<html:text name="testBean" property='<%="testList[" + counter + "]"%>' /> - <html:text name="testBean" property='<%="testList[" + counter + "]"%>' />
</logic:iterate>
```
...da gibt er halt zweimal das gleiche Feld aus - das mit der Vorbelegung nach dem Absenden klappt folglich natürlich nicht....

Ich bräuchte da wahrscheinlich zwei verschachtelte Schleifen, oder so. Hast jemand so ein Problem schonmal gehabt und kann mir einen Hinweis geben?


----------



## clemson (4. Apr 2006)

funktioniert das??

```
<logic:iterate id="element" name="testBean" property="testList" type="java.lang.String">
     <bean:write name="element" />
</logic:iterate>
```


----------



## Rumborak (4. Apr 2006)

Das funktioniert natürlich auch - danke für die Antwort!

Mein Problem ist aber vielmehr, wie mache ich das, wenn  ich zwei Textfelder nebeneinander in einer Zeile ausgeben möchte - wie muß denn da die Collection aufgebaut sein und wie kann ich die dann auf der Seite ausgeben.....?

Die Werte in den jeweiligen Feldern sollen ja auch mit dem Feldnamen in der DynaBean gespeichert werden!


----------



## clemson (4. Apr 2006)

hab ich dich richtig verstanden? du willst hast eine collection mit mehreren feldern, und diese willst du jetzt auf deiner jsp (nebeneinander) anzeigen?

dann würd ich das irgendwie so lösen (ungetestet)...


```
<%
     int cols = 2; // anzahl der spalten nebeneinander
     boolean ende_zeile = false; // flag, welches angibt, ob eine zeile beendet werden soll
     boolean beginn_zeile = true; // flag, welcen angibt, ob eine neue zeile begonnen werden soll
%>
<logic:iterate id="element" name="testBean" property="testList" indexId="counter" type="java.lang.String">
     <%
          if (beginn_zeile) {
               beginn_zeile = false; // flag zurücksetzen
               %>
                    [*]
               <%
          }
     %>

          <html:text name="testBean" property='<%="testList[" + counter + "]"%>' />

     <%
          /**
          * eine zeile soll beendet werden, wenn die position des aktuellen elements,
          * dividiert durch die anzahl der gewünschten spalten, den restwert 0 besitzt (modulo).
          **/
          ende_zeile = ((counter+1) % cols) == 0; // berechnen, ob eine zeile beendet werden soll
          if (ende_zeile) {
               beginn_zeile = true; // bei beendigung einer zeile, soll beim nächsten durchlauf eine neue zeile begonnen werden
               %>
                    
               <%
          }
     %>     
</logic:iterate>
```


----------



## Rumborak (5. Apr 2006)

...Du würdest also quasi alles in einer ArrayList hintereinander abspeichern und die Anzahl der Elemente pro Zeile dann einfach in der Schleife abfragen. Wenn ich jetzt pro Zeile für jedes Feld jeweils ein Element in der Collection haben und dies über den Namen ansprechen will, muß ich dann eine HashMap nehmen? Also eine ArrayList mit n Elementen, wobei jedes Element wiederum eine HashMap ist..... wie kann man denn dann sowas in der JSP ausgeben?

Die Datenstruktur sähe so aus:
	
	
	
	





```
[0]["Feld1"]["Feld2"]
[1]["Feld1"]["Feld2"]
[2]["Feld1"]["Feld2"]
[3]["Feld1"]["Feld2"]
...
```


----------

