Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The "required" attribute should not be set for fields in an empty_permitted form #168

Open
dylanmccall opened this issue Mar 19, 2016 · 1 comment

Comments

@dylanmccall
Copy link

I am using Floppyforms in an elaborate form page consisting of several nested ModelForm objects, and some form sets. Some of these form sets have min_num=0, which causes the initial forms to be created with empty_permitted = True. That is, the server-side validation won't complain if the entire form is empty. Required fields are only enforced if the form has been modified. However, even for those forms, any fields marked as required are given the HTML5 required attribute, making it impossible to submit the form without filling them in.

Steps to reproduce:

  • Create a Form with a required field.
  • Instantiate the form with empty_permitted=True.
  • When the form is rendered, it should be possible to submit it in a modern browser without setting a value for the field. Instead, the client-side validation rules make this impossible: the browser will complain that the field requires a value.

And a simple code example:

import floppyforms as forms
class OptionalForm(forms.Form):
    name = forms.CharField(required=True)
optional_form = OptionalForm(empty_permitted=True)
print(optional_form.as_p().strip())

Expected output:

<p>
    <label for="id_name">Name:</label>
    <input type="text" name="name" id="id_name">



</p>

Actual output:

<p>
    <label for="id_name">Name:</label>
    <input type="text" name="name" required id="id_name">



</p>

Workaround

Here's a workaround I have been using. A complete solution also needs some JavaScript code that interprets data-was-required and does fun things:

class TKDModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(TKDModelForm, self).__init__(*args, **kwargs)    

        if self.empty_permitted:
            for key, field in self.fields.iteritems():
                if field.widget.is_required:
                    field.widget.is_required = False
                    field.widget.attrs.pop('required', None)
                    field.widget.attrs['data-was-required'] = True

This goes through every field in the form, and if the widget has been marked as required we make sure to strip the required attribute, set is_required = False (so it isn't passed to the widget's template), and then add our own attribute to keep track of this field's more complex validation rules.

@gregmuellegger
Copy link
Collaborator

Hm, I think I see the problem here. We have a server-side behaviour in the form (allow either all fields to be empty, unless at least one field is filled in, then require all to be filled in) that we cannot replicate with a html-only solution.

I would recommend adding the novalidate attribute to your <form> tag as described here: http://django-floppyforms.readthedocs.org/en/latest/differences.html#client-side-validation

But I know that this does not replicate the behaviour you expect. What would you suggest as a solution? Remove the <input required> attributes when empty_permitted=True?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants