-1

I have a generic AJAX form submit JS class:

$(function() {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    $('.ajax-form').submit(function() {
        var form = $(this);
        var url = form.attr('action');
        var data = form.serialize();

        if (!form.hasClass('valid')) {
            $.ajax({
                url: url,
                type: 'post',
                data: data,
                dataType: 'json',
                success: function(result) {
                    $('.field').removeClass('has-error');
                    form.addClass('valid');
                    form.submit();
                },
                error: function(result) {
                    var errors = result.responseJSON;

                    $('.field').removeClass('has-error');

                    $.each(errors, function(key, value) {
                        var field = $('.field.' + key);
                        field.addClass('has-error').children('.error-message').text(value[0]);
                    });
                }
            });

            return false;
        }
    });
});

This works great for AJAX validation on all my forms. I am now trying to implement this on the default "forgot password" form that is generated with the auth scaffold (resources/views/auth/passwords/email.blade.php).

<form class="ajax-form" method="POST" action="{{ route('password.email') }}">
...
</form>

Although the AJAX validation is working here, the problem I am having is that when the validation passes, it is also performing the "forgot password" functionality. So basically it sends the reset password email twice (once during the AJAX submit and once during normal form submit).

I only want the AJAX submit to perform validation. If validation is successful it should (as it currently does) perform a normal form submit which will send the email.

MAX POWER
  • 5,213
  • 15
  • 89
  • 141

3 Answers3

0

Did you want to keep the Ajax submit but remove the normal form submit? If so then assuming you have a button to submit the form, you can keep the form from submitting in this answer: Want html form submit to do nothing

Community
  • 1
  • 1
Paul Jerome Bordallo
  • 1,362
  • 10
  • 11
  • No, I want the AJAX submit to do validation only. The normal submit will only occur if validation was successful. – MAX POWER Apr 26 '17 at 20:19
0

If I understand the issue correctly you need to prevent Form Default behavior and validate and if everything is validated, resume the default form behavior to submit the data.

$('.ajax-form').submit(function(evt) {
    evt.preventDefault(); // This would prevent default form submission functionality
    var form = $(this);
    var url = form.attr('action');
    var data = form.serialize();

    if (!form.hasClass('valid')) {
        $.ajax({
            url: url,
            type: 'post',
            data: data,
            dataType: 'json',
            success: function(result) {
                $('.field').removeClass('has-error');
                form.addClass('valid');                
                form.unbind('submit').submit(); // Submit the Form If everything is validated
            },
            error: function(result) {
                var errors = result.responseJSON;

                $('.field').removeClass('has-error');

                $.each(errors, function(key, value) {
                    var field = $('.field.' + key);
                    field.addClass('has-error').children('.error-message').text(value[0]);
                });
            }
        });

        return false;
    }
});
linktoahref
  • 7,812
  • 3
  • 29
  • 51
0

Here is the correct way to resolve this. In Auth\ForgotPasswordController override the sendResetLinkEmail function as follows:

/**
 * Send a reset link to the given user.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function sendResetLinkEmail(Request $request)
{
    $this->validate($request, ['email' => 'required|email']);

    // Inserted this piece of code which checks for AJAX request
    if ($request->ajax()) {
        return response()->json();
    }

    // We will send the password reset link to this user. Once we have attempted
    // to send the link, we will examine the response then see the message we
    // need to show to the user. Finally, we'll send out a proper response.
    $response = $this->broker()->sendResetLink(
        $request->only('email')
    );

    return $response == Password::RESET_LINK_SENT
                ? $this->sendResetLinkResponse($response)
                : $this->sendResetLinkFailedResponse($request, $response);
}

By doing if ($request->ajax()) we allow it to check for ajax request and only return a json response. Then in the subsequent request when it does a regular form post it will perform the forgot password functionality.

MAX POWER
  • 5,213
  • 15
  • 89
  • 141