radio button behavior unlike dropdown

Bug #130440 reported by Justin
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
web.py
Confirmed
Medium
Anand Chitipothu

Bug Description

The Radio class buttons currently don't allow tuple inputs of (value, desc) like the Dropdown class allows. Additionally, the Radio buttons don't set up a label for the description.

The following patch fixes both of those issues.

@@ -155,9 +155,15 @@
     def render(self):
         x = '<span>'
         for arg in self.args:
- if self.value == arg: select_p = ' checked="checked"'
+ if type(arg) == tuple:
+ value, desc= arg
+ else:
+ value, desc = arg, arg
+
+ if self.value == value: select_p = ' checked="checked"'
             else: select_p = ''
- x += '<input type="radio" name="%s" value="%s"%s%s /> %s ' % (net.websafe(self.name), net.websafe(arg), select_p, self.addatts(), net.websafe(arg))
+ radio_id = net.websafe(self.name)+'_'+net.websafe(value)
+ x += '<input type="radio" name="%s" id="%s" value="%s"%s%s /><label for="%s"> %s</label> ' % (net.websafe(self.name), radio_id, net.websafe(value), select_p, self.addatts(), radio_id, net.websafe(desc))
         return x+'</span>'

Revision history for this message
Justin (jedavis83) wrote :

Here's the patch attached as a file.

Revision history for this message
Anand Chitipothu (anandology) wrote :

I think, this breaks form.validates().

Revision history for this message
Justin (jedavis83) wrote :

Hmm, I just played around with it a little and I'm not sure what you mean by breaking form.validates

I got this to work:

x = form.Form(form.Radio('test', [('val1', 'desc1'), ('val2', 'desc2')], form.notnull))
y = x()
y.validates({'test':''}) #=> False
y.validates({'test':'val1'}) #=> True

I'm not sure how the validation for this would be any different than that for a dropdown -- this patch only affects the render method.

Cheers,
Justin

Revision history for this message
Anand Chitipothu (anandology) wrote : Re: [Bug 130440] Re: radio button behavior unlike dropdown

> x = form.Form(form.Radio('test', [('val1', 'desc1'), ('val2',
> 'desc2')], form.notnull))
> y = x()
> y.validates({'test':''}) #=> False
> y.validates({'test':'val1'}) #=> True

y.render() will not display desc after calling y.validates.

Revision history for this message
Justin (jedavis83) wrote :

Sorry, still don't see it:

x = form.Form(form.Radio('test', [('val1', 'desc1'), ('val2', 'desc2')], form.notnull))
y = x()
y.render()
=>

'<table>\n <tr><th><label for="test">test</label></th><td><span><input type="radio" name="test" id="test_val1" value="val1" id="test" /><label for="test_val1"> desc1</label> <input type="radio" name="test" id="test_val2" value="val2" id="test" /><label for="test_val2"> desc2</label> </span></td><td id="note_test"></td></tr>\n</table>'

y.validates({'test':''})
=>False

y.render()
=>
'<table>\n <tr><th><label for="test">test</label></th><td><span><input type="radio" name="test" id="test_val1" value="val1" id="test" /><label for="test_val1"> desc1</label> <input type="radio" name="test" id="test_val2" value="val2" id="test" /><label for="test_val2"> desc2</label> </span></td><td id="note_test"><strong class="wrong">Required</strong></td></tr>\n</table>'

Revision history for this message
Anand Chitipothu (anandology) wrote :

It nevers says checked='checked', even after y.validates({'test': ['val1']})

Here is the fix.

- if self.value == value: select_p = ' checked="checked"'
+ if self.value and value in self.value: select_p = ' checked="checked"'

This breaks the backward compatability. We can make this a new class RadioButtonList or something like that.

y.validates() still fails because RadioButton expects a list but web.input gives a scalar value.

Revision history for this message
Justin (jedavis83) wrote :

Ok, I get it now - thanks for explaining.

Any chance you could just add the labels to the radios? I've always liked using labels on inputs whenever possible, and I don't see any issues with that (though, clearly, I could be missing something).

Changed in webpy:
assignee: nobody → anandology
importance: Undecided → Medium
milestone: none → 0.3
status: New → Confirmed
Changed in webpy:
milestone: 0.3 → 0.31
Changed in webpy:
milestone: 0.32 → 0.33
Changed in webpy:
milestone: 0.33 → 0.35
Revision history for this message
foxbunny (bg-branko) wrote :

I think I've a working patch for this, and some other things for the Radio. Unfortunately, I'm not too familiar with creating the patch files, so I'll attach a diff. The diff also includes doctests.

>>> import form
>>> f = form.Form(form.Radio('radio', [('1', 'desc 1'), ('2', 'desc 2')]))
>>> f.render_css()
'<label for="radio">radio</label><span id="radio">\n<input type="radio" id="radio1" value="1" name="radio"/> <label for="radio1">desc 1</label>\n<input type="radio" id="radio2" value="2" name="radio"/> <label for="radio2">desc 2</label>\n</span>\n'
>>> f.validates({'radio':'1'})
True
>>> f.render_css()
'<label for="radio">radio</label><span id="radio">\n<input checked="checked" type="radio" id="radio1" value="1" name="radio"/> <label for="radio1">desc 1</label>\n<input type="radio" id="radio2" value="2" name="radio"/> <label for="radio2">desc 2</label>\n</span>\n'

I still don't know what to do with the first <label> tag there, where it says '<label for="radio">'. Anyway, I've changed Radio class to assign _different_ id's for each of the buttons, so that labels have something to point at, but the first label now points at the <span>, which is not very nice.

Revision history for this message
foxbunny (bg-branko) wrote :

Forgot to mention that this diff is based on Anand's last commit on GitHub (31048781ce37edd987df244cdf811e0d52387354)

Revision history for this message
foxbunny (bg-branko) wrote :

An updated fix that applies to .34-pre-release version.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.