jrief / django-angular

Let AngularJS play well with Django
http://django-angular.awesto.com/
MIT License
1.23k stars 293 forks source link

AngularJS client form validation ignores model RegexValidator #342

Open Hoffik opened 5 years ago

Hoffik commented 5 years ago

I have implemented django-angular client side form validation. Every constraint is validated as expected apart from my model RegexValidator (the error is later caught on the server's side so I believe everything is fine with the validator itself). Does django-angular ignore model (or form) defined RegexValidators or am I doing something wrong?

# models.py
class Contact(models.Model):
    firstname = models.CharField(max_length=254)
    lastname = models.CharField(max_length=254)
    address = models.CharField(max_length=254)
    email = models.EmailField(max_length=254)
    phone_regex = RegexValidator(regex=r'^\+\d{8,15}$', message="Phone number must be entered in the format: '+99999999'. Up to 15 digits allowed.")
    phone = models.CharField(validators=[phone_regex], max_length=16)
# forms.py
from djng.forms import NgFormValidationMixin, NgModelForm
from .models import Contact

class ContactForm(NgFormValidationMixin, NgModelForm):
    form_name = 'contact_form'

    class Meta:
        model = Contact
        fields = ('firstname', 'lastname', 'address', 'email', 'phone')
# views.py
from .forms import ContactForm
from django.views.generic import FormView

class ContactFormView(FormView):
    template_name = 'contact_add.html'
    form_class = ContactForm
    success_url = reverse_lazy('contacts:contact-list-view')
<!-- contact_add.html -->
<form name="{{ form.form_name }}" novalidate>
    {% csrf_token %}
    {{ form }}
    <button type="submit" class="btn" ng-disabled="{{ form.form_name }}.$invalid" ng-click="addContact()">Add contact</button>
</form>
jrief commented 5 years ago

The JavaScript prevalidation uses the same regex pattern as Python. I'm not really sure if they are 100% compatible, but the above pattern seems simple enough. In doubt, try the offending number against a pattern using JS and Python and check if there is a difference.

Hoffik commented 5 years ago

Thanks a lot for your reply. The regex itself is ok. It works just fine in Python and JS alike. I believe the problem is that the validation does not propagate from Django's model/form to the front layer. I.e. the validation on client's side does not even start. For example when I tried to print all possible error messages I can see all restrictions (field required, max length, valid email) except for the regex validation.

<!-- contact_add.html -->
    <form>
        {% csrf_token %}
        {% for field in form %}
        <div class="form-group">
            {{ field.label_tag }}<br>
            {{ field }}
            {% for error in field.errors %}
                <div class="alert alert-danger">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
        </div>
        {% endfor %}
        <button type="submit" class="btn" ng-click="addContact()">Add contact</button>
    </form>
//output
...
Email
("contact_form['email']", 'djng-field-errors', '$dirty', '$error.required', 'invalid', 'This field is required.')
("contact_form['email']", 'djng-field-errors', '$dirty', '$error.email', 'invalid', 'Enter a valid email address.')
("contact_form['email']", 'djng-field-errors', '$dirty', '$valid', 'valid', '')
Phone
("contact_form['phone']", 'djng-field-errors', '$dirty', '$error.required', 'invalid', 'This field is required.')
("contact_form['phone']", 'djng-field-errors', '$dirty', '$error.maxlength', 'invalid', 'Ensure this value has at most 16 characters')
("contact_form['phone']", 'djng-field-errors', '$dirty', '$valid', 'valid', '')

Nevertheless, I realized the proglem is not caused by django-angular library. When I removed all dependencies and left just the default validation it doesn't work either. I should probably move my question to generic stackoverflow discussion.