jQuery UI Dialog Demo/Example for WordPress

October 2017

Abstract: jQuery UI has been included with WordPress since version 3.3. However, not only is the necessary CSS not included (the CSS is required for some functionality), documentation within the WordPress documentationis also rather sparse. Code is provided to enqueue both jQuery UI and the missing CSS correctly, as well as providing a method for making jQuery UI Dialog responsive.

jQuery began in 2005 as a fairly succinct set of thoughts from developer John Resig. The first stable release occured within a year, and by fall of 2007 jQuery UI was released. After a few more years of intense development, and the founding of the jQuery Foundation (now known as the JS Foundation), jQuery 1.7.1 and jQuery UI 1.8.16 were included with the release of WordPress 3.3 in December of 2011.

Open-source software is excellent. Apache web servers, Linux, PHP, mySQL databases … These are what the internet is built on. MacOS in various forms originated as FreeBSD, a version of the Linux operating system. And WordPress itself, also open-source, powers more blogs and web sites than anything else.

But there’s a problem. Open-source developers write documentation for each other. It’s not often that users can really figure out what’s going on, especially beginning users. And when they try to get into the guts of some of it to do their own thing, they end up completely lost.

When it comes to documentation, jQuery UI is different. Their documentation pages are filled with rock-solid examples and demos. For eample, this page presents the Dialog functionality as a modal popup dialog that the underlying page then responds to. (Modal means the Dialog is on top of the page that called it.) Clicking on the “view source” link on that page opens the code for the page itself.

The question though is, how does one use this Dialog within a WordPress site? And if you’re building your first plugin for WordPress, how do you ue it with the Admin pages?

Searching for this info within the WordPress docs lands you on this page, which is the technical version of how to use wp_enqueue_script. The list of jQuery UI handles mentioned on that page has a link for jQuery UI Dialog … which goes right back to the jQuery UI demo page, which doesn’t address WordPress at all.

Before we go any further, if you’re only looking to use jQuery UI on your WordPress site for visitors, just install the jQuery UI Widgets plugin from David Gwyer. Follow his instructions and you’ll be set.

If, however, you’re writing a plugin and need to use jQuery UI, the following is for the modal Dialog portion of it. You can then modify this as needed to use any other aspects of jQuery UI.

Enqueue jQuery, jQuery UI, and jQuery’s CSS

The jQuery UI modal Dialog demo is intended to describe how to use the functionality on pages outside the WordPress environment. Within WordPress though, it’s simple to get that same functionality without retrieving the Javascript from outside sources. You’ll need to call what you need while you’re enqueuing the rest of the functionality for your Admin pages. This function includes jQuery and jQuery Core from within WordPress, along with the jQuery UI portions we need for our plugin. Other functions are commented out.

WordPress has yet to include the jQuery UI CSS. This CSS actually provides some functionality for jQuery UI, and is required for proper operation. What’s interesting though is that their CSS provides themes. You can link to their online theme CSS files (we’re using the Base theme), or build your own using their ThemeRoller and include it with your plugin. You do need to do one or the other though.

Note that this code references a local file, js/jquery-ui-custom.js, We’ll get to that next.

  /* include both jQueryUI and jQuery, along with jQueryUI CSS */
function my_jquery_ui_enqueue() {
  wp_enqueue_script( 'jquery' );
  wp_enqueue_script( 'jquery-ui-core' );
  wp_enqueue_script( 'jquery-ui-widget' );
  // wp_enqueue_script( 'jquery-ui-mouse' );
  wp_enqueue_script( 'jquery-ui-accordion' );
  // wp_enqueue_script( 'jquery-ui-autocomplete' );
  // wp_enqueue_script( 'jquery-ui-slider' );
  wp_enqueue_script( 'jquery-ui-tabs' );
  // wp_enqueue_script( 'jquery-ui-sortable' );
  // wp_enqueue_script( 'jquery-ui-draggable' );
  // wp_enqueue_script( 'jquery-ui-droppable' );
  // wp_enqueue_script( 'jquery-ui-datepicker' );
  // wp_enqueue_script( 'jquery-ui-resize' );
  wp_enqueue_script( 'jquery-ui-dialog' );
  wp_enqueue_script( 'jquery-ui-button' );
  // Get our jQueryUI script
  wp_register_script( 'jquery-ui-custom', plugins_url("js/jquery-ui-custom.js",__FILE__), false, '1.0.0' );
  wp_enqueue_script( 'jquery-ui-custom' );
  // WP doesn't include jQueryUI CSS, so go get it
  $jqueryuicssURL = 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css';
  wp_register_style('jquery-style', $jqueryuicssURL);
  wp_enqueue_style( 'jquery-style' );
}

add_action( 'admin_enqueue_scripts', array($this, 'my_jquery_ui_enqueue') );

js/jquery-ui-custom.js File

Next, we’ll pull the Javascript that does the custom work out of the jQuery UI Dialog source and save it as jquery-ui-custom.js in a subfolder we’ll name “js” in our plugin files. This is a simple copy-and-paste of the code between the script tags within their source code. This is part of the code you’ll need to modify for your own purposes.

Note that this includes code stolen from Nate Finch on making the Dialog responsive for use on tablets and smart phones. I could have figured this out, but he already did.

jQuery(document).ready(function($) {
    var dialog, form,
  var screenWidth, screenHeight, dialogWidth, dialogHeight, isDesktop;

    screenWidth = window.screen.width;
    screenHeight = window.screen.height;

  // from https://n8finch.com/make-jquery-ui-dialog-popup-responsive-javascript/
    if ( screenWidth < 500 ) {
        dialogWidth = screenWidth * .95;
        dialogHeight = screenHeight * .95;
    } else {
        //dialogWidth = 500;
        //dialogHeight = 500;		
        dialogWidth = 350;
        dialogHeight = 400;
        isDesktop = true;
    }
 
      // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
      emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
      name = $( "#name" ),
      email = $( "#email" ),
      password = $( "#password" ),
      allFields = $( [] ).add( name ).add( email ).add( password ),
      tips = $( ".validateTips" );
 
    function updateTips( t ) {
      tips
        .text( t )
        .addClass( "ui-state-highlight" );
      setTimeout(function() {
        tips.removeClass( "ui-state-highlight", 1500 );
      }, 500 );
    }
 
    function checkLength( o, n, min, max ) {
      if ( o.val().length > max || o.val().length < min ) {
        o.addClass( "ui-state-error" );
        updateTips( "Length of " + n + " must be between " +
          min + " and " + max + "." );
        return false;
      } else {
        return true;
      }
    }
 
    function checkRegexp( o, regexp, n ) {
      if ( !( regexp.test( o.val() ) ) ) {
        o.addClass( "ui-state-error" );
        updateTips( n );
        return false;
      } else {
        return true;
      }
    }
 
    function addUser() {
      var valid = true;
      allFields.removeClass( "ui-state-error" );
 
      valid = valid && checkLength( name, "username", 3, 16 );
      valid = valid && checkLength( email, "email", 6, 80 );
      valid = valid && checkLength( password, "password", 5, 16 );
 
      valid = valid && checkRegexp( name, /^[a-z]([0-9a-z_\s])+$/i, "Username may consist of a-z, 0-9, underscores, spaces and must begin with a letter." );
      valid = valid && checkRegexp( email, emailRegex, "eg. ui@jquery.com" );
      valid = valid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" );
 
      if ( valid ) {
        $( "#users tbody" ).append( "<tr>" +
          "<td>" + name.val() + "</td>" +
          "<td>" + email.val() + "</td>" +
          "<td>" + password.val() + "</td>" +
        "</tr>" );
        dialog.dialog( "close" );
      }
      return valid;
    }
 
    dialog = $( "#dialog-form" ).dialog({
      autoOpen: false,
      height: dialogHeight,
      width: dialogWidth,
      modal: true,
      buttons: {
        "Create an account": addUser,
        Cancel: function() {
          dialog.dialog( "close" );
        }
      },
      close: function() {
        form[ 0 ].reset();
        allFields.removeClass( "ui-state-error" );
      }
    });
 
    form = dialog.find( "form" ).on( "submit", function( event ) {
      event.preventDefault();
      addUser();
    });
 
    $( "#create-user" ).button().on( "click", function() {
      dialog.dialog( "open" );
    });
  } );

HTML Page

Once the foundation pieces are in places, it’s a matter of dropping the HTML code from the demo page into your Settings page in the Admin portion of the plugin you’re building. You could also include this in a callback function if you’re using the WordPress API to build your Settings pages. This is the other section of code you’ll need to modify for your own purposes. This only recreates the jQuery UI Dialog modal demo, nothing more. The rest is up to you.

$html .= '<div id="dialog-form" title="Create new user">';
  $html .= '<p class="validateTips">All form fields are required.</p>';
 
  $html .= '<form>';
    $html .= '<fieldset>';
      $html .= '<label for="name">Name</label>';
      $html .= '<input type="text" name="name" id="name" value="Jane Smith" class="text ui-widget-content ui-corner-all">';
      $html .= '<label for="email">Email</label>';
      $html .= '<input type="text" name="email" id="email" value="jane@smith.com" class="text ui-widget-content ui-corner-all">';
      $html .= '<label for="password">Password</label>';
      $html .= '<input type="password" name="password" id="password" value="xxxxxxx" class="text ui-widget-content ui-corner-all">';
     
      $html .= '<!-- Allow form submission with keyboard without duplicating the dialog button -->';
      $html .= '<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">';
    $html .= '</fieldset>';
  $html .= '</form>';
$html .= '</div>';
 
$html .= '<div id="users-contain" class="ui-widget">';
  $html .= '<h1>Existing Users:</h1>';
  $html .= '<table id="users" class="ui-widget ui-widget-content">';
    $html .= '<thead>';
      $html .= '<tr class="ui-widget-header ">';
        $html .= '<th>Name</th>';
        $html .= '<th>Email</th>';
        $html .= '<th>Password</th>';
      $html .= '</tr>';
    $html .= '</thead>';
    $html .= '<tbody>';
      $html .= '<tr>';
        $html .= '<td>John Doe</td>';
        $html .= '<td>john.doe@example.com</td>';
        $html .= '<td>johndoe1</td>';
      $html .= '</tr>';
    $html .= '</tbody>';
  $html .= '</table>';
$html .= '</div>';
$html .= '<button id="create-user">Create new user</button>';