This begins a new column series, providing tips and tutorials to guide readers in the use of code and script to create effective learning applications. This month’s column is aimed at an intermediate level, and it will teach you how to add mobile gestures to your learning content. But even if you are new to this type of work, it will help you gain a basic understanding of the concepts, terminology, and scripting involved in creating learning interactions.

I was teaching a class for eLearning designers and developers a few weeks ago, and the topic of responsive design came up. Responsive design is a frequent theme in my courses, and the discussion we had here was similar to most. Then, one of my students mentioned “clicking” within the project. I cringed a bit.

It was an innocent mistake, and a common misconception. I pointed out that people interact with mobile devices in a completely different manner than traditional point-and-click learning interactions.

“There is no mouse, and therefore no mouse-over events and no clicking,” I explained. “There are gestures, however. People want to interact with learning content the same way they might interact with other applications on their phone or tablet.”

In this tutorial, we’re going to use the Hammer.JS library to add a few mobile gestures to some learning content.

We’re going to create a short app that allows users to learn some programming terminology.

Step 1: Enter the initial code

Using any text editor you prefer, enter the initial code below. This is more or less the base code for our application.

<!DOCTYPE html>
<html>
<head>
    <title>Page Metaphor</title>
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
    <style>
        #footer
        {
            position: fixed;
            bottom: 0px;
            width: 100%;
        }
    </style>
</head>
<body>
<div data-role="page">
  <div data-role="header">
    <h1>Vocab for Coders</h1>
  </div>  <!-- header -->
  <div data-role="main" id="main" class="ui-content">
        
  </div>  <!-- main -->
  <div data-role="footer" id="footer">
    <h1>Learning Solutions</h1>
  </div>  <!-- footer -->
</div>   <!-- page -->
</body>    
</html>

Let’s take a closer look at the code to make sure you understand what’s going on. First, we’ll prepare the screen of the device so that it reacts more like a mobile app, and less like a web browser:

<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

This meta tag essentially sets the screen to 100 percent magnification and disallows the pinch gesture.

The next lines allow us to connect to the various libraries and stylesheets we’ll use for the project.

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>

In this project we’ll be using jQuery Mobile, which will allow us to style the elements within our application. jQuery Mobile styles the elements to act more like they were part of a native mobile application and less like a website. We’re also connecting to the hammer.js library, which we’ll use to detect the gestures.

We’ll be using the “page” metaphor that’s part of jQuery Mobile. The style sheet simply affixes the footer to the bottom of the screen.

<style>
        #footer
        {
            position: fixed;
            bottom: 0px;
            width: 100%;
        }
</style>

In the body section of the code, there are a number of logical divisions that provide the scaffolding for the content. You’ll note there is a header section, a main section, and a footer section. We’re going to use the main section of our application to demonstrate gestures.

Now is a good time to try your code in the browser. If you typed everything correctly so far, it should look something like Figure 1.


Figure 1: Note the visible headers and footers that appear in the web browser

Step 2: Add the data source

As a reminder, this application is designed to teach programming terminology. So, we’re going to need the terminology and definitions we’re going to teach. The code for this is located here. (I’ve used a Gist to store the code; see Figure 2. Gist is part of GitHub and is great for storing code like this!)

[Note from the editor: GitHub may be a new service to you, and in that case, Gist is probably also a new term to you. Please take the time to access these resources: Wikipedia’s GitHub page and two GitHub videos, What is GitHub? and How we build software.]

Figure 2: Application data on the Gist site

Copy the code in Figure 2 and save it in a separate file called terminology.js. Make sure you save it in the same folder as your other source-code file.

Now, above your stylesheet, add the following line to your original source code file:

<script src="terminology.js"></script>

This will include the data for the application.

Take a quick look at the code we’re adding. It’s pretty straightforward. There are two parallel arrays. The first array called vocab contains the terms that we want our user to learn. The definitions array contains the definitions for each of the terms.

Step 3: Display the first term

First we’ll add a logical division that will contain the term and definition. Within that division, we’ll add separate child divisions for each of the two pieces of information. Make sure you’re writing your code inside the <div> labeled data-role=“main” and enter the following code:

<div id="display">
        <div id="term"></div>
        <div id="definition"></div>
</div>  

That provides the space for the term, but we need to add some JavaScript to make the term display from the data. Again, right above the style element, add a set of script tags. Inside the script tags, add the following code:

var currentTerm = 0;
var lastTerm;
        
    window.onload=function()
    {
        lastTerm = vocab.length;
        document.getElementById('term').innerHTML = "<h1>" + vocab[currentTerm] + "</h1>";
    }

This code first defines the variables that we’ll use to track which term the user is reviewing and how many terms there are on the list.

The window.onload function runs when the page is drawn and determines the length of the term list and then displays the first term in the proper logical division. The expression vocab[currentTerm] will display the first vocab element because the initial value of currentTerm is zero.

Step 4: Add a tap gesture that displays the definition

When the displayed vocabulary word is tapped, we’ll have the associated definition displayed. This is where the hammer.js library comes into play. Inside your window.onload function, below the last line of code you wrote, add:

//Make it tappable
        var myHammer = new Hammer(document.getElementById('term'));
        myHammer.on("tap", function(ev){
           document.getElementById('definition').innerHTML = definitions[currentTerm]; 
        });

This code is a bit more dense. First, we define a new instance of Hammer. When we create the instance of Hammer, we provide the name of the div we want to add the gesture to. Next, using the on keyword, we define the event—in this case tap—and the function that will run in the event of a tap event.

The callback function, in this case, simply populates the definition div with the proper definition from the data array.

Run your code again. If your code is correct up to this point, you’ll see the term appear on the screen (Figure 3). Tap on the term using your mouse (which simulates a tap in mobile) and the definition should appear. If it doesn’t, review your code and look for an error or typo.

Figure 3: The application up to this point. The application reacts to the tap gesture and displays the term and its definition.

Step 5: Implement a swipeleft gesture to display the next term

In order to implement another gesture, we have to create another instance of Hammer and another callback. This instance will detect the swipeleft gesture and call a function called nextTerm when the event occurs.

At the end of the window.onload function, add the following code:

var termHammer = new Hammer(document.getElementById('display'));
 termHammer.on("swipeleft", nextTerm);

As you can see, the new instance of hammer called “termHammer” is created, and it is associated with the display div which contains both the term and the definition. The nextTerm callback function follows.

function nextTerm(evt)
    {
        currentTerm++;
        displayTerm();
    }

In the callback function above, we’ve incremented the currentTerm variable so that we move through the arrays of terms and definitions. We then call the displayTerm() function which you’ll have to add. The code appears below:

function displayTerm()
    {
        document.getElementById('term').innerHTML = "<h1>" + vocab[currentTerm] + "</h1>";
        document.getElementById('definition').innerHTML = "";   
    }

This actually displays the new term and clears the div where the definition appears. The definition appears when there is a subsequent tap on the term.

Let’s test again at this point. If you tap on the term and then make a slide gesture toward the left, the next term should appear. If not, verify your code, make corrections, and try again.

(If you’ve tried and tried and still can’t get your code to work, I’ve posted the code up to this point on another Gist here.)

Step 6: Prevent falling off the cliff

You might notice that if you swipe enough, you will get beyond the last term and your display will look something like Figure 4.

Figure 4: We have officially fallen off the cliff. This is not good!

To prevent ourselves from going outside the bounds of the available data, we need to add two small features to our application:

  1.  A swiperight so the user can go backward
  2.  A rollover feature that goes back to the first term if we fall off the cliff

Let’s deal with the swiperight gesture first.

We’re going to change our termHammer object so that it detects both swiperight and swipeleft events. Alter the code so it now looks like this:

termHammer.on("swipeleft swiperight", nextTerm);

Now it will recognize both gestures. We’re also going to have to alter the nextTerm function so that it can handle going backward or forward through the array of data.

function nextTerm(evt)
    {
        if(evt.type=="swipeleft"){
            currentTerm++;
        } else
        {
            currentTerm--;
        }
        displayTerm();
    }

The evt object passed into the function has information about the gesture that just occurred. The type property can tell us if the gesture was a swipeleft gesture or a swiperight gesture. Using this information, we either increment or decrement currentTerm to move through the array.

We can now move forward or backward through the data, but we can still fall off the cliff. This is also another good point to test and debug your code.

Now, to prevent us from going outside the bounds of the data we have, you’ll again have to modify the nextTerm function.

function nextTerm(evt)
    {
        if(evt.type=="swipeleft"){
            currentTerm++;
        } else
        {
            currentTerm--;
        }
        
        if(currentTerm == (lastTerm-1)){
            currentTerm = 0;
        }
        
        if(currentTerm < 0){
            currentTerm = lastTerm-1;
        }
        displayTerm();
    }

If you follow the logic, this simply tests the new value of currentTerm after the swipe. If it’s outside of bounds—below zero or greater than the number of terms available—it resets the counter. 

Test one last time, and you should be able to continuously use the swipe gestures to move through the list of vocabulary.

Using gestures, you can allow users to interact with your mobile learning the same way they interact with other apps on their mobile device. The advantage is that consuming your content will become instinctual, and the focus can be on the content you’re presenting.

The complete code for this app is available here.

Want more? Mark will be presenting at FocusOn Learning!

You can learn more from Mark Lassoff by attending his sessions at FocusOn Learning Conference & Expo, June 20 – 22 in San Diego, California.