diegopau
diegopau

Reputation: 1344

Using default popups to show Django Forms errors

When defining a form using Django Forms, if I have an EmailField, I will get some neat popups like I show in the pictures:

Chrome Firefox

But if I introduce a custom validation, I am unable to show errors to user in the same way (with a popup)

This is my forms.py:

from django import forms
from launcher.models import InterestedUser
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator

class JoinForm(forms.ModelForm):
# this is the only field that is actually filled by the user
    email = forms.EmailField(max_length=128, help_text="Introduce la cuenta de gmail que tienes asociada a tu"
                                                   "dispositivo Android",
                         widget=forms.EmailInput(attrs={'class': "w-input email_input",
                                                        'placeholder': 'Tu email de Google'}),
                         required=True, validators=[RegexValidator(regex='^([a-zA-Z0-9_\.\-])+\@(gmail.com)+$',
                                                                   message="La dirección de email no es válida",
                                                                   code="invalid_gmail_address")])
print("atributos {0}".format(email.widget.attrs['class']))

# this other fields will have the same value and go hidden in the form
name = forms.CharField(widget=forms.HiddenInput(), initial="(not specified)")
subject = forms.CharField(widget=forms.HiddenInput(), initial="(no subject)")
via = forms.CharField(widget=forms.HiddenInput(), initial="Join")
content = forms.CharField(widget=forms.HiddenInput(), initial="no content")

def clean_email(self):
    email = self.cleaned_data.get('email')

    try:
        beta_tester = InterestedUser.objects.get(email=email)
    # Si el email no existiese entonces salimos del clean_email y devolvemos el valor (aunque no se haya modificado)
    except InterestedUser.DoesNotExist:
        return email
    # Si el email ya existía sacamos un error de Validación:
    raise forms.ValidationError("Ya estabas anotado como Beta Tester, introduce un email diferente!")


class Meta:
    model = InterestedUser
    fields = ('email', 'name', 'subject', 'via', 'content',)

And this is how I render it in the template:

            <div class="w-form formulario" id="formulario">
                <form class="w-clearfix formulario_subscribe" name="email-form" id="join_form" method="post" data-name="Email Form" action="/">
                    {% csrf_token %}
                    {% for hidden in form.hidden_fields %}
                        {{  hidden }}
                    {% endfor %}
                    {% for field in form.visible_fields %}
                        {{ field.errors }}
                        {{ field.help_text }}
                        {{ field }}
                    {% endfor %}
                    <input class="w-button email_submit_button" type="submit" id="btn_send" value="Join" data-wait="Un momento!..."/>
                    {% if messages %}
                        <ul class="messages">
                            {% for message in messages %}
                                <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
                            {% endfor %}
                        </ul>
                    {% endif %}
                </form>
            </div>

I have a RegexValidator and I would like to show the error message if the user input doesn't pass the validator in the same way (popups) that the default validator does it! Any ideas??

Thanks a lot in advance.

Upvotes: 1

Views: 2079

Answers (1)

fasouto
fasouto

Reputation: 4511

I think this popup is created by the browser validating the HTML5 email field(looks like chrome) you can disable this validation adding the novalidate attribute to the form field. Or more interesting you can use pattern to check for gmail.com addresses, something like:

<input type="email" pattern="/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected]$" />

If you want to validate on the client side you can use something like parsley

Also instead of validate emails with a regex you can check EmailValidator. There's a property domain_whitelist that you can use to restrict gmail.com domains.

Upvotes: 1

Related Questions