I have page1 which is index.html, it a self-contained website includes header and scripts ect. I have a button on this page that when clicked will load page2 via ajax and insert page2 into page1. Page2 is just the div data-role="page" and html within it, its not a self-contained page. However, the url changes to page2.html and then if I "refresh" the page it doesn't load a complete page because page2 is not a full page, it was only ment to be injected into page1.
I tried setting the data-url="index.html&dashboard" (dashboard is the main id on page2) and in this case the url looks correct as it is still index.html&dashboard so a page refresh reloads page1 even if you were on page2. But now, jquery freaks out and sits on a loading screen forever because it can't find "dashboard" because that content was only added after the user clicked a button.
How do I work around this?
Thanks.
page1 index.html
<!DOCTYPE HTML>
<html>
<head>
<title>title</title>
<script><script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.mobile.js"></script>
<script type="text/javascript" charset="utf-8" src="js/global.js"></script>
<script type="text/javascript" charset="utf-8" src="js/login.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.mobile.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.mobile.js"></script>
<script type="text/javascript" charset="utf-8" src="js/login.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.mobile.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body>
<div data-role="page" data-theme="b">
<div data-role="header" data-theme="b">
<h1>Login</h1>
</div>
<!-- /header -->
<div data-role="content">
<div class="row">
<label for="login_name">Login Name:</label> <input
class="ui-input-text" type="text" name="login_name" id="login_name" />
</div>
<div class="row">
<label for="basic">Password:</label> <input class="ui-input-text"
type="password" name="password" id="password" />
</div>
<div class="row">
<input type="checkbox" name="remember" id="remember" class="custom"
data-mini="true" /> <label for="remember">Remember Me</label>
</div>
<div class="row">
<input type="submit" id="submit" name="submit" value="Submit" />
</div>
</div>
<!-- /content -->
</div>
<!-- /page -->
</body>
</html>
page2 dashboard.html
<div id="dashboard" data-role="page" data-theme="b" data-url="index.html&dashboard">
<div data-role="header" data-theme="b">
<h1 id="page_title">Dashboard</h1>
</div>
login.js
$(function() {
$("#submit").click(function() {
if ($("#login_name").val() == "") {
alert("Please enter a login name");
return false;
}
if ($("#password").val() == "") {
alert("Please enter a password");
return false;
}
$.post(URL + 'login', {
'APIKEY' : APIKEY,
'login' : $("#login_name").val(),
'password' : $("#password").val()
}, function(data) {
if (data.error == "") {
$.mobile.changePage("dashboard.html", { transition : "slide" });
} else {
alert(data.error);
}
}, "json");
});
});
Best Answer
Short Answer
The short answer is that jQuery Mobile expects you to use the hash to represent the state of a single page:
Instead, you are loading a completely new page when you should be just calling JavaScript to dynamically change the content on the first page to represent the second page.
If the short answer makes sense, great! If not, the long answer is incredibly detailed and describes two ways you can approach this problem.
Long Answer
What you are essentially asking is how to build a multiple page mobile website and have both pages be accessible by the URI that identifies the resource.
There are two methods you could use to tackle this problem.
Multi-Page Templates:
For jQuery mobile, this is accomplished with the jQuery Mobile Multi-page Template.
The general idea is that both of your pages are in the same HTML document, like so:
Next, what jQuery Mobile essentially does is it uses CSS to hide the DIV element with the id="two" and only show the div with the id="one". When the user clicks on the hyperlink with the `href="#two", there is a listener that intercepts the hashChange event and fires some JavaScript code that hides the DIV with id="one" and shows the DIV with id="two".
This makes the page transitions appear extremely smooth and fast, without needing to make a trip to the server to get the HTML markup.
Dynamically Intected Content:
If your data is more dynamic, then another option is to use the jQuery Mobile Dynamic Page Injection. The general premise to this process is similar to the Multi-Page Templates in that the browser listens for the hashChange event, except in addition to changing pages, it also makes an AJAX request to the server to retrieve JSON content.
When the category "Animals" is clicked on, the id="home" DIV is hidden. Instead of reloading the page, in this example, the HTML is being dynamically generated and populated with the results of a JSON object.
Here is the code that handles displaying the correct content:
Note that also, when looking at the URL for the Category page and the Animals page, you can see that the HTML document is the same each time. The difference is the hash value.
http://jquerymobile.com/demos/1.1.0/docs/pages/dynamic-samples/sample-reuse-page.html
http://jquerymobile.com/demos/1.1.0/docs/pages/dynamic-samples/sample-reuse-page.html#category-items?category=animals
When the page loads, the hash value is used to represent the state of the page. Since the browser is mostly stateless, the hash is one trick that is available to us to help determine what state a page should be displayed to the user.
Just compare your changePage method call with the URL's that are used in the menu in the Category page:
Note how the only thing that changes when a user clicks a link is the hashvalue, the page is never reloaded. But in your example, you're actually loading an entirely new page:
Logically speaking, you need to rethink your strategy for how you represent your pages. To make the most use of jQuery Mobile, think of your first HTML page as a frame for all of your CSS, JavaScript, and static content.
Afterwards, any resources you request should be identified by a URL with that same page followed by a hashvalue.
For example, if your static page is "index.html", then your dashboard might be "index.html#dashboard". You could also either include the dashboard HTML in an id="dashboard" DIV and dynamically populate it with data from the server, or you could load the HTML and data in via AJAX.
The second point is that anyone accessing your dashboard directly would need to visit "/index.html#dashboard", which would load your original page, fire some JavaScript that would check the hash, recognize it contains "dashboard", and then make the transition to the dashboard page by pulling back in the dynamic data.
For more information, see the jQuery Page Dynamic Documentation.