Django Form Wizard with Conditional Questions
Asked Answered
S

1

3

In my Django application, I currently have a form wizard with a few form classes. I would like to have the ability to have conditional questions. Meaning if the user selects yes for a certain question, another question within the form will become required and javascript will make the question visible. I found an example of how to do this online, however it doesn't work. Any suggestions on how I can create this functionality?

class QuestionForm(forms.Form):

COOL_LIST = (
    ('cool','Cool'),
    ('really cool','Really Cool'),
)

YES, NO = 'yes','no'

YES_NO = (
    (YES,'Yes'),
    (NO,'No'),
)

are_you_cool = forms.ChoiceField(choices=YES_NO,label='Are you cool?')
how_cool = forms.MultipleChoiceField(required=False,widget=CheckboxSelectMultiple, choices=COOL_LIST,label='How cool are you?')

def __init__(self, data=None, *args, **kwargs):
    super(QuestionForm, self).__init__(data, *args, **kwargs)

    if data and data.get('are_you_cool', None) == self.YES:
        self.fields['how_cool'].required = True
Stern answered 10/8, 2013 at 18:5 Comment(1)
You have to understand the web client-server flow. For your issue you've two choices: you chain forms, and thus for each form sent to the client and submited by him, the server sends to the client a new form according to your conditions. This is the standard solution. Another is: you send only one form to the client, but when he fills the fields, the form change whithout any communication with your server. This is the Ajax way, what do you prefer ?Shelby
K
0

Try to replace __init__ method of your form with custom clean_are_you_cool method. So, if user submit value Yes you should check if how_cool field is populated too. You also should do this on client side to provide great user experience. Something like this with forms:

def clean_are_you_cool(self):
    if self.cleaned_data.get('are_you_cool', None) == 'Yes':
        if self.cleaned_data.get('how_cool', None) is not None:
           #  Actions for cool user. 
           pass
    #  Or if user not cool.
Kopple answered 10/8, 2013 at 18:55 Comment(1)
Sorry for the long delay. I had to work on some other code and decided to push this off until later. I simply changed my code to something similar to [if data and data.get('drink', None) == "yes":] instead of the self.YES and it worked. This should work in most cases. Thanks for the suggestion.Stern

© 2022 - 2024 — McMap. All rights reserved.