Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26671

JQuery for changes in a form

I'm using JQuery to handle changes in unsaved form data, user enters the page, edits the data, tries to leave the page without saving and it sort of works since I'm getting the dialog when I've changed the form: enter image description here

Above says: "Do you want to leave this page? You have unsaved data, do you want to conitnue without saving your changes?"

It works well and is a lot of functionality in very little code:

<script>
    $(function() {
        // Set the unload message whenever any input element get changed.
        $(':input').on('change', function() {
            setConfirmUnload(true);
        });

        // Turn off the unload message whenever a form get submitted properly.
        $('form').on('submit', function() {
            setConfirmUnload(false);
        });
    });

    function setConfirmUnload(on) {
        var message = "Vill du gå vidare utan att spara eventuella ändringar?";
        window.onbeforeunload = (on) ? function() { return message; } : null;
    }
</script>

Compared to what I'm using, the above looks like something much better to work on than my current combination of Java + JS that uses a hidden form variables for whether the form data was changed and then tests on both Java and JS to enable the warning which is according to my specification:

enter image description here

The above is the way it should look like. Thing is, I want the user to be able to change the form and submit it to the page without getting the warning and I'd also like to exclude the searchbox "fastseach" from the warning so is it possible to exclude components? And how do I change the display of the dialog to my own? My own dialog is drawn like this:

    // is this necessary?
    function doAsk(title, msg, action, command, actionNo, commandNo, search) {  
        document.getElementById("fastsearch").value = search;
        document.actionForm.saveStatus.value = ''
        var funcYes = 'doYes()';
        var funcNo = 'hideDialog()';
        if (title == 'Fel') {
            var s = "<div style=\"position:absolute; z-index:1000001; left:15%; top:75%; font-size: 70% \"><input id=\"dialogaterga\" style=\"font-family:calibri; width:70px; float:right; margin-right:35px;\" type=button onclick=\"javascript:"
                    + funcNo + "\" value=\"Återgå\" /></div>";
            showDialog(title, msg + s);
        } else if (title == 'Varning') {
                var v = "<div style=\"position:absolute; z-index:1000001; left:15%; top:75%\"><input  style=\"font-family:calibri; width:70px\" type=button onclick=\"javascript:"
                        + funcNo
                        + "\" value=\"Nej\" /></div><div style=\"position:absolute; left:70%; top:75%\"><input  id=\"dialogwarnyes\" style=\"font-family:calibri; width:70px\" type=button onclick=\"javascript:doSubmit('"
                        + action + "','" + command + "'); \" value=\"Ja\" /></div>";
            showDialog(title, msg + v);
        } else if (title == 'Information') {
            var i = "<div style=\"position:absolute; z-index:1000001; left:70%; top:75%\"><input type=button class=\"dialogbuttonlink\" id=\"dialogstang\" onclick=\"javascript:hideDialog()\" value=\"St&auml;ng\" /></div>";
            showDialog(title, msg + i, true);
        } else if (title == 'Fel2') {
            title = 'Fel';
            var s2 = "<div style=\"position:absolute; z-index:1000001; left:15%; top:75%; font-size: 70% \"><input id=\"dialogaterga\" style=\"font-family:calibri; width:70px; float:right; margin-right:35px;\" type=button onclick=\"javascript:"
                    + funcNo + "\" value=\"OK\" /></div>";
            showDialog(title, msg + s2);
        }
        initFocus();    
    }
function showDialog(title, message, autohide) {
    //alert("showdialog");
    var type = 'prompt';
    var dialog;
    var dialogheader;
    var dialogclose;
    var dialogtitle;
    var dialogcontent;
    var dialogmask;
    var link1
    var link2

    if (!document.getElementById('dialog')) {
        dialog = document.createElement('div');
        dialog.id = 'dialog';
        link2 = document.createElement('a');
        link2.id = 'modalFocusLink';
        link2.setAttribute('onclick', 'return false');
        link2.setAttribute('onblur', 'redirectFocus');
        link2.setAttribute('href', '#');
        dialog.appendChild(link2);
        dialogheader = document.createElement('div');
        dialogheader.id = 'dialog-header';
        dialogtitle = document.createElement('div');
        dialogtitle.id = 'dialog-title';
        dialogclose = document.createElement('div');
        dialogclose.id = 'dialog-close'
        dialogcontent = document.createElement('div');
        dialogcontent.id = 'dialog-content';
        dialogmask = document.createElement('div');
        dialogmask.id = 'dialog-mask';
        document.body.appendChild(dialogmask);
        document.body.appendChild(dialog);
        dialog.appendChild(dialogheader);
        dialogheader.appendChild(dialogtitle);
        dialogheader.appendChild(dialogclose);
        dialog.appendChild(dialogcontent);
        dialogclose.setAttribute('onclick', 'hideDialog()');
        dialogclose.onclick = hideDialog;
        link1 = document.createElement('a');
        link1.id = 'modalBlurLink';
        link1.setAttribute('onclick', 'return false');
        link1.setAttribute('onfocus', 'redirectFocus');
        link1.setAttribute('href', '#');

        dialog.appendChild(link1);

    } else {
        dialog = document.getElementById('dialog');
        dialogheader = document.getElementById('dialog-header');
        dialogtitle = document.getElementById('dialog-title');
        dialogclose = document.getElementById('dialog-close');
        dialogcontent = document.getElementById('dialog-content');
        dialogmask = document.getElementById('dialog-mask');
        dialogmask.style.visibility = "visible";
        dialog.style.visibility = "visible";
    }
    dialog.style.opacity = .00;
    dialog.style.filter = 'alpha(opacity=0)';
    dialog.alpha = 0;
    var width = pageWidth();
    var height = pageHeight();
    var left = leftPosition();
    var top = topPosition();
    var dialogwidth = dialog.offsetWidth;
    var dialogheight = dialog.offsetHeight;
    var topposition = 33;// top + (height / 3) - (dialogheight / 2);
    var leftposition = width - dialogwidth - 30; // left + (width / 2) -
                                                    // (dialogwidth / 2);
    dialog.style.top = topposition + "px";
    dialog.style.left = leftposition + "px";
    dialogheader.className = type + "header";
    dialogtitle.innerHTML = title;
    dialogcontent.className = type;
    dialogcontent.innerHTML = message;
    var content = document.getElementById(WRAPPER);
    dialogmask.style.height = content.offsetHeight + 'px';

    if (title == 'Information') {
        dialog.alpha = 100;
        dialog.style.opacity = (1.0);
        dialog.style.filter = 'alpha(opacity=' + 100 + ')';
        dialog.style.visibility = "visible";
        dialogmask.style.visibility = "hidden";
        var fodi = document.getElementById("dialogstang");
        fodi.focus();
    } else {
        if (title == 'Fel') {
            var fo = document.getElementById("dialogaterga");
            fo.focus();
        } else if (title == 'Varning') {
            var vafo = document.getElementById("dialogwarnyes");
            vafo.focus();
        }
        dialog.timer = setInterval("fadeDialog(1)", TIMER);

        if (autohide) {
            dialogclose.style.visibility = "hidden";
            // window.setTimeout("hideDialog()", (autohide * 1000));
        } else {
            dialogclose.style.visibility = "visible";
        }
        if (title == 'invisible')
            dialog.style.visibility = "hidden";
    }

}

The component I'd like to exclude could be the "update" button since pressing "update" should not activate the warning, only leaving the page. Can you help me?

Upvotes: 0

Views: 330

Answers (1)

manzoid
manzoid

Reputation: 1225

There is no way to change the look of that browse-away warning dialog. It is a native facility provided by the browser. In fact, on Firefox as of version 4 you can't even customize the message by supplying your own string as the return value, rather it always says something like:

"This page is asking you to confirm that you want to leave - data you have entered may not be saved."

As for excluding various components on your page from the browse-away warning, isn't that simply a matter of extending the technique that you already appear to be using, where you disable the onbeforeunload event in your user event handlers? For example, when clicking the update button or the search button, you can first make sure to "un-hook" the onbeforeunload event by assigning it to null or a no-op function.

By the way, looking at all that raw DOM construction you are doing (all the appendChild() calls and setAttribute() calls, etc), I suggest you take a look at some client-side template frameworks. Here's a decent-looking list of alternatives. Also Angular.js from Google is pretty cool too, although not just a templating system per se.

Upvotes: 1

Related Questions