- Author:
- benjaoming
- Posted:
- August 1, 2012
- Language:
- Python
- Version:
- 1.4
- Score:
- 2 (after 2 ratings)
You need jQuery and Bootstrap 2 and bootstrap-dropdown.js. Apart from that, this should be a perfect drop-in replacement for the normal select widget. A jQuery event callback maintains a hidden input field from the user's selection. Upon loading the page, the hidden input field is set.
The SelectWidgetBootstrap also contains a <noscript> tag containing the normal forms.Select widget.
Example usage:
class MyForm(forms.Form):
group = forms.ModelChoiceField(models.Group.objects.all(), widget=SelectWidgetBootstrap(),
empty_label=_(u'(no group selected)'))
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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | class SelectWidgetBootstrap(forms.Select):
"""
http://twitter.github.com/bootstrap/components.html#buttonDropdowns
Needs bootstrap and jquery
"""
js = ("""
<script type="text/javascript">
function setBtnGroupVal(elem) {
btngroup = $(elem).parents('.btn-group');
selected_a = btngroup.find('a[selected]');
if (selected_a.length > 0) {
val = selected_a.attr('data-value');
label = selected_a.html();
} else {
btngroup.find('a').first().attr('selected', 'selected');
setBtnGroupVal(elem);
}
btngroup.find('input').val(val);
btngroup.find('.btn-group-label').html(label);
}
$(document).ready(function() {
$('.btn-group-form input').each(function() {
setBtnGroupVal(this);
});
$('.btn-group-form li a').click(function() {
$(this).parent().siblings().find('a').attr('selected', false);
$(this).attr('selected', true);
setBtnGroupVal(this);
});
})
</script>
""")
def __init__(self, attrs={'class': 'btn-group pull-left btn-group-form'}, choices=()):
self.noscript_widget = forms.Select(attrs={}, choices=choices)
super(SelectWidgetBootstrap, self).__init__(attrs, choices)
def __setattr__(self, k, value):
super(SelectWidgetBootstrap, self).__setattr__(k, value)
if k != 'attrs':
self.noscript_widget.__setattr__(k, value)
def render(self, name, value, attrs=None, choices=()):
if value is None: value = ''
final_attrs = self.build_attrs(attrs, name=name)
output = ["""<div%(attrs)s>"""
""" <button class="btn btn-group-label" type="button">%(label)s</button>"""
""" <button class="btn dropdown-toggle" type="button" data-toggle="dropdown">"""
""" <span class="caret"></span>"""
""" </button>"""
""" <ul class="dropdown-menu">"""
""" %(options)s"""
""" </ul>"""
""" <input type="hidden" name="%(name)s" value="" class="btn-group-value" />"""
"""</div>"""
"""%(js)s"""
"""<noscript>%(noscript)s</noscript>"""
% {'attrs': flatatt(final_attrs),
'options':self.render_options(choices, [value]),
'label': _(u'Select an option'),
'name': name,
'js': SelectWidgetBootstrap.js,
'noscript': self.noscript_widget.render(name, value, {}, choices)} ]
return mark_safe(u'\n'.join(output))
def render_option(self, selected_choices, option_value, option_label):
option_value = force_unicode(option_value)
selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
return u'<li><a href="javascript:void(0)" data-value="%s"%s>%s</a></li>' % (
escape(option_value), selected_html,
conditional_escape(force_unicode(option_label)))
def render_options(self, choices, selected_choices):
# Normalize to strings.
selected_choices = set([force_unicode(v) for v in selected_choices])
output = []
for option_value, option_label in chain(self.choices, choices):
if isinstance(option_label, (list, tuple)):
output.append(u'<li class="divider" label="%s"></li>' % escape(force_unicode(option_value)))
for option in option_label:
output.append(self.render_option(selected_choices, *option))
else:
output.append(self.render_option(selected_choices, option_value, option_label))
return u'\n'.join(output)
|
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.