You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<h2>jQuery Mobile and Dynamic Page Generation</h2>
26
-
<p>jQuery Mobile allows pages to be pulled into the DOM dynamically via its default click hijacking behavior, or through manual calls to $.mobile.changePage(). This is great for applications that generate HTML pages/fragments on the server-side, but there are sometimes cases where an application needs to dynamically generate page content on the client-side from JSON or some other format. This may be necessary for bandwidth/performance reasons, or because it is the data format of choice for the server they are interacting with.</p>
27
-
<p>For applications that need to generate page markup on the client-side, it's important to know about the notifications that are triggered during a $.mobile.changePage() call because they can be used as hooks into the navigation system that will allow you to generate your content at the appropriate time.</p>
28
-
<p>A call to changePage() will usually trigger the following event notifications:</p>
26
+
<p>jQuery Mobile allows pages to be pulled into the DOM dynamically via its default click hijacking behavior, or through manual calls to <code>$.mobile.changePage()</code>. This is great for applications that generate HTML pages/fragments on the server-side, but there are sometimes cases where an application needs to dynamically generate page content on the client-side from JSON or some other format. This may be necessary for bandwidth/performance reasons, or because it is the data format of choice for the server they are interacting with.</p>
27
+
<p>For applications that need to generate page markup on the client-side, it's important to know about the notifications that are triggered during a <code>$.mobile.changePage()</code> call because they can be used as hooks into the navigation system that will allow you to generate your content at the appropriate time.</p>
28
+
<p>A call to <code>changePage()</code> will usually trigger the following event notifications:</p>
29
29
<ul>
30
-
<li>pagebeforechange
30
+
<li><code>pagebeforechange</code>
31
31
<ul>
32
32
<li>Fired off before any page loading or transition.</li>
33
33
<li>NOTE: This event was formerly known as "beforechangepage".</li>
34
34
</ul>
35
35
</li>
36
-
<li>pagechange
36
+
<li><code>pagechange</code>
37
37
<ul>
38
38
<li>Fired off after all page loading and transitions.</li>
39
39
<li>NOTE: this event was formerly known as "changepage".</li>
40
40
</ul>
41
41
</li>
42
-
<li>pagechangefailed
42
+
<li><code>pagechangefailed</code>
43
43
<ul>
44
44
<li>Fired off if an error has occurred while attempting to dynamically load a new page. </li>
45
45
</ul>
46
46
</li>
47
47
</ul>
48
-
<p>These notifications are triggered on the parent container element ($.mobile.pageContainer) of pages, and will bubble all the way up to the document element and window.</p>
49
-
<p>For applications wishing to inject pages, or radically modify the content of an existing page, based on some non-HTML data, such as JSON or in-memory JS object, the pagebeforechange event is very useful since it gives you a hook for analyzing the URL or page element the application is being asked to load or switch to, and short-circuit the default changePage() behavior by simply calling preventDefault() on the pagebeforechange event.</p>
48
+
<p>These notifications are triggered on the parent container element (<code>$.mobile.pageContainer</code>) of pages, and will bubble all the way up to the document element and window.</p>
49
+
<p>For applications wishing to inject pages, or radically modify the content of an existing page, based on some non-HTML data, such as JSON or in-memory JS object, the <code>pagebeforechange</code> event is very useful since it gives you a hook for analyzing the URL or page element the application is being asked to load or switch to, and short-circuit the default <code>changePage()</code> behavior by simply calling <code>preventDefault()</code> on the <code>pagebeforechange</code> event.</p>
50
50
<p>To illustrate this technique, take a look at this <ahref="dynamic-samples/sample-reuse-page.html" rel="external">working sample</a>. In this sample, the main page starts off with a list of categories that the user can navigate into. The actual items in each category are stored in a JavaScript object in memory, for illustrative purposes, but the data can really come from anywhere.</p>
51
51
<pre><code>
52
52
var categoryData = {
@@ -120,8 +120,8 @@ <h2>jQuery Mobile and Dynamic Page Generation</h2>
120
120
</ul>
121
121
</code>
122
122
</pre>
123
-
<p>Internally, when the user clicks on one of these links, the application intercepts the internal $.mobile.changePage() call that is invoked by the frameworks' default link hijacking behavior. It then analyzes the URL for the page about to be loaded, and then decides whether or not it should handle the loading itself, or to let the normal changePage() code handle things.</p>
124
-
<p>The application was able to insert itself into the changePage() flow by binding to the "pagebeforechange" event at the document level:</p>
123
+
<p>Internally, when the user clicks on one of these links, the application intercepts the internal <code>$.mobile.changePage()</code> call that is invoked by the frameworks' default link hijacking behavior. It then analyzes the URL for the page about to be loaded, and then decides whether or not it should handle the loading itself, or to let the normal <code>changePage()</code> code handle things.</p>
124
+
<p>The application was able to insert itself into the <code>changePage()</code> flow by binding to the <code>pagebeforechange</code> event at the document level:</p>
125
125
<pre>
126
126
<code>
127
127
// Listen for any attempts to call changePage().
@@ -153,24 +153,24 @@ <h2>jQuery Mobile and Dynamic Page Generation</h2>
153
153
</code>
154
154
</pre>
155
155
<p>So why listen at the document level? In short, because of deep-linking. We need our binding to be active before the jQuery Mobile framework initializes and decides how to process the initial URL that invoked the application.</p>
156
-
<p>When the callback for the "pagebeforechange" binding is invoked, the 2nd argument to the callback will be a data object that contains the arguments that were passed to the initial $.mobile.changePage() call. The properties of this object are as follows:</p>
156
+
<p>When the callback for the <code>pagebeforechange</code> binding is invoked, the 2nd argument to the callback will be a data object that contains the arguments that were passed to the initial <code>$.mobile.changePage()</code> call. The properties of this object are as follows:</p>
157
157
<ul>
158
-
<li>toPage
158
+
<li><code>toPage</code>
159
159
<ul>
160
-
<li>Can be either a jQuery collection object containing the page to be transitioned to, *OR* a URL reference for a page to be loaded/transitioned to.</li>
160
+
<li>Can be either a jQuery collection object containing the page to be transitioned to, <b>OR</b> a URL reference for a page to be loaded/transitioned to.</li>
161
161
</ul>
162
162
</li>
163
163
<li>options
164
164
<ul>
165
-
<li>Object containing the options that were passed in by the caller of the $.mobile.changePage() function.</li>
165
+
<li>Object containing the options that were passed in by the caller of the <code>$.mobile.changePage()</code> function.</li>
166
166
<li>A list of the options can be found <ahref="../api/methods.html">here</a>.</li>
167
167
</ul>
168
168
</li>
169
169
</ul>
170
-
<p>For our sample application, we are only interested in changePage() calls where URLs are initially passed in, so the first thing our callback does is check the type for the toPage. Next, with the help of some URL parsing utilities, it checks to make sure if the URL contains a hash that we are interested in handling ourselves. If so, it then calls an application function called showCategory() which will dynamically create the content for the category specified by the URL hash, and then it calls preventDefault() on the event.</p>
171
-
<p>Calling preventDefault() on a pagebeforechange event causes the originating $.mobile.changePage() call to exit without performing any work. Calling the preventDefault() method on the event is the equivalent of telling jQuery Mobile that you have handled the changePage() request yourself.</p>
172
-
<p>If preventDefault() is not called, changePage() will continue on processing as it normally does. One thing to point out about the data object that is passed into our callback, is that any changes you make to the toPage property, or options properties, will affect changePage() processing if preventDefault() is not called. So for example, if I wanted to redirect or map a specific URL to another internal/external page, my callback could simply set the data.toPage property in the callback to the URL or DOM element of the page to redirect to. Likewise, I could set, or un-set any option from within my callback, and changePage() would use the new settings.</p>
173
-
<p>So now that we know how to intercept changePage() calls, let's take a closer look at how this sample actually generates the markup for a page. Our example actually uses, or I should say, re-uses the same page to display each of the categories. Each time one of our special links is clicked, the function showCategory() gets invoked:</p>
170
+
<p>For our sample application, we are only interested in <code>changePage()</code> calls where URLs are initially passed in, so the first thing our callback does is check the type for the <code>toPage</code>. Next, with the help of some URL parsing utilities, it checks to make sure if the URL contains a hash that we are interested in handling ourselves. If so, it then calls an application function called <code>showCategory()</code> which will dynamically create the content for the category specified by the URL hash, and then it calls <code>preventDefault()</code> on the event.</p>
171
+
<p>Calling <code>preventDefault()</code> on a <code>pagebeforechange</code> event causes the originating <code>$.mobile.changePage()</code> call to exit without performing any work. Calling the <code>preventDefault()</code> method on the event is the equivalent of telling jQuery Mobile that you have handled the <code>changePage()</code> request yourself.</p>
172
+
<p>If <code>preventDefault()</code> is not called, <code>changePage()</code> will continue on processing as it normally does. One thing to point out about the data object that is passed into our callback, is that any changes you make to the <code>toPage</code> property, or options properties, will affect <code>changePage()</code> processing if <code>preventDefault()</code> is not called. So for example, if we wanted to redirect or map a specific URL to another internal/external page, our callback could simply set the <code>data.toPage</code> property in the callback to the URL or DOM element of the page to redirect to. Likewise, we could set, or un-set any option from within our callback, and <code>changePage()</code> would use the new settings.</p>
173
+
<p>So now that we know how to intercept <code>changePage()</code> calls, let's take a closer look at how this sample actually generates the markup for a page. Our example actually uses, or we should say, re-uses the same page to display each of the categories. Each time one of our special links is clicked, the function <code>showCategory()</code> gets invoked:</p>
174
174
<pre><code>
175
175
// Load the data for a specific category, based on
176
176
// the URL passed in. Generate markup for the items in the
@@ -251,10 +251,10 @@ <h2>jQuery Mobile and Dynamic Page Generation</h2>
251
251
<pre><code>
252
252
#category-items?category=vehicles
253
253
</code></pre>
254
-
<p>The first part, before the '?' is actually the id of the page to write content into, the part after the '?' is info the app uses to figure out what data it should use when generating the markup for the page. The first thing showCategory() does is deconstruct this hash to extract out the id of the page to write content into, and the name of the category it should use to get the correct set of data from our in-memory JavaScript category object. After it figures out what category data to use, it then generates the markup for the category, and then injects it into the header and content area of the page, wiping out any other markup that previously existed in those elements.</p>
254
+
<p>The first part, before the '?' is actually the id of the page to write content into, the part after the '?' is info the app uses to figure out what data it should use when generating the markup for the page. The first thing <code>showCategory()</code> does is deconstruct this hash to extract out the id of the page to write content into, and the name of the category it should use to get the correct set of data from our in-memory JavaScript category object. After it figures out what category data to use, it then generates the markup for the category, and then injects it into the header and content area of the page, wiping out any other markup that previously existed in those elements.</p>
255
255
<p>After it injects the markup, it then calls the appropriate jQuery Mobile widget calls to enhance the list markup it just injected. This is what turns the normal list markup into a fully styled listview with all its behaviors.</p>
256
-
<p>Once that's done, it then calls $.mobile.changePage(), passing it the DOM element of the page we just modified, to tell the framework that it wants to show that page.</p>
257
-
<p>Now an interesting problem here is that jQuery Mobile typically updates the browser's location hash with the URL associated with the page it is showing. Because we are re-using the same page for each category, this wouldn't be ideal, because the URL for that page has no specific category info associated with it. To get around this problem, showCategory() simply sets the dataUrl property on the options object it passes into changePage() to tell it to display our original URL instead.</p>
256
+
<p>Once that's done, it then calls <code>$.mobile.changePage()</code>, passing it the DOM element of the page we just modified, to tell the framework that it wants to show that page.</p>
257
+
<p>Now an interesting problem here is that jQuery Mobile typically updates the browser's location hash with the URL associated with the page it is showing. Because we are re-using the same page for each category, this wouldn't be ideal, because the URL for that page has no specific category info associated with it. To get around this problem, <code>showCategory()</code> simply sets the <code>dataUrl</code> property on the options object it passes into <code>changePage()</code> to tell it to display our original URL instead.</p>
258
258
<p>That's the sample in a nutshell. It should be noted that this particular sample and its usage is not a very good example of an app that degrades gracefully when JavaScript is turned off. That means it probably won't work very well on C-Grade browsers. We will be posting other examples that demonstrate how to degrade gracefully in the future. Check this <ahref="http://jquerymobile.com/test/docs/pages/dynamic-samples/">page</a> for updates.</p>
0 commit comments