How to add <div> tag instead of <li>
forms.py
class TypeSelectionForm(forms.Form): checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), label="", required=False) def __init__(self, type_id, *args, **kwargs): super(TypeSelectionForm, self).__init__(*args, **kwargs) _type_checkbox = self.fields['checkbox_field'] MY_CHOICES=((type.id, type.title) for type in type) _type_checkbox.choices = MY_CHOICES initial_val = [] type_selection = Types.objects.filter(parent_type_id=type_id,is_active=True) for type_selection in type_selection: initial_val.append(type_selection.id) _type_checkbox.initial = initial_val views.py
def types(method): """""""""""" types = TypeSelectionForm(type_id) return render(request,'types.html',{'types':types}) In the template, I create a field like this,
types.html
{% for field in types.checkbox_field %} <div class="deletelist"> {{field}}<br /> </div> {% endfor %} It creates html like this,
<ul> <li><label for="id_checkbox_field_0"><input checked="checked" type="checkbox" name="checkbox_field" value="597" id="id_checkbox_field_0" /> comp lab</label></li> <li><label for="id_checkbox_field_1"><input checked="checked" type="checkbox" name="checkbox_field" value="598" id="id_checkbox_field_1" /> phy lab</label></li> <li><label for="id_checkbox_field_2"><input checked="checked" type="checkbox" name="checkbox_field" value="599" id="id_checkbox_field_2" /> chem lab</label></li> </ul> I want to replace the <ul> and <li> tags with <div class="class-name">
Need help.
Why not use the power of Django template tags?
from django import template from django.utils.safestring import mark_safe register = template.Library() @register.filter("as_div") def as_div(form): form_as_div = form.as_ul().replace("<ul", "<div").replace("</ul", "</div") form_as_div = form_as_div.replace("<li", "<div").replace("</li", "</div") return mark_safe(form_as_div) Put it in the template tag and then do it simply in your template
{% load ad_div %} {# some Code #} {{ form|as_div }} {# some other code #} ==============================
Another approach (cleaner)
Another approach would be to expand the django form model
in the following way
from django.forms.forms import BaseForm Class AsDiv(BaseForm): def as_div(self): return self._html_output( normal_row = u'<div%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</div>', error_row = u'<div>%s</div>', row_ender = '</div>', help_text_html = u' <span class="helptext">%s</span>', errors_on_separate_row = False) Then you can just do it, this is your template
{{ form.as_div }} From the documentation :
New in Django 1.4.
For more detailed control over the generated markup, you can iterate over the switches in the template. Assuming a
myformform with abeatlesfield that usesRadioSelectas its widget:{% for radio in myform.beatles %} <div class="myradio"> {{ radio }} </div> {% endfor %}
In your template, you should have the following:
{% for radio in types.checkbox_field %} <input style="margin: 8px -3px;float: left;" type="button" class="delete_types" id="delete_name"/>{{ radio }} {% endfor %} You should also use ModelMultipleChoiceField :
class TypeSelectionForm(forms.Form): checkbox_field = forms.ModelMultipleChoiceField(label="", queryset=Types.objects.none(), required=False) def __init__(self, *args, **kwargs): qs = kwargs.pop('queryset') super(TypeSelectionForm, self).__init__(*args, **kwargs) self.fields['checkbox_field'].queryset = qs Initiate it as follows:
def types(method): """""""""""" qs = Types.objects.filter(parent_type_id=type_id,is_active=True) types = TypeSelectionForm(queryset=qs) return render(request,'types.html',{'types':'types'}) Widgets accept the attrs attribute, which should add an attribute to each input. Try the following:
checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(attrs={'class': 'my-image-class', }), label="", required=False) UPDATE:
So, it seems that the granular approach mentioned above only works for switch widgets. But what you want is actually very simple. Just display your checkboxes as usual:
{% for field in types.checkbox_field %} {{field}} {% endfor %} This will remove your checkbox list as needed. Then, just use a little CSS to create a background image for each list item:
form ul li { background:url("<my-image>") no-repeat center; width:20px; height:20px; }
UPDATE
If you want to render checkboxes differently, you need your own widget class, like this widget job. Something like this will make you go. I personally used the attrs parameter for the widget to add to the class, but I hardcoded it here to show you that what you're asking for is probably just not pretty:
class CheckboxDivSelectMultiple(CheckboxSelectMultiple): '''renders the checkboxes as divs with a hard coded class''' def render(self, name, value, attrs=None, choices=()): if value is None: value = [] has_id = attrs and 'id' in attrs final_attrs = self.build_attrs(attrs, name=name) output = [u'<div>'] # Normalize to strings str_values = set([force_unicode(v) for v in value]) for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): # If an ID attribute was given, add a numeric index as a suffix, # so that the checkboxes don't all have the same ID attribute. if has_id: final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i)) label_for = u' for="%s"' % final_attrs['id'] else: label_for = '' cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) option_value = force_unicode(option_value) rendered_cb = cb.render(name, option_value) option_label = conditional_escape(force_unicode(option_label)) output.append(u'<div class="%s"><label%s>%s %s</label></div>' % ('new-class', label_for, rendered_cb, option_label)) output.append(u'</div>') return mark_safe(u'\n'.join(output)) use it in your form:
checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxDivSelectMultiple(), label="", required=False) This is similar to @bhappy's solution. The general solution is to define your own as_div method and use it as a template filter in your templates. Have a look at this django snippets article: Custom Form Example: Bootstrap Html Forms - CSS Toolkit