Posts about HTML5

jQuery Mobile UX: Add a back to top button

In this post we’ll see how you can improve the user experience (UX) of your jQuery Mobile apps by adding a back to top button.

back top to demo on the iPhone

You can check out a demo of the back to top button here.

Just remember to resize your browser window so you have to scroll!

How does it improve the UX of your jQuery Mobile app?

No doubt you’ve been to a page on your mobile device where the only way to get back to the top of the page is to continuously keep swiping?

Using the jQuery Mobile scrollstart and scrollstop events we can show a back to top button whenever the user has scrolled to a position which is greater of their browsers viewport as shown in the mock up below.

back to top mock up

How to create the back to top button

The first step is to add a button element to the body and bind a click event to it.

$('body').append('<a href="" id="backToTop" data-role="button" data-icon="arrow-u" data-theme="b">Back to top</a>');
$('#backToTop').click(backToTop.click);

The click event is handled by a function which scrolls to the top of the document body element.

While we could use the jQuery Mobile silentScroll function to scroll to the top of the page, the animate function gives a nice smooth scroll.

click: function () {
    backToTop.hideBackToTopButton();
    $('html, body').animate({scrollTop: 0}, 800);
}

As we are dynamically adding an element to a jQuery Mobile page we need to call the trigger function.

$('body').trigger('create');

Next we bind the scrollstart event to a function to hide the button.

$(window).on('scrollstart', backToTop.scrollStart);

scrollStart: function () {
    $('#backToTop').hide();
}

The scrollstop event is bound to a function that checks if the Y offset is greater than the height of browsers’ viewport.

Fading the button is much smoother than just showing it.

$(window).on('scrollstop', backToTop.scrollStop);

scrollStop: function () {
    var windowHeight = $(window).height();
    if (window.pageYOffset > windowHeight) {
        $('#backToTop').fadeIn('slow');
    }
}

The final step is to hook up the code for the back to top button to the page.

$('#backToTopDemoPage').live('pageinit', function (event, ui) {
    backToTop.init();
});

For more about jQuery Mobile events check out the docs.

Styling the jQuery Mobile button

As jQuery Mobile has excellent theming support you can use a data theme HTML5 attribute to style the button.

The location of the button can be changed using CSS styles.

For example to show the button in the top left corner use the CSS

top: 0px;
left: 0px;

to show the button in the botton right corner set the CSS as below:

bottom: 0px;
right: 0px;

or a combination of both.

The complete code listing is shown below.

<!DOCTYPE html>
<html>
<head>
    <title>Back to top demo</title>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>    
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
    <script type="text/javascript">
        var backToTop = {
            init: function () {
                $('html, body').append('<a href="" id="backToTop" data-role="button" data-icon="arrow-u" data-theme="b">Back to top</a>');
                $('#backToTop').click(backToTop.click);
                $(window).bind('scrollstart', backToTop.scrollStart);
                $(window).bind('scrollstop', backToTop.scrollStop);
                $('body').trigger('create');
            },
            click: function () {
                $('html, body').animate({scrollTop: 0}, 800);
            },
            scrollStart: function () {
                $('#backToTop').hide();
            },
            scrollStop: function () {
                var windowHeight = $(window).height();
                if (window.pageYOffset > windowHeight) {
                    $('#backToTop').fadeIn('slow');
                }
            }
        };

        $('#backToTopDemoPage').live('pageinit', function (event, ui) {
            backToTop.init();
        });
    </script>
    <style type="text/css">
        #backToTop {
            position: fixed;
            top: 0px;
            left: 0px;
            display: none;
        }
    </style>
</head>
<body>
    <div data-role="page" id="backToTopDemoPage" data-theme="d">
        <div data-role="content">
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
                incididunt ut labore et dolore magna aliqua.</p>
        </div>
    </div>
</body>
</html>

In the next post we’ll be looking at how to creating a back to top jQuery Mobile plugin.

How to use AmplifyJS with jQuery Mobile

AmplifyJS is a fantastic library that can provide storage to mobile devices that don’t natively support HTML5 local storage.

Using AmplifyJS means we don’t need libraries such as Modernizer to check if a mobile browser supports local storage.

AmplifyJS will try using other types of storage and fall back to use memory if it has to.

We will use the same example as was used in the post ‘How to use HTML5 local storage with jQuery Mobile’ which stores the text a user enters in local storage.

How to use Amplify.Store

You can set a value like this

amplify.store(key, value);

and get a value like this

amplify.store(key);

To see it in action check out this demo page.

The complete code listing used for the demo is shown below

<!DOCTYPE html>
<html>
<head>
    <title>jQuery Mobile local storage using AmplifyJS demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css"/>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js"></script>
    <script type="text/javascript" src="jquery.json-2.3.min.js"></script>
    <script type="text/javascript" src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>
    <script type="text/javascript" src="https://raw.github.com/appendto/amplify/master/store/amplify.store.js"></script>

    <style>
        #message {
            display: none;
            border-radius: 10px;
            padding: 10px;
            background-color: #ff0000;
            color: #fff;
        }

        #storageDemoPage h2 {
            white-space: normal;
        }
    </style>

    <script type="text/javascript">
        var localStorageKey = "demoStorageKey";
        $('#storageDemoPage').live('pagecreate', function() {
            updateStoreValue();

            $('#addToStorage').click(function(e) {
                amplify.store(localStorageKey, $('#entry').val());
                updateStoreValue();
                e.preventDefault();
            });
        });

        function updateStoreValue() {
            var item =  amplify.store(localStorageKey);
            if (item == null)
            {
                item = 'Nothing in store';
            }
            else if (item.length === 0 )
            {
                item = 'Store contains empty value';
            }
            $('.storeItem').text(item);
        }
    </script>
</head>
<body>
<section data-role="page" id="storageDemoPage">
    <section data-role="header">
            <h2>jQuery Mobile storage using AmplifyJS demo</h2>
    </section>
    <section data-role="content">
        <p id="message"/>
        <ul data-role="listview" data-inset="true">
            <li data-role="list-divider">Enter text to store</li>
            <li>
                <input type="text" id="entry" name="entry" placeholder="Enter text to store"/>
                <input type="button" id="addToStorage" value="Add to local storage"/>
            </li>
            <li data-role="list-divider">Item in store</li>
            <li class="storeItem"/>
        </ul>
    </section>
</section>
</body>
</html>

How to use HTML5 local storage with jQuery Mobile

In this post we’ll see how to use HTML5 local storage with jQuery Mobile.

It’s really easy to use local storage with mobile browsers

you can set a value like this

localStorage.setItem(key, value);

and get a value like this

localStorage.getItem(key);

How do you know if a mobile browser supports local storage?

Using Modernizer it’s easy to check if a browser supports local storage.

The code below shows an example how you could detect if local storage is supported or not.

if (Modernizr.localstorage) {
    // good times
}
else {
    // bad times
}

The good news is there are plenty of polyfills and third party libraries that provide storage support on mobile browsers that don’t natively support it.

To see an example of how to do this check out the post ‘’.

An example of using HTML5 local storage with jQuery Mobile

In this example we’ll store the text user enters in local storage.

The first thing to do is check if a browser supports local storage.

If it doesn’t we display a message to the user and disable the add button.

This can be done using the code below.

if (Modernizr.localstorage) {
    showStoreValue();
}
else {
    $('#message').text("Unfortunately your browser doesn't support local storage");
    $('#addToStorage').attr('disabled', 'disabled');
    $('#message').show();
}

Now if a browser visits the page and doesn’t support local storage they will see the following message.

The picture is just for illustrative purposes the iPhone does actually support local storage.

local storage not supoorted

The code to store the text value in local storage when the ‘Add to local storage’ button is clicked is shown below.

$('#addToStorage').click(function(e) {
    localStorage.setItem(localStorageKey, $('#entry').val());
    showStoreValue();
    e.preventDefault();
});

Before we display the value in local storage to the user, we need to check if a value exists and isn’t an empty string.

function showStoreValue() {
    var item = localStorage.getItem(localStorageKey);
    if (item == null) {
        item = 'Nothing in store';
    }
    else if (item.length === 0) {
        item = 'Store contains empty value';
    }
    $('.storeItem').text(item);
}

Using the developer tools in Google Chrome to see what’s in local storage

If you open this demo page using a Google Chrome you can use the developer tools to check what is in local storage by going to Resources > Local Storage

Chrome developer tools local storage

The complete code listing used for the demo is shown below

<!DOCTYPE html>
<html>
<head>
    <title>jQuery Mobile local storage demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css"/>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js"></script>
    <script type="text/javascript" src="http://www.modernizr.com/downloads/modernizr-latest.js"></script>
    <style>
        #message {
            display: none;
            border-radius: 10px;
            padding: 10px;
            background-color: #ff0000;
            color: #fff;
        }

        #storageDemoPage h2 {
            white-space: normal;
        }
    </style>
    <script type="text/javascript">
        var localStorageKey = "demoStorageKey";
        $('#storageDemoPage').live('pagecreate', function() {
            if (Modernizr.localstorage) {
                showStoreValue();
            }
            else {
                $('#message').text("Unfortunately your browser doesn't support local storage");
                $('#addToStorage').attr('disabled', 'disabled');
                $('#message').show();
            }
            $('#addToStorage').click(function(e) {
                localStorage.setItem(localStorageKey, $('#entry').val());
                showStoreValue();
                e.preventDefault();
            });
        });

        function showStoreValue() {
            var item = localStorage.getItem(localStorageKey);
            if (item == null) {
                item = 'Nothing in store';
            }
            else if (item.length === 0) {
                item = 'Store contains empty value';
            }
            $('.storeItem').text(item);
        }
    </script>
</head>
<body>
<section data-role="page" id="storageDemoPage">
    <section data-role="header">
        <h2>jQuery Mobile local storage demo</h2>
    </section>
    <section data-role="content">
        <p id="message"/>
        <ul data-role="listview" data-inset="true">
            <li data-role="list-divider">Enter text to store</li>
            <li>
                <input type="text" id="entry" name="entry" placeholder="Enter text to store"/>
                <input type="button" id="addToStorage" value="Add to local storage"/>
            </li>
            <li data-role="list-divider">Item in store</li>
            <li class="storeItem"/>
        </ul>
    </section>
</section>
</body>
</html>

To learn more about HTML5 local storage read this page on the dive into HTML5 site.

Mobile UX Tips – Don’t make users delete text in input fields

Ever had to delete text in an input field before you can type in what you want to enter?

It’s a pain if you’re using a desktop browser but on a mobile or tablet browser it’s complete UX fail.

The good news is it’s an easy problem to solve.

If you’re a modern browser it probably supports the HTML5 placeholder attribute.

This allows you to show helpful text in the input field which disappears when the user focuses on it.

The HTML markup below shows how to use the placeholder attribute

<form>
    <input name="q" id="q" placeholder="Enter product name or number">
    <input type="submit" value="Search">
</form>

If your browser supports it, the text in the input field should disappear when you click or tab onto it.

So what happens if a browser doesn’t support HTML5 placeholders?

The user would just see an empty text input field (try opening this page in Internet Explorer for an example).

But this isn’t what we want.

Having text in the input field is helpful because it can help the user to understand what they can enter.

One possible workaround is to use jQuery to show and hide the ‘placeholder’ text when the user focuses on the input field.

<!DOCTYPE html>
<html lang="en">
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
    <script type="text/javascript">
        var searchText = 'Enter product name or number';
        $(document).ready(function() {
            $("#q").val(searchText);
            $("#q").focus(function() {
                if ($(this).val() === searchText) {
                    $(this).val('');
                }
            });
            $("#q").blur(function () {
                if ($(this).val() === '') {
                    $(this).val(searchText);
                }
            });
        });
    </script>
</head>
<body>
<form>
    <input name="q" id="q" placeholder="Enter product name or number">
    <input type="submit" value="Search">
</form>
</body>
</html>

which works like this

But using javascript to solve the issue means browsers that do support the placeholder attribute are forced to use the workaround as well…

Modernizer to the rescue

Using Modernizer we are able to detect browser features. This means we only use the jQuery workaround on browsers that don’t support the placeholder attribute.

Here’s the final code showing how to use modernizer and the jsfiddle page to try it out.

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>
    <script type="text/javascript" src="http://www.modernizr.com/downloads/modernizr-latest.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
    <script type="text/javascript">
        if (Modernizr.input.placeholder) {
        }
        else {
            var searchText = 'Enter product name or number';
            $(document).ready(function() {
                $("#q").val(searchText);
                $("#q").focus(function() {
                    if ($(this).val() === searchText) {
                        $(this).val('');
                    }
                });
                $("#q").blur(function () {
                    if ($(this).val() === '') {
                        $(this).val(searchText);
                    }
                });
            });
        }
    </script>
    <style type="text/css">
        body {
            padding: 10px;
        }

        #q {
            width: 280px;
        }
    </style>
</head>
<body>    
<form>
    <input name="q" id="q" placeholder="Enter product name or number">
    <input type="submit" value="Search">
</form>
</body>
</html>

Using HTML5 elements with jQuery Mobile

Most developers looking to learn about jQuery Mobile will quite rightly look to the jQuery Mobile docs to start with.

It is an excellent resource.

But one thing I find odd is that while the DOCTYPE is declared the HTML5 way, divs are used instead of header and footer elements.

Here’s an example taken straight from the docs and the jsFiddle page showing it running.

<!DOCTYPE html>
<html>
  <head>
  <title>Page Title</title>
 
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css" />
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
  <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
</head>
<body>

<div data-role="page">

  <div data-role="header">
    <h1>Page Title</h1>
  </div><!-- /header -->

  <div data-role="content">
    <p>Page content goes here.</p>   
  </div><!-- /content -->

  <div data-role="footer">
    <h4>Page Footer</h4>
  </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>

And here’s a version using HTML5 markup and its jsFiddle page showing it running.

<!DOCTYPE html>
<html>
  <head>
  <title>Page Title</title>
 
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css" />
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
  <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
</head>
<body>

<section data-role="page">

  <header data-role="header">
    <h1>Page Title</h1>
  </header><!-- /header -->

  <div data-role="content">
    <p>Page content goes here.</p>   
  </div><!-- /content -->

  <footer data-role="footer">
    <h4>Page Footer</h4>
  </footer><!-- /footer -->
</section><!-- /page -->

</body>
</html>

As you can the page gets rendered the same way.

So if you’re beginning to use jQuery Mobile you should consider using HTML5 elements especially for your header and footer instead of divs.

At this point you might be thinking why is a div still being used? It’s important to remember that it is still OK to use divs ;)