[Answered ]-Django target individual check boxes in template

2๐Ÿ‘

I recommend writing your own subclass of the CheckboxSelectMultiple widget to do this, overriding its render method. The rendering code is pretty straightforward, but that widget returns the entire <ul> element with the checkboxes pre-rendered โ€“ trying to pull out the representations of the individual checkboxes in a template is going to be tricky at best.

Something like this:

class ImageCheckboxSelectMultiple(CheckboxSelectMultiple):

    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'<ul>']
        # 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))
            # Here's the new part
            image_element = u'<img src="/images/some_image.png">'
            output.append(u'<li>%s<label%s>%s %s</label></li>' % (image_element, label_for, rendered_cb, option_label))
        output.append(u'</ul>')
        return mark_safe(u'\n'.join(output))

Depending on your setup you might want to use STATIC_URL as part of the image path.

๐Ÿ‘คPeter DeGlopper

0๐Ÿ‘

For Completeness, here is my solution:

I store the necessary fields for the available accessories in a python dict, then pass to javascript in the template:

var AccessoryArray = new Array();
{% for accessory in available_accessories %}
    var this_object = new Object();
    this_object.description = "{{ accessory.full_description }}";
    this_object.filename = "{{ accessory.filename }}";
    AccessoryArray[{{ accessory.pk }}] = this_object;
{% endfor %}


$(document).ready(function() {
  // iterate through the accessory checkboxes
  $('input.accessory-checkbox').each(function(){

    // construct output for image and full description
    var filename_output = '<img src="' + media_url + 'parts/' + AccessoryArray[$(this).val()].filename + '" />';
    var description_output = '<span class="accessory-description-text">' + AccessoryArray[$(this).val()].description + '</span>';

    // insert html after the input label
    $(this).parent().after(description_output).after(filename_output);
  });
});
๐Ÿ‘คDarwin Tech

Leave a comment