# Tabelle mit checkboxen in Struts



## TorstenW (15. Aug 2008)

Da bin ich wieder und habe ein kleines Problem mit Struts!

Folgende Situation ich möchte eine Tabelle anzeigen und dann mit checkboxen in der ersten Spalte auswählen 
welche Zeilen auf eine weitere Seite übergeben werden.

Ich benutze dazu eine Treemap mit 3 werten 

String Name  String Beruf  boolean selected  diese schicke ich von der Action in die Form und lasse Sie dann 
in der JSP anzeigen die selected benutze ich um der checkbox zu übergeben ob eine Zeile schon vorgewählt 
ist oder nicht.

Die Anzeige funzt super nur wenn ich jetzt einen Haken setze oder wegnehme wird mir diese Information nicht 
übergeben die treemap in der Form ändert sich nicht ! Wie übergebe ich die Information

Kleine Anmerkung vorher habe ich die Haken über multibox im iterate der JSP erstellt und über ein String Array 
ausgelesen diese Lösung musste ich leider verwerfen da ich Syncronisationsprobleme mit der Treemap hatte. 

Hier ein bisschen  CODE


```
<%@ page language="java" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

<html:form action="/tabelle.do">
<bean:define id="treemap" name="Form" property="treemap"/>

<table>
	<TR>     
     	<TH></TH>
     	<TH>Name</TH>
	<TH>Beruf</TH>
	</TR>
<logic:iterate id="element" name="treemap" indexId="itemidx">
<td>
	<html:checkbox name="element" property="value.selected" style="height: 14px; width: 10px;">
   	</html:checkbox>
</td>

			<td>
				<bean:write name="element" property="value.name"/>
			</td>
			<td>
				<bean:write name="element" property="value.beruf"/>
			</td>
</logic:iterate>
</table>

<html:submit styleClass="button" property="button" style="width:120;" value="Submit"/>
</html:form>
```


----------



## HLX (15. Aug 2008)

Mit <bean:define> erzeugst du eine neues TreeMap-Objekt. Dabei besteht natürlich kein Bezug mehr zum Formular Du solltest stattdessen während der Iteration direkt auf die TreeMap aus dem Formular zugreifen.

```
<logic:iterate id="element" name="Form" property="treeMap" indexId="itemidx">
```

Beachte auch, dass das Wegnehmen des Häkchens einer Checkbox nicht per HTTP übermittelt wird. Du solltest dies in der Reset-Methode des Formulars behandeln.


----------



## TorstenW (15. Aug 2008)

Ok das der Bezug fehlt habe ich geänder ich mache es jetzt so wie vorgeschlagen jetzt ist die frage wenn ich den haken setze oder wegnehme
 verändert sich dann beim submit der wert in der Form oder wie komme ich jetzt an die Haken ?




			
				HLX hat gesagt.:
			
		

> Beachte auch, dass das Wegnehmen des Häkchens einer Checkbox nicht per HTTP übermittelt wird. Du solltest dies in der Reset-Methode des Formulars behandeln.


 Das verstehe ich nicht ganz ! sorry


----------



## HLX (15. Aug 2008)

TorstenW hat gesagt.:
			
		

> Ok das der Bezug fehlt habe ich geänder ich mache es jetzt so wie vorgeschlagen jetzt ist die frage wenn ich den haken setze oder wegnehme
> verändert sich dann beim submit der wert in der Form oder wie komme ich jetzt an die Haken ?


Wenn du den Haken setzt, sollte sich der Wert in der Form automatisch ändern.



			
				TorstenW hat gesagt.:
			
		

> HLX hat gesagt.:
> 
> 
> 
> ...


Bei der Übermittlung von HTML-Formulardaten ist leider keine Übertragung einer leeren Checkbox vorgesehen. Der Wert einer Checkbox wird in HTML grundsätzlich nur dann übertragen, wenn sie angeklickt ist. Somit kannst du das entfernen des Häkchens nicht automatisch auf der Serverseite feststellen. Da in diesem Falle nichts übertragen wird, geht Struts davon aus, dass das Häkchen noch gesetzt ist und behält den Wert 'true' bei.

Gelöst wird dieses Problem dadurch, dass in der Reset-Methode der Form-Klasse zunächst alle Formularwerte, die auf eine Checkbox zeigen, auf false gesetzt werden - also per Default ist das Häkchen einfach nicht angeklickt. Wenn dann anschließend von Struts das Mapping der Übertragungswerte auf die Form-Attribute vorgenommen wird, dann werden die Werte bei gesetztem Haken wieder auf true gesetzt. Falls nun bei einer Checkbox nichts übermittelt wird, bleibt der Wert false und du hast den gewünschten Effekt erzielt.


----------



## TorstenW (15. Aug 2008)

Oh das klingt logisch wie könnte so eine Reset Methode aussehen ?


----------



## HLX (15. Aug 2008)

Einfach die Reset-Methode aus der Klasse ActionForm überschreiben:

```
public class MyForm extends ActionForm {
    private boolean myCheckBox; // +getter und setter

    public void reset(ActionMapping newMapping, HttpServletRequest newRequest) {
        setMyCheckBox(false);
    }
}
```
Der Struts-RequestProcessor führt bei einem Formular zuerst diese Reset-Methode aus und mappt anschließend die RequestParameter auf die Form-Attribute.


----------



## TorstenW (15. Aug 2008)

ok das kann ich so machen wenn ich eine einzige checkbox habe aber ich arbeite ja mit einer treemap wo mir übergeben wird ob die box gesetzt ist das ist ja das grosse Problem was mich so verückt macht !

die treemap geändert wieder in die Action zu bringen !

Ich habe jetzt mit der reset methode es geschafft durch ein iterate die select alle auf false zu setzten aber das Problem ist das meine rest methode irgendwie an der falschen stelle eingreift und ich jetzt immer false rausbekomme!

Ich muss irgendwie die reihenfolge hinbekommen das der reset erst nach dem aufbau der Seite passiert und beim zurückschreiben erst der weg in die action gefunden wird da passt noch was nicht !

er soll ja eigentlich nur nach dem erstellen der seite alles auf false setzten sonst nicht !


----------



## HLX (15. Aug 2008)

Nochmal:

Wenn du dein Formular abschickst, dann wird vom Struts-Requestprocessor zuerst die Reset-Methode des Form-Objektes aufgerufen und anschließend werden die Request-Parameter deines abgesendeten Web-Formulars ausgelesen und in das Form-Objekt gespeichert. Somit hast du, sobald du in der Execute-Methode deiner Action bist, das Form-Objekt gefüllt mit den Werten, die du in deiner HTML-Seite gesetzt hast.

Die Reset-Methode wird natürlich auch aufgerufen, wenn das Formular zum erstem Mal erzeugt wird. Wenn du dann initiale Werte aus deiner Anwendung, z.B. aus einer Datenbank in das Formular einpflegen willst, darfst du die JSP-Seite mit dem Formular *nicht* direkt aufrufen, sondern musst (wie auch MVC vorsieht) über eine Action gehen:

```
<action 
     name="MyForm"
     path="/showFormular" 
     scope="session"
     type="com.MyApp.ShowFormularAction">
     <forward name="showFormular" path="/formular.jsp" />
</action>

// die Action-Klasse
public class ShowFormularAction extends Action {

     public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) {
            MyForm myForm = (MyForm) form;
            myForm.fill(getMyBackEndObjects()); // selbstdefinierte Methode zum Füllen des Formulars
            return mapping.findForward("showFormular");
    }
}

// der Aufruf des der Formular-JSP aus einer anderen JSP-Seite:
<html:link action="showFormular.do"/>
```
Bevor die Action ausgeführt wird, wird das Formular initialisiert und der Reset ausgeführt. Anschließend füllst du in der Action die Werte und leitest auf die JSP-Seite weiter.


----------



## TorstenW (18. Aug 2008)

Ich drehe gerade ein bisschen am rad ich bin der meinung das die Übergabe der gesetzten Haken schon funktioniert hat jetzt funzt aber diese Übergabe auch nicht mehr vieleicht war es aber auch nur eine Haluzination das es funzt.
Welche Einstellung habe ich jetzt wohl vergessen ? worauf muss ich achten ?

Tree wird derzeit überall gefüllt mit false
struts config steht bei scope auf session 
bean wird nicht extra definiert sondern direkt iteriert 

der tree in der Form wird nicht verändert !
aber es kommt keine übergabe der gesetzten Haken 


Ich wette ich habe eine Grundeinstellung irgendwie vertorft Hilfe Rettet mich


----------



## HLX (19. Aug 2008)

Du müsstest den Code posten, sonst wird das ein Ratespiel. Oder du debuggst die Anwendung und grenzt den Fehler ein.


----------



## TorstenW (20. Aug 2008)

JSP

```
<%@ page language="java" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

<html:form action="/tabelle.do">
<table>
   <TR>     
        <TH></TH>
        <TH>Name</TH>
   <TH>Beruf</TH>
   </TR>
<logic:iterate id="element" name="Form" property="treemap">
<td>
   <html:checkbox name="element" property="value.selected" style="height: 14px; width: 10px;"/>
      
</td>
         <td>
            <bean:write name="element" property="value.name"/>
         </td>
         <td>
            <bean:write name="element" property="value.beruf"/>
         </td>
</logic:iterate>
</table>

<html:submit styleClass="button" property="button" style="width:120;" value="Submit"/>
</html:form>
```


Struts Config

```
<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<form-beans>
        <form-bean name="Form" type="net.forms.Form"/>       
    </form-beans>
 <action-mappings>
        <action        
            path="/tabelle"
            type="net.forms.Form"
            name="Form"
            scope="session" >      	
        	<forward name="logon.Tabelle" path="/Tabelle.jsp"/>
        </action>
    </action-mappings>
</struts-config>
```

Form

```
package net.forms;


import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

/**
 * @author tw
 *
 */
public final class Form extends ActionForm {	

	private TreeMap treembts = new TreeMap();
        
        public void reset(ActionMapping mapping, HttpServletRequest request)
	  {
		super.reset(mapping,request);
          }
      //setter und getter generiert
}
```

Ich habe versucht nur den Code zu Posten der mit der Sache etwas zu tun hat .


----------



## HLX (20. Aug 2008)

Bei der Action-Deklaration in der struts-config.xml zeigt das "type"-Attribut auf die Formklasse. Hier ist die Action-Klasse anzugeben.

Was passiert in der Action-Klasse?


----------



## TorstenW (20. Aug 2008)

oh sorry das war ein fehler beim schreiben des posts kann nicht einfach rauskopieren weil noch andere sachen da laufen wo ich nicht rann will.


was in der action die sache angeht wird nur die treemap gefüllt und an die form übergeben und einmal lese ich die treemap zurück und lasse sie ausgeben um zu sehen was in der form steht dazu benutze ich aber nicht die gleiche treemap!

Mfg TW


----------



## HLX (20. Aug 2008)

Der Code scheint erstmal ok zu sein.



			
				TorstenW hat gesagt.:
			
		

> Tree wird derzeit überall gefüllt mit false
> ...
> der tree in der Form wird nicht verändert !
> aber es kommt keine übergabe der gesetzten Haken


Mir ist noch nicht ganz klar, wo das Problem ist. Wenn du den Tree überall mit false füllst, sind natürlich keine Checkboxen angeklickt. Wenn der Tree in der Form nicht verändert wird, bleibt das auch so. Warum sollten dann gesetzte Haken übergeben werden?


----------



## TorstenW (20. Aug 2008)

nein ich bekomme garkeine übergabe hin wenn ich in der Action die Treemap mit false werten fülle und dann übergebe wird natürlich kein Haken angezeigt wenn ich aber jetzt dann Haken setze sollte ja eigentlich der false wert in der Form überschrieben werden und dann sollte ich auch in der Action anzeigen können wie die  Treemap dann gefüllt ist aber dieses umschalten von false auf true funktioniert nicht !

Das anderer Problem dann zwischendurch alles wieder auf false zu setzen damit auch das problem mit weggenommenen Haken zu erledigen habe ich noch nicht angepackt !


----------



## HLX (20. Aug 2008)

Habs mir nochmal genauer angesehen. Maps sind tatsächlich nicht so einfach zu handeln wie Listen oder primitive Parameter. Folgendes sollte funktionieren:


```
// Form-Klasse
public class MyForm extends ActionForm {

    private TreeMap treembts = new TreeMap();

    public void reset(ActionMapping mapping, HttpServletRequest request) {
        if (!treembts.isEmpty()) {
            for (Iterator iter = treembts.values().iterator(); iter.hasNext();) {
                TestObject obj = (TestObject) iter.next();
                obj.setSelected(false);
            }
        }
    }

    public TreeMap getTreembts() {
        return treembts;
    }

    public void setTreembts(TreeMap newTreembts) {
        treembts = newTreembts;
    }

    public void setTreeValue(String key, Object value) {
        treembts.put(key,value);
    }
    
    public Object getTreeValue(String key) {
        return treembts.get(key);
    }
}

// Auszug aus JSP
<logic:iterate id="element" name="Form" property="treembts">
    <bean:define id="theKey" name="element" property="key"/>
    <tr>
         <td><html:checkbox name="Form" property="<%="treeValue("+theKey+").selected"%>"/></td>
         <td><bean:write name="Form" property="<%="treeValue("+theKey+").name"%>" /></td>
         <td><bean:write name="Form" property="<%="treeValue("+theKey+").beruf"%>" /></td>
    </tr>
</logic:iterate>
```


----------



## TorstenW (20. Aug 2008)

```
org.apache.jasper.JasperException: No getter method for property treeValue(Martens).selected of bean element
```

Ich glaube wir sind nah drann


----------



## HLX (20. Aug 2008)

Hast du die zusätzlichen Getter und Setter in die Form-Klasse aufgenommen (s.o.)?

[Edit] Quark - die Meldung bezieht sich auf eine Bean "element". Hast du vielleicht vergessen die Felder auf name="Form" umzustellen?

```
<html:checkbox name="Form"...
```


----------



## TorstenW (21. Aug 2008)

hatte ich falsch ja aber jetzt zeigt er 


```
org.apache.jasper.JasperException: No getter method for property treeValue(Martens).selected of bean Form
```

also auch nichts anderes


----------



## HLX (21. Aug 2008)

Also hast du doch die Getter und Setter in der Form-Klasse vergessen. Schau doch bitte nochmal in mein Beispiel oben.


----------

