17
Jan '19

In my latest projects I’ve found myself increasingly putting input forms within bootstrap modals. It cleanly separates active and static elements, it maintains a tidy UI, and it reduces page load time to name but a few benefits.

A key drawback however is that it’s very easy to click away from a modal by accident and lose your work. To deal with this I created a quick script that listens for changes in any input elements within a modal, and catches the modal close event accordingly:

var is_clicked = false;
var dirty = false;

$().ready(function() {

    /*
     * Keeps the change listener inactive until at least one element has been clicked on 
     */
    $('.modal').on('click', 'input, select, textarea', function(e) {
        is_clicked = true;
    });

    /*
     * input element change listener
     */
    $('.modal').on('change', 'input, select, textarea', function(e) {

        if(is_clicked) {
            dirty = true;
        }
    });

    /*
     * Handles the modal hide event
     */
    $('.modal').on('hide.bs.modal', function(e) {
        //Prevent date picker submits from trying to close parent modals
        if($(e.target).hasClass('date-box'))
            return false;

        if(dirty) {
            if(confirm('You have unsaved changes. Are you sure you wish to close this dialog?')) {
                is_clicked = false;
                dirty = false;
                return true;
            }

            return false;
        }

        return true;
    });
});

In reality I tend to use pnotify for my confirmation dialogs, but to keep this example as simple as possible I put in the native javascript call.