Friday, June 29, 2012

Show prompt/Run script when navigating away from a web page.

In the world of web browsers there are some real limitations to responding to user actions.  Specifically when a user is viewing a web page they can navigate away from said page in a few different ways and it can be tricky to deal with and respond to these events.  This is not a new topic but I have found the details online to be somewhat lacking.

A user can leave a page in many different ways.  First of all they can simply click a web page link to another internal or external URL.  This is the simplest action and it triggers a click event which can be responded to with a script and even canceled entirely.  The following for example will show a message when the user click an external link(indicated by the presence of the class "external").

$(document).ready(function() 
  $("a.external").click(function() {
   alert("Leaving to " + $(this).attr("herf"));
 });
});

But how can we react to other types of navigation such as the browser back and forward buttons, page reload, url change, and page close events.  This can be done to a limited extent with the onbeforeunload event though we can't actually see what action the user preformed to leave the page.  There is a further problem here though.  Simply adding a event handler on the onbeforeunload will also run when the user clicks links inside the site witch we may not want.  With that in mind the following code will attach a event handler to the onbeforeunload but will discard it when it detects that a internal or external link was clicked witch can be captured normally.  Additinal link level logic can then be added to the link click events.

$(document).ready(function() {
    // Listen for the unload event and return a warning/run custom code.
    window.onbeforeunload = function (event) {
      if(true) {
        return "You have items in your cart.";
      }
    }
   // If disable event on link clicks that are not hash links, mailto, or javascript calls.
    $("a[href]:not([href^=#],[href^=mailto],[href^=javascript])").click(function(){
      window.onbeforeunload = null;
    });
});

This bit of code will allow for a script to run when the user tries to leave the page and can warn about unsaved changes, etc.  Be warned though that this is only a prompt and furthermore that in most cases this type of alert/warning to users may be irritating.  It should only be used to trigger warnings about unsaved changes, etc.  Also there are some other limits here.  For example you can't redirect the browser to a new url on page exit as the browser is already changing pages.

Monday, June 25, 2012

Cleanly replace links with jQuery UI Dialogs.

This but of code along with a bit of link decoration will automatically open all specified links in dialog popup windows instead of in new browser windows.  It benefit here is that this code is quite small, clean, and automatically applied to all matched elements on the page without having to write custom code or hooks for each link.

First of all make sure that you are including jQuery, jQuery UI and a jQuery UI Stylesheet.

<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<link href="http://code.jquery.com/ui/1.8.21/themes/base/jquery-ui.css" rel="stylesheet"></link>

Next add the following code to a external javascript file that is included on this page or into the page code itself. Not that this needs to be included/executed after the above scripts are included.


ConfigureDialogPopups.js
// make sure the page is fully loaded.
$(document).ready(function() {
  // For each link makred up with the popup attribute change the link to open the contents in a jquery dialog instead.
  $("a[popup]").each(function() {
    $(this).click(function() {
      dest = $(this).attr("popup");
      // Get the page contents with a background ajax query.
      $.get($(this).attr("href"), function(data) {
        // Push the results into a div tag with a custom id to spit out the script and style elements.
        $("<div id='"+dest+"' class='"+dest+"'>" + data + "</div>").each(function() {
          if($(this).is("div")) {
            // Add the div to the page as a popup.
            $(this).dialog({
              close: function() {
              $(this).remove();
              },
              modal: true,
              resizable: false
            });
            // Move the first p to the dialog title. 
            $("#"+dest).dialog( "option", "title", $("#"+dest+">p").first().html() );
            $("#"+dest+">p").first().remove();

            // Update the style of the header.
            $("span.ui-dialog-title").addClass("subhead14");
          } else {
            // Add all other elements to the body directly.
            $(this).appendTo("body");
          }
        });
      });
      // Return false so the link isn't clicked.
      return false;
    }); 
  });
});

The final step is to go through the page and decorate and links you want to open in dialog popups with the popup attribute. This should be added directly to the A link that will trigger the popup and the href will be be the location to retrieve and place into the popup. The value of the popup attribute needs to be assigned a unique id that will be assigned to the resulting dialog object.

 For example the following link can be make up as so to change it from a normal page link to a popup dialog.
<a href="page2.hmtl">View Page 2</a>
<a popup="page2dialog" href="page2.hmtl">View Page 2 (Popup)</a>

Furthermore the dialog can be accessed and manipulated as needed with the following jQuery selector.
$("#page2dialog")