Search code examples
djangodjango-formsdjango-1.5django-formwizard

Add custom html to choicefield label in django


I am struggling with a requirement now, I want to add an image to choice field label and I really dont have a clue how to do it. I am using django form wizard to render the form. Here is the image which shows what I want to achieve : enter image description here

And here is what I have got right now ( to make the radio buttons inline, I know it could be achieved through css): enter image description here

Here is the forms.py:

from django import forms
from django.utils.translation import gettext as _


CHOICES=[('0','Pay by card'), ('1','Invoice')]




class PaymentForm(forms.Form):
    title = 'payment'
    payment_method = forms.ChoiceField(label = _("Payment Options"), choices=CHOICES, widget=forms.RadioSelect(), required = True)

I am rendering using wizard form:

 {{ wizard.form.payment_method.label_tag }}
                                {{ wizard.form.payment_method|safe }}
                                {{ wizard.form.payment.errors}}

Anyone has any suggestion for this apart from custom widget?


Solution

  • 1) Shortly (but i'm not sure) call a function where 'Pay by card' and return all <img>... that you need.

    2) You can make somthing like @Gahbu said

    3)Long [Better, i think, but untested :( ]: Make a renderer:

    from myapp.my_widgets import CardsRadioFieldRenderer
    
    CARD_CHOICE = '0'
    
    CHOICES=[(CARD_CHOICE,'Pay by card'), ('1','Invoice')]
    
    class PaymentForm(forms.Form):
        title = 'payment'
        payment_method = forms.ChoiceField(label = _("Payment Options"), choices=CHOICES,widget=forms.RadioSelect(renderer=CardsRadioFieldRenderer), required = True)
    
    # myapp/my_widgets.py
    
    class CardRadioInput(RadioInput):
        def __init__(self, name, value, attrs, choice, index):
            self.name, self.value = name, value
            self.attrs = attrs
            choice_value = force_text(choice[0])
            self.choice_value = choice_value
            if choice_value == CARD_CHOICE:
                choice_label = force_text(self.get_html_for_card_choice())
            else:
                choice_label = force_text(choice[1])
            self.choice_label = choice_label
            self.index = index
    
       def get_html_for_card_choice(self):
            #some logic to get the images tags (<img ...> <img ...>)
            return text
    
    
    class CardsRadioFieldRenderer(RadioFieldRenderer):
        def __getitem__(self, idx):
            choice = self.choices[idx] # Let the IndexError propogate
            return CardRadioInput(self.name, self.value, self.attrs.copy(), choice, idx)