With today's dynamic systems getting them to load properly is always a challenge.  Especially if you have content loaded via Ajax after the initial load.  This can be the hardest part.  Even more so, things like jQuery Mobile make it even harder.  This is because jQuery Mobile rewrites the html that is initially loaded to be styled and work properly. 

So, lets take a basic example and figure out how to style some ajax loaded content.

Lets look at a basic example of some jQuery Mobile page. Not thing fancy here, this just creates a basic page with a header and footer with some minor content.

view plain print about
1<!DOCTYPE html>
2<html>
3    <head>
4    <title>Page Title</title>
5    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
6    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
7    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>
8</head>
9<body>
10
11<div data-role="page">
12
13    <div data-role="header" >
14        <h1>Mail Reader</h1>
15    </div><!-- /header -->
16
17    <div data-role="content">    
18        
19        <div class="ui-grid-a">
20            <div class="ui-block-a" style="width: 25%;'">                
21                <ul data-role="
listview" data-inset="true">
22                    <li data-role="
list-divider">My Email</li>
23                    <li><a href="
test.cfm" id="LoadInDiv" rel="external" class="linkDiv">Inbox</a></li>
24                    <li><a href="
test2.cfm" id="LoadInDiv2" rel="external" class="linkDiv">Outbox</a></li>
25                    <li data-role="
list-divider">Other</li>
26                    <li><a href="
index.html">Feeds</a></li>
27                </ul>
28            </div>
29            <div class="
ui-block-b" style="width: 72%; padding-left: 20px;" id="contentDiv">
30            
31            </div>
32        </div>
33    </div><!-- /content -->
34
35    <div data-role="
footer">
36        <div data-role="
navbar">
37            <ul>
38                <li><a href="
#">Summary</a></li>
39                <li><a href="
#" class="ui-btn-active">Favs</a></li>
40                <li><a href="
#">Setup</a></li>
41            </ul>
42        </div><!-- /navbar -->
43    </div><!-- /footer -->
44</div><!-- /page -->
45</body>
46</html>

 

Rendered it looks like this:

 

So now lets take the base and put a little JavaScript in to it.  This script will handle the click and load some external content.

view plain print about
1<script language="JavaScript">
2$(function(){
3    $('.linkDiv').click(function(event) {        
4        $('#contentDiv').load($(this).attr('href'));
5        return false;
6    });
7});
8</script>

The return from the load call contains this:

view plain print about
1<ul data-role="listview" data-inset="true" data-theme="e">
2    <li><a href="index.html">This could be a subject</a> <span class="ui-li-count">12</span></li>
3    <li><a href="index.html">This could be a subject</a> <span class="ui-li-count">0</span></li>
4    <li><a href="index.html">This could be a subject</a> <span class="ui-li-count">0</span></li>
5    <li><a href="index.html">This could be a subject</a> <span class="ui-li-count">0</span></li>
6    <li><a href="index.html">This could be a subject</a> <span class="ui-li-count">0</span></li>
7    <li><a href="index.html">This could be a subject</a> <span class="ui-li-count">0</span></li>
8</ul>

When rendered I now get this:

Obviously this is wrong.  The returned content has no styling or any "jQuery Mobile" magic in it.  Even the number is off on the far right.

This happens because jQuery Mobile does not know to style the content. It is not that it can't, it just doesn't know it should.  The content is pulled in after the styling has been applied.  So, the question is, How can I get jQuery Mobile to apply its secret sauce to the loaded content?

Well, this was no simple task.  I tried more things than I can count. Had many more failures than I would have liked to.  At one point I got it to work fairly easily. However, subsequent loads would break the UI.  I finally ran across a forum entry that I pieced together with other findings that gave me enough info to create a solution. 

The first thing was not not use load. Load, while a great way to get content into something was not the right way to go here.  What I I needed was to get the content and store it in a var.  Then I had to "coherse" jQuery Mobile into doing it's magic.

So, a simple modification to the JS and I get the magic I am looking for.

view plain print about
1<script language="JavaScript">
2     $(function(){    
3        $('.linkDiv').click(function(event) {
4            $.get($(this).attr('href'), function(data) {
5                $('#contentDiv').html(data).page();
6                $( "div[data-role=page]" ).page( "destroy" ).page();
7            });
8            return false;
9        });
10    });
11</script>

So what is the big change?  Well, I replaced the load with get.  This allowed me to store the result in a var.  I could then take that return and put it into the div.  Yes, load does that for me in one line.  However, adding the ".page()" to the load chain had no effect.  This way the page() worked. However, to be honest, I have no idea what the page() function does.  I just know it has to be there. The next part of the magic sauce was the next line.  Now just like the page function, I have no idea what this does either.  All I know is that these two lines of code allow me to produce the result below.

 

 

Well, there you have it.  A few magic beans and BOOM.

 

Till next time,

 

--Dave