25 min read

In this article by Chip Lambert and Shreerang Patwardhan, author of the book, Mastering jQuery Mobile, we will take our Civic Center application to the next level and in the process of doing so, we will explore different widgets. We will explore the touch events provided by the jQuery Mobile framework further and then take a look at how this framework interacts with third-party plugins. We will be covering the following different widgets and topics in this article:

  • Collapsible widget
  • Listview widget
  • Range slider widget
  • Radio button widget
  • Touch events
  • Third-party plugins
  • HammerJs
  • FastClick
  • Accessibility

(For more resources related to this topic, see here.)

Widgets

We already made use of widgets as part of the Civic Center application. “Which? Where? When did that happen? What did I miss?” Don’t panic as you have missed nothing at all. All the components that we use as part of the jQuery Mobile framework are widgets. The page, buttons, and toolbars are all widgets. So what do we understand about widgets from their usage so far?

One thing is pretty evident, widgets are feature-rich and they have a lot of things that are customizable and that can be tweaked as per the requirements of the design. These customizable things are pretty much the methods and events that these small plugins offer to the developers. So all in all:

Widgets are feature rich, stateful plugins that have a complete lifecycle, along with methods and events.

We will now explore a few widgets as discussed before and we will start off with the collapsible widget. A collapsible widget, more popularly known as the accordion control, is used to display and style a cluster of related content together to be easily accessible to the user. Let’s see this collapsible widget in action.

Pull up the index.html file. We will be adding the collapsible widget to the facilities page. You can jump directly to the content div of the facilities page. We will replace the simple-looking, unordered list and add the collapsible widget in its place. Add the following code in place of the <ul>…<li></li>…</ul> portion:

<div data-role="collapsibleset">
<div data-role="collapsible">
<h3>Banquet Halls</h3>
<p>List of banquet halls will go here</p>
</div>
<div data-role="collapsible">
<h3>Sports Arena</h3>
<p>List of sports arenas will go here</p>
</div>
<div data-role="collapsible">
   <h3>Conference Rooms</h3>
<p>List of conference rooms will come here</p>
</div>
<div data-role="collapsible">
<h3>Ballrooms</h3>
<p>List of ballrooms will come here</p>
</div>
</div>

That was pretty simple. As you must have noticed, we are creating a group of collapsibles defined by div with data-role=”collapsibleset”. Inside this div, we have multiple div elements each with data-role of “collapsible”. These data roles instruct the framework to style div as a collapsible. Let’s break individual collapsibles further. Each collapsible div has to have a heading tag (h1-h6), which acts as the title for that collapsible.

This heading can be followed by any HTML structure that is required as per your application’s design. In our application, we added a paragraph tag with some dummy text for now. We will soon be replacing this text with another widget—listview. Before we proceed to look at how we will be doing this, let’s see what the facilities page is looking like right now:

Mastering jQuery Mobile

Now let’s take a look at another widget that we will include in our project—the listview widget. The listview widget is a very important widget from the mobile website stand point. The listview widget is highly customizable and can play an important role in the navigation system of your web application as well.

In our application, we will include listview within the collapsible div elements that we have just created. Each collapsible will hold the relevant list items which can be linked to a detailed page for each item. Without further discussion, let’s take a look at the following code. We have replaced the contents of the first collapsible list item within the paragraph tag with the code to include the listview widget. We will break up the code and discuss the minute details later:

<div data-role="collapsible">
<h3>Banquet Halls</h3>
<p>
<span>We have 3 huge banquet halls named after 3 most celebrated Chef's from across the world.</span>
<ul data-role="listview" data-inset="true">
<li>
<a href="#">Gordon Ramsay</a>
</li>
<li>
<a href="#">Anthony Bourdain</a>
</li>
<li>
<a href="#">Sanjeev Kapoor</a>
</li>
</ul>
</p>
</div>

That was pretty simple, right? We replaced the dummy text from the paragraph tag with a span that has some details concerning what that collapsible list is about, and then we have an unordered list with data-role=”listview” and some property called data-inset=”true”. We have seen several data-roles before, and this one is no different. This data-role attribute informs the framework to style the unordered list, such as a tappable button, while a data-inset property informs the framework to apply the inset appearance to the list items. Without this property, the list items would stretch from edge to edge on the mobile device. Try setting the data-inset property to false or removing the property altogether. You will see the results for yourself.

Another thing worth noticing in the preceding code is that we have included an anchor tag within the li tags. This anchor tag informs the framework to add a right arrow icon on the extreme right of that list item. Again, this icon is customizable, along with its position and other styling attributes. Right now, our facilities page should appear as seen in the following image:

Mastering jQuery Mobile

We will now add similar listview widgets within the remaining three collapsible items. The content for the next collapsible item titled Sports Arena should be as follows. Once added, this collapsible item, when expanded, should look as seen in the screenshot that follows the code:

<div data-role="collapsible">
   <h3>Sports Arena</h3>
   <p>
       <span>
We have 3 huge sport arenas named after 3 most celebrated sport personalities from across the world.
       </span>        <ul data-role="listview" data-inset="true">            <li>                <a href="#">Sachin Tendulkar</a>            </li>            <li>                <a href="#">Roger Federer</a>            </li>            <li>                <a href="#">Usain Bolt</a>            </li>        </ul>    </p> </div>

Mastering jQuery Mobile

The code for the listview widgets that should be included in the next collapsible item titled Conference Rooms. Once added, this collapsible, item when expanded, should look as seen in the image that follows the code:

<div data-role="collapsible">
   <h3>Conference Rooms</h3>
   <p>
       <span>
           We have 3 huge conference rooms named after 3 largest technology companies.
       </span>
       <ul data-role="listview" data-inset="true">
           <li>
               <a href="#">Google</a>
           </li>
           <li>
               <a href="#">Twitter</a>
           </li>
           <li>
               <a href="#">Facebook</a>
           </li>
       </ul>
   </p>
</div>

Mastering jQuery Mobile

The final collapsible list item – Ballrooms – should hold the following code, to include its share of the listview items:

<div data-role="collapsible">
   <h3>Ballrooms</h3>
   <p>
       <span>
           We have 3 huge ball rooms named after 3 different dance styles from across the world.
       </span>
       <ul data-role="listview" data-inset="true">
           <li>
               <a href="#">Ballet</a>
           </li>
           <li>
               <a href="#">Kathak</a>
           </li>
           <li>
               <a href="#">Paso Doble</a>
           </li>
       </ul>
   </p>
</div>

After adding these listview items, our facilities page should look as seen in the following image:

Mastering jQuery Mobile

The facilities page now looks much better than it did earlier, and we now understand a couple more very important widgets available in jQuery Mobile—the collapsible widget and the listview Widget. We will now explore two form widgets – slider widget and the radio buttons widget.

For this, we will be enhancing our catering page. Let’s build a simple tool that will help the visitors of this site estimate the food expense based on the number of guests and the type of cuisine that they choose. Let’s get started then. First, we will add the required HTML, to include the slider widget and the radio buttons widget. Scroll down to the content div of the catering page, where we have the paragraph tag containing some text about the Civic Center’s catering services.

Add the following code after the paragraph tag:

<form>
   <label style="font-weight: bold; padding: 15px 0px;" for="slider">Number of guests</label>
   <input type="range" name="slider" id="slider" data-highlight="true" min="50" max="1000" value="50">
   <fieldset data-role="controlgroup" id="cuisine-choices">
       <legend style="font-weight: bold; padding: 15px 0px;">Choose your cuisine</legend>
       <input type="radio" name="cuisine-choice" id="cuisine-choice-cont" value="15" checked="checked" />
       <label for="cuisine-choice-cont">Continental</label>
       <input type="radio" name="cuisine-choice" id="cuisine-choice-mex" value="12" />
       <label for="cuisine-choice-mex">Mexican</label>
       <input type="radio" name="cuisine-choice" id="cuisine-choice-ind" value="14" />
       <label for="cuisine-choice-ind">Indian</label>
   </fieldset>
   <p>
       The approximate cost will be: <span style="font-weight: bold;" id="totalCost"></span>
   </p>
</form>

That is not much code, but we are adding and initializing two new form widgets here. Let’s take a look at the code in detail:

<label style="font-weight: bold; padding: 15px 0px;" for="slider">Number of guests</label>
<input type="range" name="slider" id="slider" data-highlight="true" min="50" max="1000" value="50">

We are initializing our first form widget here—the slider widget. The slider widget is an input element of the type range, which accepts a minimum value and maximum value and a default value. We will be using this slider to accept the number of guests. Since the Civic Center can cater to a maximum of 1,000 people, we will set the maximum limit to 1,000 and we expect that we have at least 50 guests, so we set a minimum value of 50. Since the minimum number of guests that we cater for is 50, we set the input’s default value to 50. We also set the data-highlight attribute value to true, which informs the framework that the selected area on the slider should be highlighted.

Next comes the group of radio buttons. The most important attribute to be considered here is the data-role=”controlgroup” set on the fieldset element. Adding this data-role combines the radio buttons into one single group, which helps inform the user that one of the radio buttons is to be selected. This gives a visual indication to the user that one radio button out of the whole lot needs to be selected.

The values assigned to each of the radio inputs here indicate the cost per person for that particular cuisine. This value will help us calculate the final dollar value for the number of selected guests and the type of cuisine.

Whenever you are using the form widgets, make sure you have the form elements in the hierarchy as required by the jQuery Mobile framework. When the elements are in the required hierarchy, the framework can apply the required styles.

At the end of the previous code snippet, we have a paragraph tag where we will populate the approximate cost of catering for the selected number of guests and the type of cuisine selected.

The catering page should now look as seen in the following image. Right now, we only have the HTML widgets in place. When you drag the slider or select different radio buttons, you will only see the UI interactions of these widgets and the UI treatments that the framework applies to these widgets. However, the total cost will not be populated yet. We will need to write some JavaScript logic to determine this value, and we will take a look at this in a minute. Before moving to the JavaScript part, make sure you have all the code that is needed:

Mastering jQuery Mobile

Now let’s take a look at the magic part of the code (read JavaScript) that is going to make our widgets usable for the visitors of this Civic Center web application. Add the following JavaScript code in the script tag at the very end of our index.html file:

$(document).on('pagecontainershow', function(){
   var guests = 50;
   var cost = 35;
   var totalCost;
   $("#slider").on("slidestop", function(event, ui){
       guests = $('#slider').val();
       totalCost = costCal();
       $("#totalCost").text("$" + totalCost);
   });
   $("input:radio[name=cuisine-choice]").on("click", function() {
       cost = $(this).val();
       var totalCost = costCal();
       $("#totalCost").text("$" + totalCost);
   });
   function costCal(){
       return guests * cost;
   }
});

That is a pretty small chunk of code and pretty simple too. We will be looking at a few very important events that are part of the framework and that come in very handy when developing web applications with jQuery Mobile.

One of the most important things that you must have already noticed is that we are not making use of the customary $(document).on(‘ready’, function(){ in Jquery, but something that looks as the following code:

$(document).on('pagecontainershow', function(){

The million dollar question here is “why doesn’t DOM already work in jQuery Mobile?” As part of jQuery, the first thing that we often learn to do is execute our jQuery code as soon as the DOM is ready, and this is identified using the $(document).ready function. In jQuery Mobile, pages are requested and injected into the same DOM as the user navigates from one page to another and so the DOM ready event is as useful as it executes only for the first page. Now we need an event that should execute when every page loads, and $(document).pagecontainershow is the one.

The pagecontainershow element is triggered on the toPage after the transition animation has completed. The pagecontainershow element is triggered on the pagecontainer element and not on the actual page.

In the function, we initialize the guests and the cost variables to 50 and 35 respectively, as the minimum number of guests we can have is 50 and the “Continental” cuisine is selected by default, which has a value of 35. We will be calculating the estimated cost when the user changes the number of guests or selects a different radio button. This brings us to the next part of our code.

We need to get the value of the number of guests as soon as the user stops sliding the slider. jQuery Mobile provides us with the slidestop event for this very purpose. As soon as the user stops sliding, we get the value of the slider and then call the costCal function, which returns a value that is the number of guests multiplied by the cost of the selected cuisine per person. We then display this value in the paragraph at the bottom for the user to get an estimated cost.

We will discuss some more about the touch events that are available as part of the jQuery Mobile framework in the next section.

When the user selects a different radio button, we retrieve the value of the selected radio button, call the costCal function again, and update the value displayed in the paragraph at the bottom of our page.

If you have the code correct and your functions are all working fine, you should see something similar to the following image:

Mastering jQuery Mobile

Input with touch

We will take a look at a couple of touch events, which are tap and taphold. The tap event is triggered after a quick touch; whereas the taphold event is triggered after a sustained, long press touch.

The jQuery Mobile tap event is the gesture equivalent of the standard click event that is triggered on the release of the touch gesture. The following snippet of code should help you incorporate the tap event when you need to use it in your application:

$(".selector").on("tap", function(){
   console.log("tap event is triggered");
});

The jQuery Mobile taphold event triggers after a sustained, complete touch event, which is more commonly known as the long press event. The taphold event fires when the user taps and holds for a minimum of 750 milliseconds. You can also change the default value, but we will come to that in a minute. First, let’s see how the taphold event is used:

$(".selector").on("taphold", function(){
   console.log("taphold event is triggered");
});

Now to change the default value for the long press event, we need to set the value for the following piece of code:

$.event.special.tap.tapholdThreshold

Working with plugins

A number of times, we will come across scenarios where the capabilities of the framework are just not sufficient for all the requirements of your project. In such scenarios, we have to make use of third-party plugins in our project. We will be looking at two very interesting plugins in the course of this article, but before that, you need to understand what jQuery plugins exactly are.

A jQuery plugin is simply a new method that has been used to extend jQuery’s prototype object. When we include the jQuery plugin as part of our code, this new method becomes available for use within your application. When selecting jQuery plugins for your jQuery Mobile web application, make sure that the plugin is optimized for mobile devices and incorporates touch events as well, based on your requirements.

The first plugin that we are going to look at today is called FastClick and is developed by FT Labs. This is an open source plugin and so can be used as part of your application. FastClick is a simple, easy-to-use library designed to eliminate the 300 ms delay between a physical tap and the firing on the click event on mobile browsers.

Wait! What are we talking about? What is this 300 ms delay between tap and click? What exactly are we discussing? Sure. We understand the confusion. Let’s explain this 300 ms delay issue.

The click events have a 300 ms delay on touch devices, which makes web applications feel laggy on a mobile device and doesn’t give users a native-like feel. If you go to a site that isn’t mobile-optimized, it starts zoomed out. You have to then either pinch and zoom or double tap some content so that it becomes readable. The double-tap is a performance killer, because with every tap we have to wait to see whether it might be a double tap—and this wait is 300 ms. Here is how it plays out:

  1. touchstart
  2. touchend
  3. Wait 300ms in case of another tap
  4. click

This pause of 300 ms applies to click events in JavaScript, but also other click-based interactions such as links and form controls. Most mobile web browsers out there have this 300 ms delay on the click events, but now a few modern browsers such as Chrome and FireFox for Android and iOS are removing this 300 ms delay. However, if you are supporting the older Android and iOS versions, with older mobile browsers, you might want to consider including the FastClick plugin in your application, which helps resolve this problem.

Let’s take a look at how we can use this plugin in any web application. First, you need to download the plugin files, or clone their GitHub repository here: https://github.com/ftlabs/fastclick. Once you have done that, include a reference to the plugin’s JavaScript file in your application:

<script type=”application/javascript” src=”path/fastclick.js”></script>

Make sure that the script is loaded prior to instantiating FastClick on any element of the page. FastClick recommends you to instantiate the plugin on the body element itself. We can do this using the following piece of code:

$(function){
   FastClick.attach(document.body);
}

That is it! Your application is now free of the 300 ms click delay issue and will work as smooth as a native application.

We have just provided you with an introduction to the FastClick plugin. There are several more features that this plugin provides. Make sure you visit their website—https://github.com/ftlabs/fastclick—for more details on what the plugin has to offer.

Another important plugin that we will look at is HammerJs. HammerJs, again is an open source library that helps recognize gestures made by touch, mouse, and pointerEvents. Now, you would say that the jQuery Mobile framework already takes care of this, so why do we need a third-party plugin again? True, jQuery Mobile supports a variety of touch events such as tap, tap and hold, and swipe, as well as the regular mouse events, but what if in our application we want to make use of some touch gestures such as pan, pinch, rotate, and so on, which are not supported by jQuery Mobile by default? This is where HammerJs comes into the picture and plays nicely along with jQuery Mobile. Including HammerJS in your web application code is extremely simple and straightforward, like the FastClick plugin. You need to download the plugin files and then add a reference to the plugin JavaScript file:

<script type="application/javascript" src="path/hammer.js"></script>

Once you have included the plugin, you need to create a new instance on the Hammer object and then start using the plugin for all the touch gestures you need to support:

var hammerPan = new Hammer(element_name, options);
hammerPan.on('pan', function(){
   console.log("Inside Pan event");
});

By default, Hammer adds a set of events—tap, double tap, swipe, pan, press, pinch, and rotate. The pinch and rotate recognizers are disabled by default, but can be turned on as and when required.

HammerJS offers a lot of features that you might want to explore. Make sure you visit their website—http://hammerjs.github.io/ to understand the different features the library has to offer and how you can integrate this plugin within your existing or new jQuery Mobile projects.

Accessibility

Most of us today cannot imagine our lives without the Internet and our smartphones. Some will even argue that the Internet is the single largest revolutionary invention of all time that has touched numerous lives across the globe. Now, at the click of a mouse or the touch of your fingertip, the world is now at your disposal, provided you can use the mouse, see the screen, and hear the audio—impairments might make it difficult for people to access the Internet. This makes us wonder about how people with disabilities would use the Internet, their frustration in doing so, and the efforts that must be taken to make websites accessible to all.

Though estimates vary on this, most studies have revealed that about 15% of the world’s population have some kind of disability. Not all of these people would have an issue with accessing the web, but let’s assume 5% of these people would face a problem in accessing the web. This 5% is also a considerable amount of users, which cannot be ignored by businesses on the web, and efforts must be taken in the right direction to make the web accessible to these users with disabilities.

jQuery Mobile framework comes with built-in support for accessibility. jQuery Mobile is built with accessibility and universal access in mind. Any application that is built using jQuery Mobile is accessible via the screen reader as well. When you make use of the different jQuery Mobile widgets in your application, unknowingly you are also adding support for web accessibility into your application. jQuery Mobile framework adds all the necessary aria attributes to the elements in the DOM. Let’s take a look at how the DOM looks for our facilities page:

Mastering jQuery Mobile

Look at the highlighted Events button in the top right corner and its corresponding HTML (also highlighted) in the developer tools. You will notice that there are a few attributes added to the anchor tag that start with aria-. We did not add any of these aria- attributes when we wrote the code for the Events button. jQuery Mobile library takes care of these things for you. The accessibility implementation is an ongoing process and the awesome developers at jQuery Mobile are working towards improving the support every new release.

We spoke about aria- attributes, but what do they really represent? WAI – ARIA stands for Web Accessibility Initiative – Accessible Rich Internet Applications. This was a technical specification published by the World Wide Web Consortium (W3C) and basically specifies how to increase the accessibility of web pages. ARIA specifies the roles, properties, and states of a web page that make it accessible to all users.

Accessibility is extremely vast, hence covering every detail of it is not possible. However, there is excellent material available on the Internet on this topic and we encourage you to read and understand this. Try to implement accessibility into your current or next project even if it is not based on jQuery Mobile. Web accessibility is an extremely important thing that should be considered, especially when you are building web applications that will be consumed by a huge consumer base—on e-commerce websites for example.

Summary

In this article, we made use of some of the available widgets from the jQuery Mobile framework and we built some interactivity into our existing Civic Center application. The widgets that we used included the range slider, the collapsible widget, the listview widget, and the radio button widget. We evaluated and looked at how to use two different third-party plugins—FastClick and HammerJs. We concluded the article by taking a look at the concept of Web Accessibility.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here