Chained Popups With SimpleDialog2


The jQuery Mobile (jQM) library includes a great popup widget, which can be used for tooltips, context menus, modal forms, lightboxes, etc. Unfortunately, as of version 1.4, the jQM popup still does not support chaining (having one popup on top of another). The API Documentation makes this statement:

The framework does not currently support chaining of popups so it’s not possible to embed a link from one popup to another popup. All links with a data-rel="popup" inside a popup will not do anything at all.

Imagine you have a use case where the user clicks a button to launch a popup form. On that form the user must select at least one checkbox. If the user clicks OK and no checkboxes are selected, the applications should launch a new popup warning the user that no checkboxes are selected. The user clicks OK on this second popup, which returns focus to the first popup where the user can either select a checkbox or click cancel to dismiss the popup.

Because the built-in popup widget does not support this, we can use a third party plugin. Fortunately, J. T. Sage has developed the SimpleDialog2 popup jQuery Mobile plugin, which is highly flexible and customizable. To include this plugin in your page, download the files and then add the SimpleDialog2 CSS file after the jQM CSS file(s), and add the SimpleDialog2 JavaScript file after the jQM JavaScript file. With the plugin in place, let’s build an example for the use case described earlier.

Example

ChainedPopups

The page markup is the standard jQM page with one button that is used to launch the first popup:

<div data-role="page" id="page1">
    <div data-role="header" data-position="fixed">
         <h1>SimpleDialog2 Chained Popup</h1>
    </div>
    <div class="ui-content" role="main">
        <button id="openPopup">Select One or More Item(s)...</button>
    </div>  
</div>

Then the markup for the popup is included outside of the jQM page in the body of the HTML document:

<div id="inlinecontent" style="display:none" > 
  <div  style="padding: 15px;">       
    <fieldset id="cBoxes" data-role="controlgroup" >
      <legend>Favorite Fruit:</legend>
      <input type="checkbox" name="checkbox-v-2a" id="checkbox-v-2a" />
      <label for="checkbox-v-2a">Apple</label>
      <input type="checkbox" name="checkbox-v-2b" id="checkbox-v-2b" />
      <label for="checkbox-v-2b">Banana</label>
      <input type="checkbox" name="checkbox-v-2c" id="checkbox-v-2c" />
      <label for="checkbox-v-2c">Orange</label>
    </fieldset>
    <div class="ui-grid-a">
      <div class="ui-block-a"><button id="dialogSubmit" data-theme="b">OK</button></div>
      <div class="ui-block-b"><button id="dialogCancel" rel='close'>Cancel</button></div>
    </div>
  </div>
</div>

As you can see, the popup includes 3 checkboxes, an OK button, and a Cancel button.  The Cancel button has rel=”close”, which simply tells jQM to close the popup without us adding any code.

To launch the popup, we handle the click event on the one button in the jQM page.

$(document).on('click', '#openPopup', function() {
  $('#inlinecontent').simpledialog2({
    mode: "blank",
    headerText: "Select Item(s)",
    headerClose: false,
    blankContent: true,
    themeDialog: 'a',
    width: '75%',
    zindex: 1000
  });
});

Within the click handler, we call the simpledialog2() method on the popup DIV. This method can take many options, but for this example we only need a few. The blank mode means we are providing all markup, buttons, and button handlers outside of SimpleDialog2, and blankContent must be set to true when using inline markup for the popup. The other important property here, which will become evident when we launch the second popup, is zIndex.

Next we add a handler for the OK button within the popup. When clicked, we check if any checkboxes are checked. If at least one is checked, we simply close the popup, but if none are checked, we launch a second popup on top of the first warning the user that at least one must be checked:

$(document).on('click', '#dialogSubmit', function() {
  var numChecked = $('#cBoxes [type=checkbox]:checked').length;
  if (numChecked > 0){
    $(document).trigger('simpledialog', {'method':'close'});
  } else {
    $('<div>').simpledialog2({
    mode: 'blank',
    headerText: 'Warning',
    headerClose: true,
    transition: 'flip',
    themeDialog: 'b',
    zindex: 2000,
    blankContent : 
      "<div style='padding: 15px;'><p>Please select at least one checkbox first.</p>"+
      // NOTE: the use of rel="close" causes this button to close the dialog.
      "<a rel='close' data-role='button' href='#'>OK</a></div>"
    });        
  }
});

As the second dialog is very simple, instead of inline markup we just create the markup as blankContent directly in the simpledialog2() call. The markup consists of a DIV with the textual prompt and one button with rel=”close”, which will close the popup when clicked. Note the higher zIndex assigned to the second popup.

zIndex is our friend

When SimpleDialog2 creates a modal popup, it creates the popup and also a semi-transparent overlay screen div which covers the background, forcing the user to deal with the popup until it is dismissed. This overlay screen is assigned a zIndex one less than that of the popup. If we leave the zIndex at the default value, both popups will have the default zIndex of 500 and both overlay screens will have a zIndex of 499. So the problem is that while the second popup is active, the user can still click on the original popup because it is above both overlay screens. By assigning a higher zIndex to the second popup, its overlay screen will block the original popup until the second popup is dismissed, thus ensuring modal behavior.

Demo

I have created a demo in jsFiddle that demonstrates this chained popup technique with the SimpleDialog2 plugin:

Chained Popup Demo

In the demo I have added a couple of CSS rules to make the popup look more like the built-in widget, but this is optional.

Buy Me A Coffee :) @ ko-fi.com

Advertisements

4 thoughts on “Chained Popups With SimpleDialog2

  1. Uncaught TypeError: Cannot read property ‘sdIntContent’ of undefined in line no 338 of js file while repeatedly opening and closing the simple dialog

  2. Alvin, perhaps you can post your question on stackoverflow with the jquery-mobile tag and the relevant markup/script. Without details it is difficult to answer your question.

  3. Hi,
    How to prevent simpledialog2 from firing existing callbacks? everytime I open a dialog it fires existing callbacks again.

Drop me a line or two ;)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s