Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ElijahPaul's avatar

Validate form served via AJAX call using jQuery validation

can't seem to figure this one out.

I've configured my login form to submit via AJAX. My LoginController.php checks to see if the user has 2FA enabled, and if so pulls the form from the @section('content) section of the 2FA blade template and loads it (via AJAX) into the @section('content') section of the existing layout:

layouts/auth.blade.php

<html>
    <head>
        ...
    </head>
    <body>
        <div id="content">
            @yield('content')
        </div>
        <script src="{{ secure_asset('js/jquery.min.js') }}"></script>
        <script src="{{ secure_asset('js/jquery.validate.min.js') }}"></script>
        <script src="{{ secure_asset('js/login.js') }}"></script>
    </body>
</html>

login.blade.php

@extends('layouts.auth')

@section('content')
    <form id="loginForm" class="js-validation">
        <div class="form-group">
            <input id="email" name="email" type="email">
        </div>
        <div class="form-group">
            <input id="password" name="password" type="password">
        </div>
        <button id="login-submit-btn" class="btn"></button>
    </form>
@endsection

2fa.blade.php

@extends('layouts.auth')

@section('content')
    <form id="2faLoginForm" class="js-validation">
        <div class="form-group">
            <input id="passcode" type="tel" name="passcode">
        </div>
        <button id="submit-btn" class="btn"></button>
    </form>
@endsection

login.js

....
// login form jQuery
$(document).on('click', '#login-submit-btn', function (e) {
    e.preventDefault();
    if ($('.js-validation').valid()) {
        var formData;
        formData = $('#loginForm').serialize();
        var validator = $(".js-validation").validate();
        $.ajax({
            url: '/login',
            type: 'POST',
            data: formData,
            dataType: 'JSON',
            success: function(data) {
                console.log(data);
                if (data.intended) {
                    window.location.href = data.intended;
                } else {
                    $("#content").html(data.content);
                }
            },
            error: function(data){
                var errors = $.parseJSON(data.responseText).errors;
                if (errors.email) {
                    validator.showErrors({
                        "email": errors.email[0]
                    });
                }
                if (errors.password) {
                    validator.showErrors({
                        "password": errors.password[0]
                    });
                };
            }
        });
    }
})

// 2fa form jQuery
$(document).on('click', '#submit-btn', function (e) {
    e.preventDefault();
    if ($('.js-validation').valid()) {
        var validator = $(".js-validation").validate();
            $.ajax({
                url: "/login/2fa",
                type: 'POST',
                data: {
                    "_token": $('input[name="_token"]').val(),
                    "passcode": $('#passcode').val(),
                },
                error: function (data) {
                    var error;
                    var message;
                    if (data.responseJSON.errors) {
                        error = data.responseJSON.errors.passcode[0];
                        validator.showErrors({
                            "passcode": error
                        });
                    }
                },
                success: function (data) {
                    window.location.href = data.intended;
                }
            });
    }
});

LoginController.php

private function authenticated(Request $request, Authenticatable $user)
    {
        if ($request->ajax()) {
            if (!empty($user->google2faSecurity->google2fa_enable)) {
                Auth::logout();
                $request->session()->put('2fa:user:id', $user->id);
                $twoFactorLogin = view('login.2fa')->renderSections();
                return response()->json([
                    'content' => $twoFactorLogin['content'],
                ]);
            }
            return response()->json([
                'intended' => $this->redirectPath(),
            ]);
        }
    }

While jQuery Validate works with the initial loaded login.blade.php form, it doesn't with the AJAX served 2fa.blade.php form added to the DOM that replaces it. So no client side validation is performed on the newly displayed 2fa form.

How can I get jQuery validation to work on the AJAX served 2fa form?

After a fair bit of Googling (and tinkering) I've come up with nothing that works. :(

Thanks.

P.S. If I'm going about this all wrong or there are mistakes please do let me know.

0 likes
2 replies
Talinon's avatar
Talinon
Best Answer
Level 51

I think what is going on is when you replace the login form within the DOM, the original elements that have event listeners are removed. When you replace it with the 2fa content, JQuery doesn't have event listeners attached to the freshly added content.

Perhaps you can solve this by wrapping the 2fa form query javascript into a function, and then call it in your AJAX success function.

Something like:

// 2fa form jQuery
function load2fa(
    $(document).on('click', '#submit-btn', function (e) {
        ....
        ....

    });
);
          success: function(data) {
                console.log(data);
                if (data.intended) {
                    window.location.href = data.intended;
                } else {
                    $("#content").html(data.content);
            load2fa();  // load event listeners for the new content
                }
            },
1 like
ElijahPaul's avatar

I had to also re-initialise my jQuery validation plugin, but this worked great.

Thank you.

Please or to participate in this conversation.