Confirm form submission without loops using jQuery

 Reading time ~2 minutes

Heads up: this article is over a year old. Some information might be out of date, as I don't always update older articles.

Introduction

This post falls in the category “Short tricks that I would teach to my younger self”.

Let’s assume that you want to display a confirmation dialog before submitting an important form. You can leverage the Window.confirm() method, which displays a modal dialog with two buttons, Ok and cancel.

Window.confirm() returns true if the user clicks on the Ok button.

<form onsubmit="return confirm('Do you really want to submit the form?');">

You can also implement this using jQuery:

$(form).on('submit', function() {
    if(confirm('Do you really want to submit the form?')) {
        return true;
    }

    return false;
});

Or more succint:

$(form).on('submit', function() {
    return confirm('Do you really want to submit the form?');
});

This simply works out of the box because the confirm() method blocks the event loop, therefore the form is not submitted until the user clicks one of the two choices.

Now, let’s say that we want to use a nice-looking jQuery plugin, much more appealing to the users, to display the dialog. But when we try to emulate the previous example:

$(form).on('submit', function() {
    dialog.confirm({
        message: 'Do you really want to submit the form?',
        confirm: function() {
            return true;
        },
        cancel: function() {}
    });

    return false;
});

we notice that the form never gets submitted, due to the asynchronous nature of javascript. Before reaching the confirm function, the submit handler returns false, preventing the form to submit. We also cannot do the following:

$(form).on('submit', function() {
    dialog.confirm({
        message: 'Do you really want to submit the form?',
        confirm: function() {
            $(form).submit();
        },
        cancel: function() {}
    });

    return false;
});

otherwise we are stuck in an infinite loop, where the form never gets submitted.

The solution

The solution is pretty straightforward. We should remove the submit handler on the form as soon as the user confirms his choice. For example we can use the off() method, which removes an event handler, previously attached with on():

$(form).on('submit', function() {
    var $this = $(this);    // reference to the current scope

    dialog.confirm({
        message: 'Do you really want to submit the form?',
        confirm: function() {
            $this.off('submit').submit();
        },
        cancel: function() {}
    });

    return false;
});

In this way, the second time the form submission is not intercepted by jQuery.

comments powered by Disqus

Check for foreign key existence in migrations

Laravel provides a couple of handy features to check for the existence of a table or column using the hasTable and hasColumn methods:

<? …