Page Events

Exclusive offer: get 50% off this eBook here
jQuery Mobile Cookbook

jQuery Mobile Cookbook — Save 50%

Over 80 recipes with examples and practical tips to help you quickly learn and develop cross-platform applications with jQuery Mobile book and ebook.

$26.99    $13.50
by Chetan K Jain | January 2013 | Cookbooks Open Source

This article by Chetan K Jain, author of jQuery Mobile Cookbook, shows you how to use the various events available in the framework. You will learn to use the page initialization, page load, page change, and page remove events. You will also see how to use the page transition and animation events.

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

Page initialization events

The jQuery Mobile framework provides the page plugin which automatically handles page initialization events. The pagebeforecreate event is fired before the page is created. The pagecreate event is fired after the page is created but before the widgets are initialized. The pageinit event is fired after the complete initialization. This recipe shows you how to use these events.

Getting ready

Copy the full code of this recipe from the code/08/pageinit sources folder. You can launch this code using the URL http://localhost:8080/08/pageinit/main.html

How to do it...

Carry out the following steps:

  1. Create main.html with three empty <div> tags as follows:

    <div id="content" data-role="content"> <div id="div1"></div> <div id="div2"></div> <div id="div3"></div> </div>

  2. Add the following script to the <head> section to handle the pagebeforecreate event :

    var str = "<a href='#' data-role='button'>Link</a>"; $("#main").live("pagebeforecreate", function(event) { $("#div1").html("<p>DIV1 :</p>"+str); });

  3. Next, handle the pagecreate event :

    $("#main").live("pagecreate", function(event) { $("#div1").find("a").attr("data-icon", "star"); });

  4. Finally, handle the pageinit event :

    $("#main").live("pageinit", function(event) { $("#div2").html("<p>DIV 2 :</p>"+str); $("#div3").html("<p>DIV 3 :</p>"+str); $("#div3").find("a").buttonMarkup({"icon": "star"}); });

How it works...

In main.html, add three empty divs to the page content as shown. Add the given script to the page. In the script, str is an HTML string for creating an anchor link with the data-role="button" attribute.

Add the callback for the pagebeforecreate event , and set str to the div1 container. Since the page was not yet created, the button in div1 is automatically initialized and enhanced as seen in the following image.

Add the callback for the pagecreate event . Select the previous anchor button in div1 using the jQuery find() method, and set its data-icon attribute. Since this change was made after page initialization but before the button was initialized, the star icon is automatically shown for the div1 button as shown in the following screenshot. Finally, add the callback for the pageinit event and add str to both the div2 and div3 containers. At this point, the page and widgets are already initialized and enhanced. Adding an anchor link will now show it only as a native link without any enhancement for div2, as shown in the following screenshot. But, for div3, find the anchor link and manually call the buttonmarkup method on the button plugin, and set its icon to star. Now when you load the page, the link in div3 gets enhanced as follows:

 

 

There's more...

You can trigger "create" or "refresh" on the plugins to let the jQuery Mobile framework enhance the dynamic changes done to the page or the widgets after initialization.

Page initialization events fire only once

The page initialization events fire only once. So this is a good place to make any specific initializations or to add your custom controls.

Do not use $(document).ready()

The $(document).ready() handler only works when the first page is loaded or when the DOM is ready for the first time. If you load a page via Ajax, then the ready() function is not triggered. Whereas, the pageinit event is triggered whenever a page is created or loaded and initialized. So, this is the best place to do post initialization activities in your app.

$(document).bind("pageinit", callback() {...});</p>

 

jQuery Mobile Cookbook Over 80 recipes with examples and practical tips to help you quickly learn and develop cross-platform applications with jQuery Mobile book and ebook.
Published: November 2012
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Page load and remove events

The jQuery Mobile framework triggers the page load events whenever an external page is loaded into the DOM. It fires the pagebeforeload event before loading the page and then fires either the pageload or pageloadfailed event based on the status of the page load. The pageremove event is fired when a page is removed from the DOM. This recipe shows you how to use the page load and page remove events.

Getting ready

Copy the full code of this recipe from the code/08/pageload sources folder. You can launch this code using the URL http://localhost:8080/08/pageload/main.html.

How to do it...

Carry out the following steps:

  1. Create main.html with four buttons and an empty div element, as shown in the following code snippet:

    <div id="content" data-role="content"> <a href="page1.html" data-role="button" data- inline="true">Page 1</a> <a href="page2.html" data-role="button" data- inline="true">Page 2</a> <a href="page3.html" data-role="button" data- inline="true">Page 3</a> <a href="page4.html" data-role="button" data- inline="true">Page 4</a> <div id="msgdiv"></div> </div>

  2. Add the following script to the <head> section to handle the pagebeforeload event :

    $(document).bind("pagebeforeload", function(event, data) { var str = "<p>LOADING PAGE ...</p>" + "<p>url: " + data.url + "</p>" + "<p>absUrl : " + data.absUrl + "</p>" + "<p>dataUrl : " + data.dataUrl + "</p>" + "<p>options.type: " + data.options.type + "</p>"; var re = /page2.html/; if ( data.url.search(re) !== -1 ) { str += "<p>ABORTED!!! page2.html does not exist.</p>"; event.preventDefault(); data.deferred.reject( data.absUrl, data.options); } re = /page4.html/; if ( data.url.search(re) !== -1 ) { str += "<p>ABORTED!!! error dialog shown instead.</p>"; event.preventDefault(); data.deferred.resolve( data.absUrl, data.options, $("#subpage")); } $("#msgdiv").html(str).trigger("refresh"); });

  3. Next, handle the pageload event:

    $(document).bind("pageload", function(event, data) { var str = "<p>PAGE LOADED!</p><p>textStatus: " + data.textStatus + "</p><p>xhr.status : " + data.xhr.status + "</p>"; $("#msgdiv").append(str).trigger("refresh"); });

  4. Next, handle any error with the pageloadfailed event:

    $(document).bind("pageloadfailed", function(event, data) { var str = "<p>PAGE LOAD FAILED!</p>" + "<p>textStatus: " + data.textStatus + "</p>" + "<p>xhr.status : " + data.xhr.status + "</p>" + "<p>errorThrown : " + data.errorThrown + "</p>"; $("#msgdiv").append(str).trigger("refresh"); });

  5. Also handle the pageremove event:

    $("#page1").live("pageremove", function(event) { $("#msgdiv").append("<p>PAGE REMOVED!</p>").trigger("refresh"); });

  6. Now, create a dialog with id="dialog" as follows:

    <div id="dialog" data-role="dialog" data-theme="e" data-add-back- btn="true"> <div data-role="header"> <h1>Page Load Failed!</h1> </div> <div data-role="content"> <p>There was an error</p> </div> </div>

  7. Finally, create page1.html with a button to go back to #main, as shown in the following code snippet:

    <div id="page1" data-role="page" data-theme="e"> <div data-role="header"> <h1>Header of Page 1</h1> </div> <div data-role="content"> <a href="#" data-role="button" data- rel="back">Go to Main Page</a> </div> </div>

How it works...

In main.html, create the #main page and add four anchor links with the data-role="button" and data-inline="true" attributes, to create four inline buttons. These links point to page1.html, page2.html, page3.html, and page4.html. Also add an empty div container with id="msgdiv" to display the messages. Next, add a dialog with id="dialog" to main.html. Finally, create only page1.html, as shown, with a link to return back to the main page. The other three pages are not created. Bind the page load and page remove events to callback functions as given in the script. These callback functions have two parameters available. The first is the event object and the second is the data object.

In the callback of the pagebeforeload event, get the url , absUrl (absolute URL), dataUrl (the data URL), and options.type properties from the data object. Display them in the msgdiv container. The options object is the same that gets passed into the $.mobile.loadPage() call.

In the callback of the pageload event , get the xhr.status (the jQuery XMLHttpRequest object) and textStatus attributes that indicate page load success and display them in the msgdiv container.

Add the pageloadfailed callback function to display the data.xhr.status and data. errorThrown properties on page load error. Finally, add the pageremove callback function and display a message that the page was removed.

Now, when you initially load the app and click on the Page 1 button to open page1.html, the pagebeforeload event is triggered first, then the pageload event is fired after the page is fully loaded. Navigate back to the main page and this triggers the pageremove event. You can see these messages displayed, as shown in the following screenshot:

 

 

Next, in the pagebeforeload event handler , use a regular expression search to check whether the page requested or the data.url is page2.html (which does not exist). Display a custom error message if page2.html was requested. Also prevent any further action on this request by calling event.preventDefault(). The data.deferred.reject() method must be finally called to reject the deferred object reference contained in the data object. Now, when you click on the Page 2 button, the pageloadfailed event is not triggered, as shown in the following screenshot, and the custom error message ABORTED!!! page2.html does not exist. is displayed:

 

Click on the Page 3 button; it now tries to load page3.html, which is not present, and displays an Error Loading Page default error message overlaid on the current page, as shown in the following screenshot. You can also see the messages from the pageloadfailed event handler here. There was no custom event handling done in this case.

 

Finally, add code in the pagebeforeload callback function to search for page4.html in the data.url object. If the string was found, redirect the request to load the #dialog dialog. Also, display a custom message if page4.html was requested. Now, to prevent the default action on pagebeforeevent, call the event.preventDefault() method . You must also call the data.deferred.resolve() method to resolve the deferred object reference contained in the data object. Then, open the #dialog page by passing it as the parameter to the resolve method, as shown in the code. Now, when you click on the Page 4 button, the custom error dialog popup is displayed. When you close the dialog, your custom message ABORTED!!! error dialog shown instead. is displayed, as shown in the following screenshot. You will note that the pageloadfailed event callback function did not get called.

 

There's more...

If you prevent the default page load events by calling the event.preventDefault() method , then you must inform the framework to resume processing other changePage() requests once you are done. You can do this by calling the reject() or resolve() methods on the data.deferred object passed to the callback function of the event.

Page change events

The jQuery Mobile framework triggers page change events whenever a page is loaded by the $.mobile.changePage() method into the DOM. The pagebeforechange event is fired first, before the page changes. Then, either the pagechange event (on success) or the pagechangefailed event (on failure) is fired. This recipe shows you how to use the page change events.

Getting ready

Copy the full code of this recipe from the code/08/pagechange sources folder. You can launch this code using the URL http://localhost:8080/08/pagechange/main.html.

How to do it...

Carry out the following steps:

  1. Create main.html with two links to open two dialogs and an empty div element in its page content, as follows:

    <div id="content" data-role="content"> <a href="#dialog1" data-role="button">Dialog 1</a> <a href="#dialog2" data-role="button">Dialog 2</a> <div id="msgdiv"></div> </div>

  2. Add the following script to the <head> section to handle the pagebeforechange event:

    $(document).bind("pagebeforechange", function(event, data) { var str = "<p>CHANGING PAGE ...</p><p>toPage: "; str += (!!data.toPage.attr)? data.toPage.attr("data- url") : data.toPage; str += "</p>"; $("#msgdiv").html(str).trigger("refresh"); $("#dialogdiv").html(str).trigger("refresh"); });

  3. Next, handle the pagechange event:

    $(document).bind("pagechange", function(event, data) { var str = "<p>CHANGED PAGE ...</p><p>fromPage: "; str += (!!data.options.fromPage && !!data.options.fromPage. attr)? data.options.fromPage.attr("data-url") : "none"; str += "</p><p>options.transition: " + data.options.transition + "</p>"; $("#msgdiv").append(str).trigger("refresh"); $("#dialogdiv").append(str).trigger("refresh"); });

  4. Next, handle any error with the pagechangefailed event:

    $(document).bind("pagechangefailed", function(event, data) { var str = "<p>PAGE CHANGE FAILED ...</p>"; $("#msgdiv").append(str).trigger("refresh"); });

  5. Finally, create the #dialog1 dialog as follows. The second dialog, #dialog2 , is not created.

    <div id="dialog1" data-role="dialog" data-theme="e" data-add-back-btn="true"> <div data-role="header"> <h1>Dialog Header</h1> </div> <div data-role="content"> <div id="dialogdiv"></div> </div> </div>

How it works...

In main.html, add two anchor links with data-role="button" to the content of the #main page. These links point to the #dialog1 and #dialog2 dialogs. Also, add an empty div container with id="msgdiv" to display the messages. Finally, add only one dialog with id="dialog1" to main.html. Add an empty div container with id="dialogdiv" to this dialog. The other dialog is not created. Bind the page change events to the callback functions as given in the script. These call back functions have two parameters available. The first is the event object and the second is the data object.

In the callback of the pagebeforechange event, get the data.toPage (target page) attribute. This can either be a string or an object. Check if this is an object (if it has the toPage attribute) and then use the data.toPage.data-url string. Display the toPage message in both the message div containers.

In the callback of the pagechange event, get the data.fromPage (source page) attribute. Check again whether this is an object or a string and display the data.fromPage.data-url string if it is an object in both the message div containers. Also, the data.options object has properties, such as transition, that you can use.

Finally, in the callback for the pagechangefailed event, display a custom error message. When the page loads for the first time, you can see the following image. The text main is shown for toPage; there is no fromPage here:

 

Click on the Dialog 1 button and the following dialog box will be shown. The toPage value is dialog1 and fromPage is main. The transition that was used is shown as pop , which is the default transition for the dialog:

 

Close this dialog box, and the #main page opens , which displays a message similar to the one shown in the following screenshot. toPage is main and fromPage is dialog1. The transition used is again shown as pop :

 

Finally, click on Dialog 2 button; since #dialog2 does not exist, the custom error message PAGE CHANGE FAILED is shown, as you can see in the following screenshot, from the pagechangefailed callback:

There's more...

You can prevent the default page change action by calling the event.preventDefault() method in the pagebeforechange event handler. You can redirect the navigation to another page here using the $.mobile.changePage() method.

Sequence of pagechange event

After the pagebeforechange event is triggered, the changePage() request loads the page into the DOM, and then the transition of the page occurs. The pageshow and pagehide events are triggered at this point. Finally, the pagechange event is fired only after this.

Page transition and animation events

During page navigation, the current page transitions out and the new active page transitions in. Animation is used where supported. The jQuery Mobile framework triggers four page transition events during page navigation, which are listed as follows:

  • pagebeforehide: This event is triggered before the current page is hidden

  • pagehide : This event is fired once the current page is hidden

  • pagebeforeshow: This event is fired before the new active page is shown

  • pageshow : This event is triggered once the active page is shown

You can also access the animationComplete plugin to perform custom actions as soon as the animation is completed. This recipe shows you how to use the page transition events and also how to use the animationComplete plugin.

Getting ready

Copy the full code of this recipe from the code/08/transition sources folder. You can launch this code using the URL http://localhost:8080/08/transition/main.html.

How to do it...

Carry out the following steps:

  1. Create main.html, and add #main page with a link to open the #page page and an empty div container, as shown in the following code snippet:

    <div id="main" data-role="page" data-theme="e"> <div data-role="header"> <h1>Page Transition and Animation Events</h1> </div> <div id="content" data-role="content"> <a href="#page" data-role="button" data- transition="slide">Page 1</a> <div id="msgdiv"></div> </div>

  2. Create the #page page, as follows, with a button to go back to #main and an empty div container to display messages:

    <div id="page" data-role="page" data-theme="e"> <div data-role="header"> <h1>Page Header</h1> </div> <div data-role="content"> <a href="#" data-rel="back" data-role="button">Go Back</a> <div id="pagediv"></div> </div>

  3. Add the following script to the <head> section, to clear the message div containers whenever a link is clicked:

    $("#main").live("pageinit", function(event) { $("a").bind("click", function(event, ui) { $("#msgdiv").html(""); $("#pagediv").html(""); }); });

  4. Handle the pagebeforeshow event:

    $(document).bind("pagebeforeshow", function(event, data) { var str = "<p>BEFORE PAGE SHOW ...</p><p>Previous Page: "; str += (!!data.prevPage.attr)? data.prevPage.attr("data-url") : "none"; str += "</p>"; $("#msgdiv").append(str).trigger("refresh"); $("#pagediv").append(str).trigger("refresh"); });

  5. Handle the pagebeforehide event:

    $(document).bind("pagebeforehide", function(event, data) { $(data.nextPage).animationComplete(anim); var str = "<p>BEFORE PAGE HIDE ...</p><p>Current Page: "; str += (!!data.nextPage.attr)? data.nextPage.attr("data-url") : "none"; str += "</p>"; $("#msgdiv").append(str).trigger("refresh"); $("#pagediv").append(str).trigger("refresh"); });

  6. Handle the pageshow event:

    $(document).bind("pageshow", function(event, data) { var str = "<p>PAGE SHOW!</p><p>Previous Page: "; str += (!!data.prevPage.attr)? data.prevPage.attr("data-url") : "none"; str += "</p>"; $("#msgdiv").append(str).trigger("refresh"); $("#pagediv").append(str).trigger("refresh"); });

  7. Handle the pagehide event:

    $(document).bind("pagehide", function(event, data) { var str = "<p>PAGE HIDE!</p><p>Current Page: "; str += (!!data.nextPage.attr)? data.nextPage.attr("data-url") : "none"; str += "</p>"; $("#msgdiv").append(str).trigger("refresh"); $("#pagediv").append(str).trigger("refresh"); });

  8. Add the callback function for the animationComplete() method :

    anim = function() { $("#msgdiv").append("ANIMATION DONE!!!").trigger("refresh"); $("#pagediv").append("ANIMATION DONE!!!").trigger("refresh"); }

How it works...

Create main.html and add an anchor link with data-role="button" to the content of the #main page. This link opens the #page page in main.html. Create the #page page, as shown with a link to go back to #main. Add empty #msgdiv and #pagediv containers to the pages respectively, to display messages. Bind the click event of the anchor link in the pageinit event handler , and clear any previously displayed messages. This callback is triggered whenever you click on the links in the app.

Now, bind the four page transition events to their callback functions as given in the script. These callback functions have two parameters available. The first is the event object and the second is the data object.

In the callback of the pagebeforeshow event, get the data.prevPage (previous page) object. This can be empty on first load. Check if it is available (if it has the prevPage attribute) and use the data.prevPage.data-url string. Display the prevPage message in both the message div containers. Use similar logic in the callback for the pagehide event.

Similarly, in the callback of the pagebeforehide and pagehide events, obtain and display the data.toPage (source page) property. Finally, invoke the animationComplete plugin and de fine the anim callback function, as shown in the pagebeforehide event handler. Write code in the anim() function to display a simple ANIMATION DONE!!! message in both the div containers, as shown.

When the page loads for the first time, you can see the following image with the pagebeforeshow and pageshow event handlers being called. prevPage is undefined at this point of time.

 

 

Click on the Page 1 button to open #page . You can see messages from the pagebeforehide and pagebeforeshow event handlers saying that Current Page is page and Previous Page is main. Then, you can see the ANIMATION DONE!!! message from the animationComplete() callback. The page is visible at this point, and the messages from the pagehide and pageshow events can also be seen:

 

 

Click on the Go Back button. Now, #main is shown and the messages are displayed as before. This time, Current Page is main and Previous Page is page:


 

There's more...

On first load, the pagebeforeshow and pageshow event handlers show an empty data.nextPage object. To display proper values on first load, these two events must be bound to their callback functions in the mobileinit handler, when the page loads and before loading the jquery.mobile.js script file, as shown in the following code snippet:

<script> $(document).bind("mobileinit", function() { $(document).bind("pagebeforeshow", function(event, data) { alert(data.nextPage); }); $(document).bind("pageshow", function(event, data) { alert(data.nextPage); }); }); </script> <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="http://code.jquery.com/mobile/1.1.1/jquery.mobile- 1.1.1.min.js"></script>

Summary

In this article, we have discussed page initialization events, page load and remove events, page change events, and page transition and animation events.

Resources for Article :


Further resources on this subject:


About the Author :


Chetan K Jain

Chetan K Jain loves to code, and has been writing code for over 16 years now. He is a Senior Architect, and has worked on mobile technologies for over 4 years for Nokia. Since then, he has moved on to work as a freelance consultant.

Chetan has significant experience in writing cross-platform mobile apps using jQuery Mobile, HTML5, CSS3, JavaScript, Nodejs, and has also worked extensively on Qt. Prior to mobile technologies, he has worked with Java technology and was also certified as an MCSD and MCSE in his early days.

Chetan is an active contributor to open source development, and tries to help jQuery Mobile development whenever he can. He regularly participates in developer forums, and was earlier a top-ranked member and a "mad scientist" in the Nokia Qt Developer Forum.

Chetan was born in Bangalore and lives there with his wife Shwetha and son Tanmay.

The only time he ventured to live away from Bangalore was when he worked for over 4 years in the USA. His adventure didn't end there. He did a solo US cross country drive in his two door coupe from the east coast to the west and back, driving alone for over 8000 plus miles in 16 days to experience and live life as he calls it. His travelogue can be found at http://adventure.chetankjain.net.

Chetan has contributed and published over 15 books to Gutenberg as a volunteer. He has also published four books on Jaina Literature and History written by his mother Saraswathamma. He is a voracious reader, and his other interests include music, movies, and travelling. Photography is his favorite hobby, and his clicks can be found at http://www.facebook.com/chetankjainphotos/photos_stream.

Chetan can be reached at chetankjain@gmail.com. He also blogs at http://dev.chetankjain.net.

Books From Packt


jQuery 1.4 Reference Guide
jQuery 1.4 Reference Guide

Learning jQuery, Third Edition
Learning jQuery, Third Edition

jQuery Plugin Development Beginner's Guide
jQuery Plugin Development Beginner's Guide

jQuery Mobile Web Development Essentials
jQuery Mobile Web Development Essentials

jQuery Mobile First Look
jQuery Mobile First Look

jQuery UI 1.8: The User Interface Library for   jQuery
jQuery UI 1.8: The User Interface Library for jQuery

jQuery Tools UI Library
jQuery Tools UI Library

jQuery for Designers: Beginner’s Guide
jQuery for Designers: Beginner’s Guide


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
u
X
8
Z
R
f
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software