0

I have a login form for which I want the client to send AJAX POST request as below with error handling. In case of validation/authentication errors, I don't the page to be reloaded or refreshed to the url corresponding to POST request Handler(/users/login/) with the JSON string received from login view's response. I tried using event.preventDefault() as suggested by many answer on SO but could not make it work. Any clue as to what is going wrong here? I don't think this to be a Django issue. I know that the onsubmit is triggerred because the window redirects to the POST handler URL /users/login/ with the expected JSON string response - {"error": ["Entered mobile number is not registered"]}

JQuery code

$("#loginform").on('submit', function(event) {
            event.preventDefault();
            alert("Was preventDefault() called: " + event.isDefaultPrevented());
            console.log("form submitted!");
            var url = "/users/login/";

            $.ajax({
                type: "POST",
                url:url,
                data: $("#loginform").serialize(),
                success: function(data)
                {
                    console.log(data);
                    var result = JSON.stringify(data);
                    if(result.indexOf('errors')!=-1 ){
                        console.log(data);
                        if(data.errors[0] == "Mobile number and password don't match")
                        {
                            $('.login-error').text("Mobile number and password don't match");
                        }

                        else if(data.errors[0] == "Entered mobile number is not registered")
                        {
                            $('.login-error').text("Entered mobile number is not registered");
                        }

                    }

                    else
                    {
                        window.open("/users/profile/");
                    }

                    //var result = JSON.stringify(data);
                    // console.log(result);

                }
            })

    });

View Handler

def login(request):
    if request.method == 'POST':
        mobile_number = request.POST.get('mobile_number', '')
        password = request.POST.get('password', '')

        data = {}

        user_queryset = User.objects.filter(mobile_number=mobile_number)

        if len(user_queryset) == 0:
            data['error'] = []
            data['error'].append("Entered mobile number is not registered")
            # return JsonResponse(data)

        elif len(user_queryset) == 1:
            email = user_queryset[0].email

            user = auth.authenticate(email=email, password=password)

            if user is not None:
                auth.login(request, user)

            else:
                data['error'] = []
                data['error'].append("Mobile number and password don't match")

        return JsonResponse(data)

HTML code

<div class="container-fluid bg-primary" id="login">
        <div class="row">
            <div class="col-lg-3 text-center">
            </div>
            <div class="col-lg-6 text-center">
            <h1>&nbsp;</h1><h3>&nbsp;</h3>
                <h2 class="section-heading">Login to your profile</h2>
                <hr>
            </div>
            <div class="col-lg-3 text-center">
            </div>
            <h2>&nbsp;</h2>
            <h2>&nbsp;</h2>
            <h2>&nbsp;</h2>
        </div>
        <div class="col-md-4 col-md-offset-4 ">
            <form id='loginform' action='/users/login/' method='post' accept-charset='UTF-8'>
            {% csrf_token %}
                <fieldset >
                    <div class="form-group">
                        <input type="text" name="mobile_number" id="mobile_number" tabindex="1" class="form-control" placeholder="Mobile Number" value="">
                    </div>
                    <div class="form-group">
                        <input type="password" name="password" id="password" tabindex="2" class="form-control" placeholder="Enter Password">
                        </div>
                </fieldset>
                <button type="submit" class="btn btn-primary btn-xl btn-block">LOG IN</button><br><br>
                <span class="login-error"></span>
                <h1>&nbsp;</h1><h1>&nbsp;</h1>
            </form>
        </div>
    </div>
anon
  • 1,069
  • 1
  • 12
  • 17
  • Did you try to debug JS/Python and see if the ajax is actually triggered/it goes into your submit handler? Also try to add return false; at the end of the submit handler in JS. – Bogdan Goie Jul 07 '15 at 08:39
  • You can also have a look at this page, which show ajax submit and form validation: http://jsn-techtips.blogspot.nl/2014/04/django-show-form-validation-error-with.html – het.oosten Jul 07 '15 at 08:41
  • @BogdiG : Yes, I know it is triggerred because the window redirects to the POST handler URL `/users/login/` with the expected JSON string response - `{"error": ["Entered mobile number is not registered"]}`. I should mention this in the question. – anon Jul 07 '15 at 08:59
  • @anon Try return false; at the end of the .submit handler and remove event.preventDefault(). return false; will actually call automatically preventDefault() and stopPropagation() under the hood. or just add event.stopPropagation() as well in adition to event.preventDefault() – Bogdan Goie Jul 07 '15 at 09:11
  • @BogdiG : I tried `return false` but it did not work. – anon Jul 07 '15 at 10:34

2 Answers2

0

In addition to event.preventDefault();, it might be a good idea to also call event.stopPropagation() in this case.

Boris Chervenkov
  • 630
  • 1
  • 12
  • 12
  • If the handler function has an error, the browser will stop the execution and proceed with the normal event handling, as you're describing. if you're using IE, the event object might not have the `preventDefault()` method. In this case you can refer to this answer: http://stackoverflow.com/a/1000606/74632 – Boris Chervenkov Jul 07 '15 at 10:54
0

Use : 'event.preventDefault()' or 'return false' after the ajax call.

Sunny
  • 73
  • 1
  • 1
  • 9
  • I have already used event.preventDefault() as you can see in the second line of the JQuery code section – anon Jul 07 '15 at 10:08