Marcio Cruz
Marcio Cruz

Reputation: 2069

How do I make a RadioSelect have a image as radio value?

I have the following form:

class ReviewForm(forms.ModelForm):
class Meta:
    model = Review

    widgets = {
        'tipo' : forms.RadioSelect(),
    }

But I want to use images as the values of my radio buttons, the image will vary according to the option, like this:

<input type="radio" id="id_tipo_0" value="UP" name="tipo" /><img src="/images/thumb_up.gif"/>
<input type="radio" id="id_tipo_1" value="DOWN" name="tipo" /><img src="/images/thumb_DOWN.gif"/>

I have no clues on how to achieve this.

Upvotes: 2

Views: 3384

Answers (3)

Wouter Klein Heerenbrink
Wouter Klein Heerenbrink

Reputation: 1391

There is a nice solution for this issue!

A ModelChoiceField has the method label_from_instance(self, obj). This method is called for every option in the ModelChoiceField.

You can overwrite ModelChoiceField.label_from_instance with:

def label_from_instance(obj):
    """
    Shows an image with the label
    """
    image = conditional_escape(obj.thumbnail_image.url)
    title = conditional_escape(obj.title)

    label = """<img src="%s" />%s""" % (image, title)

    return mark_safe(label)

Note: you need to use mark_safe, otherwise the renderer will escape the img tag. Do apply the conditional_escape to the user input values (title and url).

If you want to use a regular ChoiceField you can just add HTML to the choices parameter and add mark_safe.

Upvotes: 12

errx
errx

Reputation: 1791

You can override RadioSelect (and RadioFieldRenderer) class.

OR! you can use jquery ( or something similar) to insert your img dynamically.

$(document).ready(function(){
  $("#id_tipo_0").after('<img src="/images/thumb_up.gif"/>')
  $("#id_tipo_1").after('<img src="/images/thumb_down.gif"/>')
});

Upvotes: 1

Dominique Guardiola
Dominique Guardiola

Reputation: 3431

If you want to use Django form rendering function, you'll have to use javascript to modifiy the DOM, and this will be a mess because the names of the option are rendered just after the input tag, not enclosed in any tag...

If your form does not have any other tags, go ahead, just write your input just as in your example, carefully using the Django names and values for the radio input, add a submit button, a CSRF token and that's all, you'll be able to validate your form in the view like if it was rendered via {{form.as_p}}

Upvotes: 0

Related Questions