Reputation: 3
I'm building my first web app with django and am having a hard time figuring out how to use dynamic form in order to have different output for different selected choice.
for example, for my measure choice qualitative, I want the form be the same(no extra fields) but if the quantitative value is selected, I want my template to show two more fields(value_min and value_max)
the first option when qualitative value is selected
the second option when quantitative value is selected
thank you for your help...
Upvotes: 0
Views: 657
Reputation: 3
thanks @videap and @Rhea for your help... so I figured out how to resolve my problem using the guidance of videap and the post Show and hide dynamically fields in Django form
So the solution was:
for the form :
class NewCriterioForm(forms.ModelForm):
parent = TreeNodeChoiceField(queryset=Criteria.objects.all())
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.criteria_CHOICES = [('FunCriteria','FunCriteria'),('nonFunCriteria','nonFunCriteria')]
self.mesure_CHOICES = (('Quantitative','Quantitative'),('Qualitative','Qualitative'))
self.fields['parent'].label=''
self.fields['parent'].required=False
self.fields['type']= forms.CharField(widget=forms.Select(choices=self.criteria_CHOICES))
self.fields['mesure']= forms.ChoiceField(choices=self.mesure_CHOICES)
class Meta:
model = Criteria
fields = ('name', 'parent', 'type','slug','description','mesure','value_min','value_max')
}
for the view :
......
criterion = NewCriterioForm()
return render(request, 'addCriteria.html', {'criterion': criterion})
and finaly, in the template , I put this code:
<script>
function Hide() {
if(document.getElementById('id_mesure').options[document.getElementById('id_mesure').selectedIndex].value == "Qualitative") {
document.getElementById('id_value_min').style.display = 'none';
document.getElementById('id_value_max').style.display = 'none';
} else {
document.getElementById('id_value_min').style.display = '';
document.getElementById('id_value_max').style.display = '';
}
}
window.onload = function() {
document.getElementById('id_mesure').onchange = Hide;
};
</script>
<div>
{{ criterion.name.label_tag }}{{ criterion.name }}
</div>
<tr></tr>
<div>
{{ criterion.parent.label_tag }}{{ criterion.parent }}
</div>
<div>
{{ criterion.type.label_tag }}{{ criterion.type }}
</div>
<div>
{{ criterion.slug.label_tag }}{{ criterion.slug }}
</div>
<div>
{{ criterion.description.label_tag }}{{ criterion.description }}
</div>
<div>
{{ criterion.mesure.label_tag }}{{ criterion.mesure }}
</div>
<div id="id_value_min">
{{ criterion.value_min.label_tag }}{{ criterion.value_min }}
</div>
<div id="id_value_max">
{{ criterion.value_max.label_tag }}{{ criterion.value_max }}
</div>
Upvotes: 0
Reputation: 644
Forms are rendered on the template before the page load. So, django variables cannot e manipulated by the user.
While rendering your form, django allows you to set classes to the form fields. use them to hide the extra fields.
example value_min = forms.CharField(widget=forms.TextInput(attrs={'class':'hide'}))
you may add a form check while clean
class MYform(forms.Form):
#....
def clean_min_value(self):
#check here for choice field value
#return value or blank accordingly
similarly you can add validators to the form to ensure this value is only set if choice is set to quantitative
value_min = forms.CharField(widget=forms.TextInput(attrs={'class':'hide'}), validators=[check_choice])
def check_choice(Value):
# validate Value
Upvotes: 0
Reputation: 86
You can't use the django tags for conditions, because it only renders from the backend, so this is a frontend issue. In my implementations I normally use javascript with the following idea:
Upvotes: 1