Overriding __init__ for a form and setting the checkbox disabled and using initial=True
I have a form where I am overriding the init so I can set some checkboxes to be disabled, these disabled checkboxes are pre-checked.
cl开发者_开发技巧ass HomePhoneBundleOrderForm(forms.Form):
def __init__(self, *args, **kwargs):
super(HomePhoneBundleOrderForm, self).__init__(*args, **kwargs)
self.fields['telephone_line'].widget.attrs['disabled'] = 'disabled'
self.fields['voice_mail'].widget.attrs['disabled'] = 'disabled'
telephone_line = forms.BooleanField(initial=True, help_text="Local telephone line included.")
voice_mail = forms.BooleanField(label="", help_text="Voicemail – included in this bundle.", initial=True)
The problem is when I submit this form, even when they are pre-checked, the form gives me an error saying that the field is required and then the checkbox becomes unchecked. Can you anyone give me some help as to why and how to fix this?
Thanks
-J
Here's another option that will work for both single Forms as well as Formsets. @sandinymyjoints links to a good post and the accepted answer there is certainly well thought out. But hacking Request parameters can lead to a lot of trouble as a general rule. As a specific case, hacking the POST of a formset submission involves regex and that's really ugly. In a Formset (remember that they are collections of Forms), your forms will POST as form-0-telephone_line
and form-0-voice_mail
and such. Try this instead.
In your Form class define two fields - a visible one to look good and a hidden one to carry the data. The visible checkbox will be disabled and thus will never POST (as you well know), but it will give clear visual indication to the user what is happening. The hidden checkbox will hold your initial True checked status.
class HomePhoneBundleOrderForm(forms.Form):
def __init__(self, *args, **kwargs):
super(HomePhoneBundleOrderForm, self).__init__(*args, **kwargs)
self.fields['telephone_line_visible'].widget.attrs['disabled'] = 'disabled'
telephone_line = forms.BooleanField(initial=True,
widget=forms.HiddenInput)
telephone_line_visible = forms.BooleanField(initial=True,
required=False,
label="Telephone line",
help_text="Local telephone line included.")
Or if you want to keep the "hack" code entirely in one location:
def __init__(self, *args, **kwargs):
super(HomePhoneBundleOrderForm, self).__init__(*args, **kwargs)
# Hack
self.fields['telephone_line'].widget=forms.HiddenInput()
self.fields['telephone_line_visible'] = forms.BooleanField(initial=True,
required=False,
label="Telephone line",
help_text="Local telephone line included.")
self.fields['telephone_line_visible'].widget.attrs['disabled'] = 'disabled'
I think you are having the same problem as this: disabled field is not passed through - workaround needed
"Since you are disabling the widget and not the field, as far as the form is concerned it's always receiving nothing for fieldA and that will always fail validation."
See the accepted answer to that question for some possible solutions. Looks like the best one involves modifying POST to put the value you want into the fields.
You could try enabling them on the client side before submitting with javascript/jQuery, something similar to this:
//enable disabled fields so they would get submitted with the request
$('#form').submit(function() {
$('input,select', this).prop('disabled', '');
return true;
});
精彩评论