django - Creating a radio select with select box options - django

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)

Related

A Select Widget with fields as checkboxes with multiple options possible

I have the following model:
class Owner(models.Model)
country = models.CharField(max_length=255, choices=COUNTRIES, default=COUNTRIES_DEFAULT)
COUNTRIES is compose of tuples:
COUNTRIES = (
('afg', 'Afghanistan'),
('ala', 'Aland Islands'),
('alb', 'Albania'),
('dza', 'Algeria'),
('asm', 'American Samoa'),
....... )
For FrontEnd, I need to show a Widget, and for each country to have a checkbox.
A Person/User can select multiple Countries.
I presume I need to use a custom widget, but I don't know where to start inherit for Field/Widget and make the query in the database.
--- Why is not a duplicate of Django Multiple Field question ----
I don't need a new Model field, or to store it in the database and is not a many to many relation, so something like the package django-multiselectfield is not useful.
The ModelField is storing just one value, but in the form will appear values from the tuple.I added just to see the correspondence.
Instead I need to be just a Form Field, to get the values, and query the database. Like get all owners that resides in USA and UK.
Also is not looking like Select2, I need to respect design. As functionality is like in the image:
In your Form you must define a MultipleChoiceField with the CheckboxSelectMultiple widget:
countries = forms.MultipleChoiceField(choices=COUNTRIES, widget=forms.CheckboxSelectMultiple)
This will give you a list of multiple choice checkboxes. You can style that yourself to appear with a scrollbar if you don't want to show a long list.
Here is an example from the Django documentation: https://docs.djangoproject.com/en/2.1/ref/forms/widgets/#setting-arguments-for-widgets

Django forms.SelectMultiple complains about choices

I'm trying to create a form consisting of a multiple select field which is used to select multiple instances of my Person model.
class MyForm(forms.Form):
choices = [(p.id, str(p)) for p in Person.objects.all()]
my_field = forms.ChoiceField(widget=forms.SelectMultiple, choices=choices)
The widget looks exactly like I want, but when I submit the form, it fails with the message
Select a valid choice. ['2', '3'] is not one of the available choices.
What am I doing wrong? When removing the widget=forms.SelectMultiple, from the third line, it works, but then it's only a single select field.
You are getting the error because ChoiceField expects a single choice.
If you want to allow multiple choices, use a MultipleChoiceField.
my_field = forms.MultipleChoiceField(choices=choices)
Note you don't have to specify the widget, as it's forms.SelectMultiple by default.

Django Forms: En-/Disable a Charfield dynamically

i have a form with a ChoiceField and a CharField. Now i want to enable the CharField just when i select a specific choice of the ChoiceField (e.g. choice 3). Otherwise the CharField should be disabled.
My ChoiceField
choices = (('1', 'some text',),
('2', 'some text',),
('3', 'some text',))
host = forms.ChoiceField(choices = choices)
And a simple CharField
hostAdress = forms.CharField()
Do you have any ideas to get it this way?
you can start with the char field disabled/hidden and use javascript to catch change event on the select box and change the charfield on that event. For example:
$("#id_choice").change(function(eObj) {
$("#id_char").removeAttr("disabled");
this is just an example (using jQuery), you need to make sure to disable the charfield again if the select box is unselected (not sure if you allow this behaviour) and you also need to handle the display of form errors properly if you hide the field and not enable/disable it.
I would use jQuery for this.
$('your-select-input-selector').change(function() {
var bDisable = true;
if ($(this).val() == '3'):
bDisable = !bDisabled;
$('your-text-input-selector').prop('disabled', bDisable);
});
You also need to handle the case where the select input is already set on the value 3 when you first load the page.

Render (and validate) related choice form fields in Django

I am trying to work out the best way to implement a form in django that has two choice fields on it, one of which affects the choices available in the other. An example - form field one is a radio button (can choose only one option) called 'cuisine', and the second is a multichoice field called 'menu'. If you choose 'french' from 'cuisine' then you get french dishes in the menu list, but if you choose 'chinese' you get a different selection.
How do I work this server-side in the form validation process. How do I 'bind' the two controls so that only dishes related to the cuisine option are accepted?
And how do I render this - should I pass in a ModelForm for each type of cuisine, or have a single menu ModelForm that has everything in it, and just show/hide stuff on the client-side?
All of the menu options are stored in the db and loaded in as fixtures, and the cuisines are hard-coded into the app:
CUISINE = ((0,'French'),(1,'Chinese'),(2,'Italian'))
class MenuItem(models.Model):
description = models.CharField(max_length=200)
cuisine = models.IntegerField('Cuisine', choices=CUISINE)
For rendering, you can use django-selectable or django-autocomplete-light,
For server side validation, django has it completely documented.

How do I construct a Django form with model objects in a Select widget?

Let's say I'm using the Django Site model:
class Site(models.Model):
name = models.CharField(max_length=50)
My Site values are (key, value):
1. Stackoverflow
2. Serverfault
3. Superuser
I want to construct a form with an html select widget with the above values:
<select>
<option value="1">Stackoverflow</option>
<option value="2">Serverfault</option>
<option value="3">Superuser</option>
</select>
I'm thinking of starting with the following code but it's incomplete:
class SiteForm(forms.Form):
site = forms.IntegerField(widget=forms.Select())
Any ideas how I can achieve that with Django form?
EDIT
Different pages will present different site values. A dev page will show development sites while a cooking page will show recipe sites. I basically want to dynamically populate the widget choices based on the view. I believe I can achieve that at the moment by manually generating the html in the template.
I think you're looking for ModelChoiceField.
UPDATE: Especially note the queryset argument. In the view that is backing the page, you can change the QuerySet you provide based on whatever criteria you care about.
I haven't tested this, but I'm thinking something along the lines of...
site = forms.IntegerField(
widget=forms.Select(
choices=Site.objects.all().values_list('id', 'name')
)
)
Edit --
I just tried this out and it does generate the choices correctly. The choices argument is expecting a list of 2-tuples like this...
(
(1, 'stackoverflow'),
(2, 'superuser'),
(value, name),
)
The .values_list will return that exact format provided you have the ID and the name/title/whatever as so: .values_list('id', 'name'). When the form is saved, the value of .site will be the id/pk of the selected site.