1

I am trying to create a form where the users will enter their emails. Typically the validation errors for email(empty field or not proper format) are displayed by the browser.

Using the basic form example, everything shows correctly:

<form action="/notify-email/add/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit" />
</form>

enter image description here

In my case, if there are no validation errors I use an ajax request to save the email and show a modal with a thank you message.But if there are validation errors I can see them when only if I hover. enter image description here

Also, the modal is shown even if there are errors in validation.

This is my models.py:

from django.db import models


class NotifyEmail(models.Model):
    email = models.EmailField(max_length=255)
    date_added = models.DateField(auto_now_add=True)
    time_added = models.TimeField(auto_now_add=True)

    def __str__(self):
        return self.email

This is the form based on the model:

from django import forms
from landing.models import NotifyEmail


class NotifyEmailForm(forms.ModelForm):
    class Meta:
        model = NotifyEmail
        fields = ["email"]

    def __init__(self, *args, **kwargs):
        super(NotifyEmailForm, self).__init__(*args, **kwargs)

        self.fields['email'].widget = forms.EmailInput(attrs={'placeholder': 'Email',
                                                              'required': True})

My views.py:

from django.shortcuts import render
from django.http import JsonResponse
from .forms import NotifyEmailForm



def add_notify_email(request):
    if request.method == "POST":
        form = NotifyEmailForm(request.POST)

        if form.is_valid():
            form.save(commit=True)
            print("Email Added.")
            return JsonResponse({'msg': 'Data saved'})
        else:
            print("Error in Notify Form")
            return JsonResponse({"msg": "Error"})

    else:
        form = NotifyEmailForm()
    return render(request, "landing/home.html", {"form": form})

My urls.py:

from django.conf.urls import url
from . import views

urlpatterns = [url(r'^notify-email/add/$', views.add_notify_email)]

The html code:

<div class="container-fluid" id="comingSoon">
    <div class="container">
        <h2>Coming Soon</h2>
        <h5>If you want to get notified when we go live, please enter your email below.</h5>
    </div>
    <div class="container" id="notify-email-container">
        <form action="/notify-email/add/" method="post" id="notify-email-form">
            {% csrf_token %}
            <div class="form-group row">
                <div class="col-sm-10" id="email-input-container">
                    <input class="form-control" type="email" name="email" placeholder="Your email...." maxlength="255" required id="id_email" />
                </div>

                 {% for error in form.email.errors %}
                    <div class="alert alert-error">
                        <p class="field-error"><i class="fa fa-exclamation-circle" aria-hidden="true"></i>{{ error|escape }}</p>
                    </div>
                {% endfor %}
                <div class="col-sm-2">
                    <button type="button" class="btn btn-block btn-primary" onclick="addNotifyEmail()" id="submit-notify-email">Notify Me</button>

                </div>
            </div>
        </form>
    </div>
</div>


<div class="modal" tabindex="-1" role="dialog" id="thanks">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Thank you</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>We would like to thank you for your interest.</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<script>
    function addNotifyEmail(e){
        var notifyEmailForm = $("#notify-email-form");
        var thanksModal = $("#thanks");

        $.ajax({
        type: 'POST',
        url: '/notify-email/add/',
        data: notifyEmailForm.serialize(),
        success: function(res){
                   thanksModal.modal('show')}

    })}
</script>
IordanouGiannis
  • 4,149
  • 16
  • 65
  • 99

1 Answers1

0

I'm not sure that I'm understanding your question well.

So, the problem is if you have some validation errors they appear in your "errors" div, only if you hover them? If it is, then it is related to your css or javascript. Check your scripts and css files. Maybe somewhere you trigger your .field-error element.

About modal appearence. Well, it is about your AJAX request.

In your code, you will get showing your modal anyway while the HTTP Request will get answer with 200 code. It means even if you will not have valid form you sending back JsonResponse with some msg and its bringing back to your page, which means your script will trigger success every time and that's why your modal is appearing.

Instead of just sending some JsonResponse({"msg": "Error"}), try to use it also to handle error.

function addNotifyEmail(e){
    var notifyEmailForm = $("#notify-email-form");
    var thanksModal = $("#thanks");

    $.ajax({
    type: 'POST',
    url: '/notify-email/add/',
    data: notifyEmailForm.serialize(),
    success: function(res){
        if(res.msg !== "Error") {
               thanksModal.modal('show');
        }
    }
})}

Take a look here for more details about handling error in AJAX requests.

catscoolzhyk
  • 675
  • 10
  • 29
  • About the validation errors, the browser for the email it usually displays a pop-up saying something like you should include @ in the email address This pop-up message is displayed in the basic example of the form but not in the ajax one. I have added a picture to make it clearer.. – IordanouGiannis Nov 04 '17 at 02:41
  • Well, a problem is definitely related to attached ids and classes, and that means CSS or JS. Try to remove your custom ids and classes. If the problem exists, then try to remove optional tags (divs). See, when you use basic Django Form it renders all necessary elements with necessary attributes. You can compare HTML code of Django Form which works as you expect and your code. And try to step by step come to Django Form version to detect the problem. Hope you will find it. – catscoolzhyk Nov 04 '17 at 03:53
  • For example, try to remove from inputs parent (div) its id (email-input-container) and from the top div remove class "row". What about your modal problem? – catscoolzhyk Nov 04 '17 at 03:56