Page Events

jQuery Mobile Cookbook


November 2012

$10.00

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

(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>

 

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="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:


Books to Consider

comments powered by Disqus