Customize radioselect default renderer - django

I have the following form with radioselect options :
jobStatus = forms.ChoiceField( widget=forms.RadioSelect())
However, it renders the radio buttons in <ul> <li> .. </li></ul> tags.
Could you suggest me any way to render the only radiobutton input ?
Thanks

This is a nice how-to for overriding the renderer of the radio select widget.
https://wikis.utexas.edu/display/~bm6432/Django-Modifying+RadioSelect+Widget+to+have+horizontal+buttons
Basically, create a class that inherits from the forms.RadioFieldRenderer class and override the render method. Then in your form when setting the widget use the renderer argument to set the renderer to your custom renderer class.
That being said, I usually just change the appearance using CSS

Related

Don't render abel for id in django form

Is it possible not to render the for attribute of a label?
I want <label>Text</label> instead of <label for="id_i">Text</label> ?
you will need to manually render the form field: <label>{{field.label}}</label> will render the label as you require. See the docs for how to manually render form fields: https://docs.djangoproject.com/en/dev/topics/forms/#looping-over-the-form-s-fields
I more flexible solution is to override id_for_label in a widget.

Django - Field attributes in widget context

As I am using some more exotic css framework I would like to change the behaviour of the text input (provide it with label etc. by default).
I have overridden the template in django/forms/widgets/input.html
Unfortunately the widget context is missing the field, so I cannot use field properties like help_text, label, etc in my template. Therefore I would need to override the TextInput widget.
My two options are now:
Setting my own widget class for every single field in my Form / Modelform classes
Using My custom ModelForm which iterates all the fields in __init__ and replaces the widget.
Is there any better way to override django's default text_input widget?
Does is there any other way to get field.errors and field.label into the widget
(Or is there a reason why there is no label in the widget context)?

set the css class of a form widget based on the data

The attrs attribute of a widget allows to define the html attributes. For example, setting it to widget.attrs['class'] = 'class1 class2' will add class="class1 class2" on the rendered widget.
However, how can I set them based on the data? I display an update form and I'd like to change the CSS class based on the data that is going to be displayed when the form is rendered.
Where could I check for the data in order to change the attrs property of the widget before it is rendered?
Thanks
You have the data in your context, so you should be able to do {% if %} testing the data you want to change the class

django - Creating a radio select with select box options

I want to create a set of radio options that look like so:
The non-standard part is that selecting the first or second radio button option requires the user to further specify information from a select box.
How do I do this with a django form? Based on what I see in the docs you can pass a Choices 2-tuple with only strings as the human-readable values, I need the ability to pass a widget plus a label. I am rendering the form via django-crispy-forms in the template (i.e. all my template has is {% crispy form %}), so I would prefer a solution that doesn't require any template-side manipulation.
Thanks!
in forms.py
CHOICES = (('0', 'option1',), ('1', 'option2',), ('2', 'option3',))
class NameForm(forms.ModelForm):
options = forms.ChoiceField(initial=0, widget = forms.RadioSelect(renderer = HorizontalRadioRenderer), choices=OPTIONS)

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.
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.
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"/>')
});
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}}