Difference from standard Django 1.4 implementation is just structure of list. In django <input>
elements are wrapped by their labels, and look like this::
<ul>
<li><label><input/> Label 1</label>
<li><label><input/> Label 2</label>
</ul>
This widget puts labels after input elements::
<ul class="form-button-radio">
<li><input/> <label>Label 1</label>
<li><input/> <label>Label 2</label>
</ul>
It makes possible to define style for both inputs and labels, hiding inputs and making labels look like pressable buttons. No javascript needed, just CSS (see docstring).
To auto-submit the form when pressing a button, JQuery can be added::
<script>
$(document).ready(function() {
$('ul.form-button-radio input[type="radio"]').change(function() {
$(this).parents('form').submit();
});
});
</script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | class ButtonRadioSelect(forms.RadioSelect):
"""Radio Select with overridden renderer, placing labels after inputs.
To make 3d stateful buttons, add CSS::
<style type="text/css">
ul.form-button-radio li {display: inline-block;}
ul.form-button-radio input[type="radio"] {display: none}
ul.form-button-radio input[type="radio"]+label {
padding: 2px;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border: 2px outset #BBB;
cursor: pointer;
}
ul.form-button-radio input[type="radio"]:checked+label {
font-weight: bold;
background-color: #999;
color: white;
}
</style>
"""
class ButtonRadioInput(forms.widgets.RadioInput):
def __unicode__(self):
# No idea, why Superclass' __unicode__ does not call
# correct render() method
return self.render()
def render(self, name=None, value=None, attrs=None, choices=()):
name = name or self.name
value = value or self.value
attrs = attrs or self.attrs
if 'id' in self.attrs:
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
else:
label_for = ''
choice_label = conditional_escape(force_unicode(self.choice_label))
return mark_safe(u'%s <label%s>%s</label>' % (self.tag(), label_for, choice_label))
class ButtonRadioFieldRenderer(forms.widgets.RadioFieldRenderer):
def __iter__(self):
for i, choice in enumerate(self.choices):
yield ButtonRadioSelect.ButtonRadioInput(self.name, self.value,
self.attrs.copy(), choice, i)
def __getitem__(self, idx):
choice = self.choices[idx] # Let the IndexError propogate
return ButtonRadioSelect.ButtonRadioInput(self.name, self.value,
self.attrs.copy(), choice, idx)
def render(self):
"""Outputs a <ul> for this set of radio fields."""
return mark_safe(u'<ul class="form-button-radio">\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
% force_unicode(w) for w in self]))
renderer = ButtonRadioFieldRenderer
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.