Quick tip for using Knockout.js and jQuery Mobile List Dividers

For my latest project I needed to bind a Knockout.js observableArray to a jQuery Mobile listview with a list divider at the top.

I initially tried adding the data-bind attribute to the ul element as shown in the code below (see jsFiddle for the complete code listing and working demo).

<ul data-role="listview" data-bind="foreach: fruit">
    <li data-role="list-divider">Fruit</li>
    <li>
        <h3 data-bind=" text: Name"/>
    </li>
</ul>

But this meant the list divider was repeated for every list item!

Knockout.js without comment based control

Comment based control flows to the rescue

By using a comment based control flow (introduced in knockout.js 2.0) the foreach binding can be moved below the list divider but still within the ul element.

See jsFiddle for the complete code listing and working demo.

<ul data-role="listview">
    <li data-role="list-divider">Fruit</li>
    <!-- ko foreach: fruit -->
    <li>
        <h3 data-bind=" text: Name"/>
    </li>
    <!-- /ko -->
</ul>

Knockout.js jQuery Mobile Comment Based Control Flow

How to create a jQuery Mobile App using ASP.NET MVC

In this post I’ll show you how to create a mobile web app using jQuery Mobile and ASP.NET MVC 4.

I’ve used AppHarbor to host the app so you can see it action by clicking here.

Yummy Bakes

The source code for the demo in this post can be found on github.

The first step in creating a mobile ASP.NET MVC mobile web app is to either choose select the ‘Mobile Application’ project template or an empty project.

ASP.NET MVC project template

As personal preference I prefer the empty solution as it won’t be cluttered by controllers, views and scripts you don’t need.

In the layout file for the app (used as the template for other views) we add the CSS and JavaScript resources required.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
    <link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/css")" rel="stylesheet" type="text/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.1/jquery.mobile-1.0.1.min.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
    <script type="text/javascript" src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/js")"></script>    
</head>
<body>
    <section data-role="page" data-theme="d" id="@ViewBag.PageId">
        <section data-role="header"data-theme="e">
            <section id="header">
                <a href="@Url.Action("Index", "Recipe")">
                    <h2 class="header-text">
                        <img src="~/Content/Images/logo.png" alt="YummyCake">Yummy Bakes</h2>
                </a>
            </section>
        </section>
        <section data-role="content">
            @RenderBody()
        </section>
    </section>
</body>
</html>

Here we’re using the new ASP.NET MVC 4 bundling and minification functionality in combination with content delivery networks (CDN’s) to increase the performance of the application.

You can read more about bundling and minification in the post ‘ASP.NET MVC Mobile Performance Tip – Bundle and Minify‘.

jQuery Mobile data-* attributes

If you’ve not used jQuery Mobile before you may be wondering what the data-* attributes are for.

jQuery Mobile uses the attributes to apply styles and functionality to elements on the page.

As the same header will be used in all of the pages in this mobile web app we can define it in the layout file.

The call to RenderBody() is wrapped in a data-role= “content” attribute which jQuery Mobile uses to define the content of a page.

See the jQuery docs for more information about page structure.

Now we’ve created the layout template the next thing to do is create the ASP.NET MVC controller for the mobile web app.

using System;
using System.Linq;
using System.Web.Mvc;
using YummyBakesASPNETMVC.Data;
using YummyBakesASPNETMVC.Models;

namespace YummyBakesASPNETMVC.Controllers
{
    public class RecipeController : YummyBakesBaseController
    {
        public ActionResult Index()
        {
            return View(SampleRecipes.Recipes.Take(3).ToList());
        }

        public ActionResult Details(int id)
        {
            ViewBag.PageId = "recipe-details";
            return View(SampleRecipes.Recipes.Single(r => r.Id == id));
        }

        public ActionResult Find()
        {
            return View(SampleRecipes.Recipes);
        }

        public ActionResult AddReview(Review review)
        {
            review.DatePublished = DateTime.Now;                        
            //SampleRecipes.Recipes.Single(r => r.Id == review.RecipeId).Reviews.Add(review);
            return Content(RenderPartialViewToString("Review", review));
        }
    }
}

The Index action for the RecipeController will return a view model containing the top 3 baking recipes.

To keep things simple the recipes are coming back from a static list and not from a database.

In the view for the Index action the user will see text about the app, a link to a page to find recipes and a list of the top three recipes.

Yummy Bakes Home

The markup for the view is shown below.

@model IEnumerable<YummyBakesASPNETMVC.Models.Recipe>
@{
    ViewBag.Title = "Yummy Bakes";    
}
<p class="intro">
    From old favourites to new twists on modern classics, from sweet to savoury we've
    got a recipe just for you!</p>
<a href="@Url.Action("Find","Recipe")" data-role="button" data-icon="search" class="find-recipe-link">Find a recipe</a>
<ul data-role="listview" data-divider-theme="e" class="recipe-list">
    <li data-role="list-divider" class="list-divider">Top Recipes</li>
    @foreach (var recipe in @Model)
    {
        Html.RenderPartial("RecipeListItem", recipe);
    }
</ul>

Note how the RenderPartial method to output the list items.

Partial views are a great way of separating the responsibly of a view and help keep ASP.NET MVC mobile web apps in a maintainable structure.

Again if you’re new to jQuery Mobile the data-role=”listview” attribute in the ul tag is used to style lists, the data-role=”button” attribute makes a standard hyperlink look like a button for which we add an icon to by using the data-icon attribute.

The recipe detail view uses partial views to display information for the recipe for which CSS is used to add the background images and style the lists.

It also contains a form so users can submit reviews.

YummBakes Review

I’ve commented out the line in the code that would actually persist the review (because I don’t want to manage spam) so any reviews you add will only be shown locally on the page.

The JavaScript below shows the AJAX call used to submit a new review.

Pay attention to the line which refreshes the list view called in the complete event. Without this the list of reviews would not get updated. See the post ‘Don’t forget to call refresh when adding items to your jQuery Mobile list‘.

$(".review-form").validate({
    submitHandler: function (form) {            
        var data = {
            RecipeId: $('#recipeId').val(),
            Author: $('#name').val(),
            Title: $('#title').val(),
            Rating: $(".starRating span.chosen").length,
            Body: $('#review-body').val()
        };

        $.ajax({
            type: 'POST',
            url: $(".review-form").attr('action'),
            data: data,
            success: function (result) {
                $('.review-collapsible').trigger('collapse');
                $(".review-form")[0].reset();
                $('.reviews').append(result);
            },
            error: function (request, status, error) {
                console.log(request.responseText);
                console.log(status);
                console.log(error);
            },
            complete: function () {
                $('.reviews').listview('refresh');
            }

        });
    }
});

As we’ll see in this series about creating mobile web apps there are a number of ways of how we could have structured an application like this.

This example uses multiple pages, so whenever a user clicks on a link to see the detail for a recipe, a request is made to the server which is handled by a controller action with its’ own view.

In later posts in the series we’ll see how this differs to ASP.NET MVC single page applications.

ASP.NET MVC Mobile Performance Tip – Bundle and Minify

A few months ago I wrote a blog post about how you could improve the performance of your ASP.NET MVC apps using a third party library to compress and combine your CSS and JavaScript resources.

The latest release of ASP.NET (v4.5) comes with its’ own bundling and minification tools.

And the great news is they’re very easy to use.

For example if your layout file contained three CSS and four JavaScript resources

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/html5reset-1.6.1.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/photoswipe.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/respond.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/klass.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/code.photoswipe-2.1.6.min.js")" type="text/javascript"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

You can bundle and minify CSS and Javascript resources for your ASP.NET mobile apps by using standard HTML like this

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="/Content/css" rel="stylesheet" type="text/css" />
    <script src="/Scripts/js" type="text/javascript"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

or like this using HTML helpers

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" rel="stylesheet" type="text/css" />
    <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
</head>
<body>
    @RenderBody()
</body>
</html>

Note: Scott Gu reckons the helper will probably be called Html.Bundle in the future.

Using HTML helpers gives you the advantage of adding a unqiue hash based upon the contents of the directory structure on the server for the script resource e.g.

Bundling and Minification Hash Files

ASP.NET will then cache the output for a year which means it will be served from the cache.

Should any files in a resource directory change the generated hash will also change and user will get an updated version of the file.

So how does ASP.NET MVC 4.5 bundling and minification perform?

This is Chrome resource graph for loading the page without any bundling or minification

Without bundling or minification

and here’s the resource graph for a ASP.NET MVC app using the new bundling or minification tools.

With bundling or minification

The images say it all!

How to create a jQuery Mobile Plugin

In this post we’ll see how to create a jQuery Mobile plugin.

This plugin will enhance a users’ experience of your jQuery Mobile app by adding a ‘Back to top’ button to a page.

This will save them from having to continuously scroll to get back to the top of a page.

back top to demo on the iPhone

See the post ‘jQuery Mobile UX: Add a back to top button‘ for more details abouts how it works.

The first step in creating a jQuery Mobile plugin… use a boilerplate!

Thanks to Addy Osmani creating a jQuery Mobile plugin is easy becuase he’s put together boilerplates for jQuery plugins.

You can find out more by reading his Smashing Magazine article ‘Essential jQuery Plugin Patterns‘.

The boilerplate code for the plugin can be found on github.

Getting started with the jQuery Mobile Plugin Boilerplate

For a jQuery Mobile plugin we will use the ‘jquery.widget-factory.mobile-plugin.boilerplate.js’ boilerplate.

All that’s left is to define the namespace, add the options and write the functions for the plug in.

jQuery Mobile plugin namespaces

As this is a mobile plugin we’ll use mobile as the first parameter and the name of the plug in as the second parameter.

$.widget("mobile.backToTop", $.mobile.widget, {

jQuery Mobile plugin options

Options allow users to configure the plugin.

For this plugin the user is able to specify:

The id. The default is ‘backToTop’.

The text. The default is ‘Back to top’.

The theme. The default is ‘a’. However the user can provide the letter if they want to use a particular theme.

The position. The default is the top left corner. The user can specify another location using the values ‘topright’,'bottomleft’ and ‘bottomright.

The _create function

This function will run the first time the widget is called.

For the back to top plugin the _create function is used to add the button to the page, position it and bind events.

Deciding if a plugin functions should be private or public?

Any functions you want to be able to be called externally should be public and called like this

$(document).backToTop("click");

or like this passing an argument

$(document).backToTop("position","bottomleft");

Private functions start with _underscores.

Using the plugin

This plugin adds a button to the document body so it doesn’t need to listen to the create event for an indivual page.

$(document).bind("pageinit", function() {
    $(document).backToTop({
        id: 'backToTopPlugin',
        text: 'Back to top',
        theme: 'b',
        position: 'bottomright'
    });
});

This means it doesn’t matter if there are multiple jQuery Mobile pages within the same document the _create function will only be called once, and work on all of the pages.

The code for the jQuery Mobile plugin

Rather than having to keep updating this post with the latest version of the plugin, the code is stored on github.

Mobile Intel: Tablets and smartphones – so what’s the big deal?

Mel Findlater gave an excellent talk today for the Cambridge Usability Group about how tablets in particular can change lives.

Mel Findlater

She started by giving an insight into how tablets have transformed the lives of people with disabilities by helping them communicate, interact and learn.

By using a mainstream rather than a specialist device they felt more confident allowing them to break down barriers and build relationships which otherwise would have been difficult to do.

Mel also talked about the role tablets played in ‘keeping dementia at bay’ and played a video of an elderly gentleman talking about how an iPad gave him opportunities to do challenging tasks and activities.

It’s very rare to attend a presentation were so many of the audience wanted to share their experiences and ideas, which goes some way to tell you how good a job Mel did.

Mel mentioned she’s trying to put together an event for developing apps for older and disabled users so if you’re interested let her know.

There’s also a Official RNIB Accessibility Hackathon taking place on Saturday 11th Febuary 2012 in London, so if you’re interested developing apps with accessibility in mind make sure you sign up!

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.

Example of using the jQuery Mobile scrollstart and scrollstop events

In this post we’ll see how easy it is to bind to the jQuery Mobile scrollstart and scrollstop events.

The JavsScript below shows how to bind to the scrollstart and scrollstop events.

$('div[data-role="page"]').live('pageinit', function (event, ui) {
    var eventsElement = $('#events');
    $(window).bind('scrollstart', function () {
        console.log('start');
        $('.ui-body-c').css('background', 'green');
        eventsElement.append('<li><a href="">Start</a></li>');
        eventsElement.listview('refresh');
    });

    $(window).bind('scrollstop', function () {
       console.log('stop');
       $('.ui-body-c').css('background', 'red');
       eventsElement.append('<li><a href="">Stop</a></li>');
       eventsElement.listview('refresh');
    });
});

When the user starts scrolling the background turns green and when the user stops scrolling the background turns red.

Whenever a scroll event is triggered an item is added to the list.

You see can see a demo of the scrollstart and scrollstop events in action here.

JavaScript best practice: Always specify a radix when using parseInt

Whenever you use the parseInt function make sure you always specify the radial, even though it’s optional… otherwise you could end up with some unexpected results.

For example the JavaScript code below parses two numbers without specifying a radial and adds them together

$('#Calculate').click(function() {
    var firstNumber = parseInt($('#firstNumber').val());
    var secondNumber = parseInt($('#secondNumber').val());
    $('#total').val(firstNumber + secondNumber);
});

When the user enters ’043′ as the first number and ’1′ and the second number

What happens when you don't use parseInt

the calculated result is 36 and NOT 44. You can test this yourself using this jsFiddle.

This happens because the input began with “0” and so the radix of eight (octal) was used.

The solution is to specify a radix, which in our case is ten (decimal).

$('#Calculate').click(function() {
    var firstNumber = parseInt($('#firstNumber').val(),10);
    var secondNumber = parseInt($('#secondNumber').val(),10);
    $('#total').val(firstNumber + secondNumber);
});

For this reason the best practice is to always specify a radix when using parseInt.