Search code examples
javascriptjquerysubmitonbeforeunloadconfirm

submit during beforeunload, maybe who knows radically another method solution


Reviewed many similar questions on stackoverflow.com (also on other resources), but found no answers. So I simplified and generalized questions. It seems like the obvious solution:

$(document).ready(function() {
    var a = 3;
    var b = 5;

    // no message when pressed submit button
    $('form').submit(function() {
        $(window).off('beforeunload');
    });

    // confirm of the need to save
    $(window).on('beforeunload', function(e) {
        if (a != b)
            if (confirm('You changed data. Save?')) {
                $('form').submit();
                // alert('Your data is saved. (With alert submit() work only in FireFox!?)');
            }
    });
});

But not submit work. If you use the alert(), it works only in FireFox. I would like to correct (possibly without delay) cross-browser solution. Maybe who knows radically another method solution.

P.S. On some originality beforeunload described here in the first part: https://stackoverflow.com/a/6065085/1356425, but this is not the solution obvious functional.


Solution

  • I used synchronous AJAX (JAX) request and run handler for events onUnload or onBeforeUnload once for the respective browser. This solution has a single and almost cross-browser behavior.

    Example (on jsfiddle):

    $(document).ready(function() {
    
        var form = $('form');
        var textareas = $('textarea');
    
        function array_compare(a_0, a_1) {
            if(a_0.length != a_1.length)
                return false;
    
            for(i = 0; i < a_0.length; i++)
                if(a_0[i] != a_1[i])
                    return false;
    
            return true;
        }
    
        var flag = false; // flag to control the execution of the unloadHandler() once
        var a_open = []; // array with data before unload
    
        $('textarea').each(function(index) {
            a_open.push($(this).val());
        });
    
        function unloadHandler() {
            if (flag)
                return;
    
            var a_close = []; // array with data during unload
            $('textarea').each(function(index) {
                a_close.push($(this).val());
            });
    
            if (!array_compare(a_open, a_close)) {
                if (confirm('You changed the data, but not saved them. Save?')) {
                    $.ajax({
                        type: 'POST',
                        url: '/echo/json/',
                        async: false,
                        data: form.serialize()/* {
                            json: JSON.stringify({
                                text: 'My test text.'
                            }),
                            delay: 3
                        } */,
                        success: function(data) {
                            if (data) {
                                console.log(data);
                                alert('All data is saved!');
                            }
                        }
                    });
                }
            }
    
            flag = true;
        }
    
        // For FireFox, Chrome
        $(window).on('beforeunload', function () {
            unloadHandler();
        });
    
        // For Opera, Konqueror
        $(window).unload(function() {
            unloadHandler();
        });
    
        // Without message when pressed submit button
        $('form').submit(function() {
            $(window).off('beforeunload');
            $(window).off('unload');
        });
    
    });