[Java / MVC] processing van request parameters (checkbox)

Pagina: 1
Acties:

  • Standeman
  • Registratie: November 2000
  • Laatst online: 14:55

Standeman

Prutser 1e klasse

Topicstarter
Op mijn werk hier beschikken over een home made implementatie van het MVC framework a la struts welke in principe prima werkt, maar nog wat functionaliteit mist.

Ik loop nu echter tegen een probleem aan waarvoor ik niet direct een oplossing hebt en het is allemaal de schuld van de HTML standaard ;)

De meeste van jullie weten wel dat HTML checkbox elementen alleen in de request parameters aanwezig zijn wanneer deze zijn aangevinkt. Wanneer de checkbox leeg is, wordt deze gewoon genegeerd tijdens het posten van het HTML formulier.
Hier ligt ook mijn probleem, ik zal het proberen duidelijk te maken aan de hand van een voorbeeld.

Ik heb een Collection met Employee objecten welke weer een id en een naam bezitten. Tevens heb ik een formbean object welke ik gebruik als DTO tussen mijn JSP en Action. Deze zien er ongeveer alsvolgt uit:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Employee {
  private int id;
  private String name;
  
  ..... (getters, setters, etc)
}

public class EmployeeBean {
  private Employee employee;
  private boolean selected; //Checkbox wel / niet geselecteerd


  ..... (getters, setters, etc)
}

public class EmployeeFormBean {
  private Collection employees;
  private .... //Nog wat meer variabelen van het HTML form.
}



Nu populaten we het object EmployeeFormBean automatisch aan de hand van onze workflow. De geconfigureerde formbean wordt uit de sessie gehaald en op basis van de parameternamen de juiste waarden geset (dit doen we met behulp van apache commons-beanutils).

De grap is echter.. Dat aangezien uitgevinkte checkboxes niet in je request parameters zitten en dus employeeBean.setSelected() nooit wordt aangeroepen. Hierdoor weet ik dus niet of een checkbox, welke aanstond, uitgezet is?

Ik zie tot nu nog maar 1 optie om dit probleem op te lossen:
- In mijn specifieke action nog maals door de request parameters heenlopen en de missende employees deselecteren (een niet generieke en imo ranzige oplossing).

Ik hoop dat er iemand hier rondloopt die het "missende checkbox probleem" al eens op een generieke wijze heeft opgelost of iemand die een goed idee heeft..

The ships hung in the sky in much the same way that bricks don’t.


  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 13-02 14:51
en het value attribuut van de checkbox op true setten helpt ook niet?

  • Standeman
  • Registratie: November 2000
  • Laatst online: 14:55

Standeman

Prutser 1e klasse

Topicstarter
TukkerTweaker schreef op dinsdag 11 juli 2006 @ 14:39:
en het value attribuut van de checkbox op true setten helpt ook niet?
uhmm.. nope. aangezien dit niet de checkbox op "checked" zet..

The ships hung in the sky in much the same way that bricks don’t.


  • al-ahlex
  • Registratie: September 2002
  • Laatst online: 05-10-2021
Ik heb dit probleem inderdaad ook tegengekomen (in PHP), en heb dit opgelost met Javascript - ik weet niet of dat een optie is voor jullie. Deze (ranzige) method geeft een 0 door indien checked, en een 1 indien niet.


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function checkbox($name,$val) {
        static $uniqId;
        $uniqId++;

        $ret = "<input
                    type=checkbox
                    id='checkbox_{$uniqId}'
                 onclick=\"document.getElementById('chk_{$uniqId}').value=Number(this.checked);\" style=\"border:none;background:transparent;width:auto;\"
                    value=\"1\" ";

        if($val) $ret .= "checked=\"checked\" ";
        $ret .= "/>";

        $ret .= "<input type=\"hidden\" id=\"chk_{$uniqId}\" name=\"".htmlentities($name,ENT_QUOTES,'UTF-8')."\" value=".intval($val)." /> ";

        return $ret;
    }

[ Voor 28% gewijzigd door al-ahlex op 11-07-2006 15:35 ]


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Volgens mij kan je dit simpel oplossen door een initialisatie te laten plaatsvinden die voor de request parameters ingelezen worden de checkbox values op false zet. Krijg je een true uit de request terug, dan zijn ze gecheckt (waren ze misschien al, maar doet er niet toe); zijn ze uitgecheckt, dan blijven ze gewoon false

  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 13-02 14:51
Standeman schreef op dinsdag 11 juli 2006 @ 15:12:
[...]


uhmm.. nope. aangezien dit niet de checkbox op "checked" zet..
Klopt maar dan komen ze volgens mij wel in de request terecht.

  • Standeman
  • Registratie: November 2000
  • Laatst online: 14:55

Standeman

Prutser 1e klasse

Topicstarter
-FoX- schreef op dinsdag 11 juli 2006 @ 15:18:
Volgens mij kan je dit simpel oplossen door een initialisatie te laten plaatsvinden die voor de request parameters ingelezen worden de checkbox values op false zet. Krijg je een true uit de request terug, dan zijn ze gecheckt (waren ze misschien al, maar doet er niet toe); zijn ze uitgecheckt, dan blijven ze gewoon false
tja.. probleem is dat tussen het moment van het request en het populaten van mijn bean ik nog geen flauw idee heb of ik met checkboxes o.i.d te maken heb..

Het ziet er een beetje als volgt uit:

Java:
1
2
3
4
5
6
    doPost(HttpServletRequest request) {
           Object bean = getBeanFromSession(request, beanName);
            try {
                BeanUtils.populate(bean, request.getParameterMap());
            }
    }


In het echt is het wel wat gecompliceerder aangezien er eerst nog wat workflow zaken worden uitgevoerd, maar hier komt het wel in principe op neer.

Ik heb inmiddels wel een oplossing welke ongeveer hetzelfde is als die van al-ahlex, namelijk het volgende:

Java:
1
2
3
4
5
<c:forEach var="employeeBean" items="${searchEmployeeForm.employees}" varStatus="stat">
  <c:when test="${employeeBean.selected}">
    <input type="checkbox" name="employees[${stat.index}].selected" checked/>
    <input type="hidden" name="employees[${stat.index}].selected" value="false"/>   
  </c:when>


Hierdoor wordt er altijd een waarde doorgestuurd. Of ik er blij mee ben, weet ik nog niet. Ik denk dat ik er maar een tag voor ga maken, anders gaan er een hoop fouten gemaakt worden....

The ships hung in the sky in much the same way that bricks don’t.


  • paulh
  • Registratie: Juli 1999
  • Laatst online: 01-02 16:45
In struts heb je dit probleem ook. Daar hebben ze in ieder geval nog een reset methode toegevoegd waarin je de waarden van je formbean can resetten. Zet dus voor de request alle attributen waar een checkbox op van toepassing is op false. Na de request zijn dan correct gevuld.

Als je niet weet welke velden een checkbox zouden zijn kan je er dan niet van uit gaan dat alle boolean velden checkboxen zijn? Dan kan je eventueel met reflection de boel resetten (ook niet ideaal uiteraard).

[ Voor 28% gewijzigd door paulh op 11-07-2006 21:13 ]

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Nasty. Maar heb je de mogelijkheid om van JSF en backing beans gebruik te maken? Daarmee werkt het namelijk wel gewoon.

Overigens vind ik EmployeeBean een beetje foute benaming voor een simpele helper/wrapper class. Ik zou eerder EmployeeData gebruiken en de EmployeeFormBean hernoemen naar EmployeeBean. Maarja, dat ben ik :P

  • rrrandy
  • Registratie: Juli 2005
  • Laatst online: 25-01 15:24
BalusC schreef op dinsdag 11 juli 2006 @ 22:16:
Nasty. Maar heb je de mogelijkheid om van JSF en backing beans gebruik te maken? Daarmee werkt het namelijk wel gewoon.
Waarom denk je dat JSF eigen input-tags heeft? Precies om dit soort problemen op te lossen ;)

[ Voor 25% gewijzigd door rrrandy op 12-07-2006 09:57 ]


  • Standeman
  • Registratie: November 2000
  • Laatst online: 14:55

Standeman

Prutser 1e klasse

Topicstarter
paulh schreef op dinsdag 11 juli 2006 @ 21:09:
In struts heb je dit probleem ook. Daar hebben ze in ieder geval nog een reset methode toegevoegd waarin je de waarden van je formbean can resetten. Zet dus voor de request alle attributen waar een checkbox op van toepassing is op false. Na de request zijn dan correct gevuld.

Als je niet weet welke velden een checkbox zouden zijn kan je er dan niet van uit gaan dat alle boolean velden checkboxen zijn? Dan kan je eventueel met reflection de boel resetten (ook niet ideaal uiteraard).
Helaas geen JSF tot mijn beschikking hier.. ;( Om de een of andere redenen vinden ze hier nogal graag voor de 36ste keer het wiel uit ;)

(inmiddels zijn er al wel bewegingen om naar Spring / Spring MVC over te stappen.. al een hele vooruitgang!)

Dat Reset ga ik even naar kijken. Volgens mij niet zo lastig te implementeren in ons eigen MVC thingy..

The ships hung in the sky in much the same way that bricks don’t.


  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

rrrandy schreef op woensdag 12 juli 2006 @ 09:56:
Waarom denk je dat JSF eigen input-tags heeft? Precies om dit soort problemen op te lossen ;)
Dat is niet de essentie van JSF, dat is puur een bijkomend voordeel ;)

Overigens, Standeman:
Java:
1
2
3
4
5
<c:forEach var="employeeBean" items="${searchEmployeeForm.employees}" varStatus="stat">
  <c:when test="${employeeBean.selected}">
    <input type="checkbox" name="employees[${stat.index}].selected" checked/>
    <input type="hidden" name="employees[${stat.index}].selected" value="false"/>   
  </c:when>
Volgens mij heb je in deze c:choose groep ook nog een c:otherwise met precies dezelfde HTML, echter dan zonder "checked". Je zou deze ook kunnen vervangen door:
Java:
1
<input type="checkbox" name="employees[${stat.index}].selected" <c:if test="${employeeBean.selected}">checked</c:if> />

  • Standeman
  • Registratie: November 2000
  • Laatst online: 14:55

Standeman

Prutser 1e klasse

Topicstarter
BalusC schreef op woensdag 12 juli 2006 @ 16:34:
[...]
Dat is niet de essentie van JSF, dat is puur een bijkomend voordeel ;)

Overigens, Standeman:
Java:
1
2
3
4
5
<c:forEach var="employeeBean" items="${searchEmployeeForm.employees}" varStatus="stat">
  <c:when test="${employeeBean.selected}">
    <input type="checkbox" name="employees[${stat.index}].selected" checked/>
    <input type="hidden" name="employees[${stat.index}].selected" value="false"/>   
  </c:when>
Volgens mij heb je in deze c:choose groep ook nog een c:otherwise met precies dezelfde HTML, echter dan zonder "checked". Je zou deze ook kunnen vervangen door:
Java:
1
<input type="checkbox" name="employees[${stat.index}].selected" <c:if test="${employeeBean.selected}">checked</c:if> />
Ja dat klopt op zich wel, maar anders krijg ik de volgende constructie:
Java:
1
2
3
4
5
6
<input type="checkbox" name="employees[${stat.index}].selected" 
<c:if test="${employeeBean.selected}">checked</c:if> />

<c:if test="${employeeBean.selected}">
 <input type="hidden" name="employees[${stat.index}].selected" value="false"/>
</c:if>


Naar mijn mening zit er dan niet erg veel verschil.. Ik ben iig van plan om er een tag voor te gaan schrijven.. Is een stuk makkelijker voor de anderen hier.

The ships hung in the sky in much the same way that bricks don’t.


Verwijderd

BalusC schreef op woensdag 12 juli 2006 @ 16:34:
Je zou deze ook kunnen vervangen door:
Java:
1
<input type="checkbox" name="employees[${stat.index}].selected" <c:if test="${employeeBean.selected}">checked</c:if> />
Dat vind ik echt ransig. Ik heb persoonlijk liever simpele valide xml zodat je met een willekeurige xml editor aan de slag kunt.

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

JSP en XML zijn twee verschillende dingen.

Verwijderd

BalusC schreef op donderdag 13 juli 2006 @ 09:51:
JSP en XML zijn twee verschillende dingen.
In het jaar 1998 inderdaad wel, maar de spec is zo langzamerhand gevorderd. Ik schrijf dus simpelweg jspx bestanden, dan kan ik dus wel elke xml gebruiken (inclusief code completion). Geen jsp_only geneuzel.

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

In dit geval, JSP en JSPX zijn twee verschillende dingen ;)
Pagina: 1