How to keep the Checkbox checked in form re-rendering?

101 views
Skip to first unread message

yongzh...@gmail.com

unread,
Apr 7, 2015, 1:56:15 PM4/7/15
to we...@googlegroups.com
Hello all,

I implement a form app by following the online instruction (http://webpy.org/form). In my code, I use the definition

    form.Checkbox('Image #1', checked=True),
   
so it is checked when user accesses this form page. I noticed that if there is any validation failure and the form was re-rendered, all checkbox would be in unchecked status. I just wonder if there is an easy way to keep all those checkbox checked in the re-rendered form. Thanks a lot.   

Best Regards,
-Yongzhi

Christophe

unread,
Apr 7, 2015, 4:38:20 PM4/7/15
to we...@googlegroups.com
(re)Hi,

I presume using bare HTML might prevent this behaviour:

<input type="checkbox" checked>

Regards,

Christophe.
--
You received this message because you are subscribed to the Google Groups "web.py" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webpy+un...@googlegroups.com.
To post to this group, send email to we...@googlegroups.com.
Visit this group at http://groups.google.com/group/webpy.
For more options, visit https://groups.google.com/d/optout.

yongzh...@gmail.com

unread,
Apr 7, 2015, 5:37:55 PM4/7/15
to we...@googlegroups.com
Hi Zbouboutchi,

I used

myform = form.Form(
...
   form
.Checkbox('Image #1', checked=True),
    form
.Checkbox('Image #2', checked=True),
    form
.Checkbox('Image #3', checked=True)
)

in the app.py to define several checkbox whose default status are checked. If I insert

<input type="checkbox" checked>

in the templates/*.html. I just got an additional checkbox (checkbox only without label) which is checked in the first rendering and re-rendering but my own checkbox keep unchanged. Not sure if I understand you correctly. Thank you for your suggestion and help.

Best Regards,
-Yongzhi

Christophe

unread,
Apr 8, 2015, 1:52:06 AM4/8/15
to we...@googlegroups.com
Ooops I realize I misunderstood your first question... My apologies.

I ran some test on my side and found that this behavior might be related to the validates() method.
I re-used the example given in http://webpy.org/form and modified a little the POST method to understand when the checkbox had lost its checked attribute:

    def POST(self):
        form = myform()
        print form.render() # prints bare HTML in the console
        if not form.validates():
            print form.render() # re-prints if form is'nt valid
            return render.formtest(form)
        else:
            # form.d.boe and form['boe'].value are equivalent ways of
            # extracting the validated arguments from the form.
            print form.render() # re-prints anyway
            return "Grrreat success! boe: %s, bax: %s" % (form.d.boe, form['bax'].value)

Whenever the form validates or not, I got this in the console:

127.0.0.1:44907 - - [08/Apr/2015 07:37:35] "HTTP/1.1 GET /" - 200 OK    ### First call to index
<table> ### Start of first print
   <tr><th><label for="boe">boe</label></th><td><input type="text" id="boe" name="boe"/></td></tr>
   <tr><th><label for="bax">bax</label></th><td><input type="text" id="bax" name="bax"/></td></tr>
   <tr><th><label for="moe">moe</label></th><td><textarea id="moe" name="moe"></textarea></td></tr>
   <tr><th><label for="curly_">curly</label></th><td><input checked="checked" type="checkbox" id="curly_" value="" name="curly"/></td></tr> ### In red, the checkbox that won't check, here it is already checked
   <tr><th><label for="french">french</label></th><td><select id="french" name="french">
 <option value="mustard">mustard</option>
 <option value="fries">fries</option>
 <option value="wine">wine</option>
</select>
</td></tr>
</table>
<table>
   <tr><th><label for="boe">boe</label></th><td><input type="text" id="boe" value="" name="boe"/></td></tr>
   <tr><th><label for="bax">bax</label></th><td><input type="text" id="bax" value="7" name="bax"/></td></tr>
   <tr><th><label for="moe">moe</label></th><td><textarea id="moe" name="moe"></textarea></td></tr>
   <tr><th><label for="curly_">curly</label></th><td><input type="checkbox" id="curly_" value="" name="curly"/></td></tr> ### Here, checked attribute vanished...
   <tr><th><label for="french">french</label></th><td><select id="french" name="french">
 <option selected="selected" value="mustard">mustard</option>
 <option value="fries">fries</option>
 <option value="wine">wine</option>
</select>
</td></tr>
</table>

127.0.0.1:44907 - - [08/Apr/2015 07:37:41] "HTTP/1.1 POST /" - 200 OK

I did'nt look further in the web.py source code to understand this behaviour, but I think you found a little bug related to the validates() method.

I'll take a look later in the day.

Regards,

Christophe.

Christophe

unread,
Apr 8, 2015, 2:59:27 PM4/8/15
to we...@googlegroups.com
So .. After some investigation, this is probably a problem related to web.input's interpretation when the form is filled.

When a checkbox is checked, web.input() contains this:
<Storage {'french': u'mustard', 'curly': u'', 'moe': u'', 'bax': u'', 'boe': u''}>

On the other side, when it's not checked, the curly key simply disappears:
<Storage {'french': u'mustard', 'moe': u'', 'bax': u'', 'boe': u''}>

I presume that the form is filled using the keys found in web.input() instead of using the list of inputs of the form itself, I didn't put the finger on the exact place where it stands :-[

I'm trying to write the smallest patch for form.py, but I'm not the python's superheroe I would dream of, so I have to work a little on that. ;)

Before I find the holy grail, you might fix this behaviour on your side reading the keys of web.input and checking the checkbox by yourself (always on the example...) :

    def POST(self):
        form = myform()
        if not form.validates():
            if 'curly' in web.input():
                form['curly'].set_value(True)

            return render.formtest(form)
        else:
            # form.d.boe and form['boe'].value are equivalent ways of
            # extracting the validated arguments from the form.
            return "Grrreat success! boe: %s, bax: %s" % (form.d.boe, form['bax'].value)

This seems to give pretty good results here :)

Regards,

Christophe.
Reply all
Reply to author
Forward
0 new messages