Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails: checkbox not being set back to false

I am developing a Grails (1.0.4) app where I want to edit a collection of collections on a single page in a grid view. I got it to work quite well depending only on the indexed parameter handling of Spring MVC, except for one thing:

boolean (or, for that matter, Boolean) values in the grid can be set via checkbox, but not unset, i.e. when I check the checkbox and update, the value is set to true, but afterwards when I edit again, uncheck the checkbox and update, it remains true.

This is the GSP code of the checkbox:

<g:checkBox name="tage[${indexTag}].zuweisungen[${indexMitarb}].fixiert" value="${z.fixiert}" />

And this is the HTML that is generated:

<input type="hidden" name="tage[0].zuweisungen[0]._fixiert" />
<input type="checkbox" name="tage[0].zuweisungen[0].fixiert" checked="checked" id="tage[0].zuweisungen[0].fixiert"  />

I've found a Grails bug that describes exactly this effect, but it's marked as fixed in 1.0.2, and the problem mechanism described there (underscore in hidden field name is put in the wrong place) is not present in my case.

Any ideas what could be the reason?

like image 687
Michael Borgwardt Avatar asked Feb 22 '09 06:02

Michael Borgwardt


2 Answers

This is my own solution, basically a workaround that manually does what the grails data binding should be doing (but doesn't):

Map<String,String> checkboxes = params.findAll{def i = it.key.endsWith("._fixiert")} // all checkboxes
checkboxes.each{
    String key = it.key.substring(0, it.key.indexOf("._fixiert"))
    int tagIdx = Integer.parseInt(key.substring(key.indexOf('[')+1, key.indexOf(']')))
    int zuwIdx = Integer.parseInt(key.substring(key.lastIndexOf('[')+1, key.lastIndexOf(']')))
    if(params.get(key+".fixiert"))
    {
        dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert = true
    }
    else
    {
        dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert = false                    
    }
}

Works, requires no change in grails itself, but isn't reusable (probably could be made so with some extra work).

like image 187
Michael Borgwardt Avatar answered Sep 24 '22 18:09

Michael Borgwardt


I think that the simplest workaround would be to attach a debugger and see why Grails is failing to populate the value. Considering Grails is open source you'll be able to access the source code and once you figure out the solution for it you can patch your version.

I have also found this other bug GRAILS-2861 which mentions the issue related to binding to booleans (see Marc's comment in the thread). I guess that is exactly the problem you are describing.

like image 29
alexpopescu Avatar answered Sep 24 '22 18:09

alexpopescu