Dynamically create jQuery Mobile page via JavaScript after clicking
Solution 1
I had some time to mess around with this and I've found a solution that works (tested).
SOME NOTES:
- the javascript encapsulated in $(document).ready(); is for dynamically creating a page if the user navigates to your index.html file with a hash mark already appended (i.e. index.html#some_hash_mark).
- The function, create_page(page_id) is for creating a page from a link (or programatically if you like).
- Note that the jquery core script and the jquery mobile css are loaded before the $(document).ready() statement but that the jquery mobile script is loaded after.
- See that the body tag has been given an id that is refrenced when appending pages to it.
Document Sample
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css"/>
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
//check if hash exists and that it is not for the home screen
if (window.location.hash != '' && window.location.hash != '#page_0') {
//set whatever content you want to put into the new page
var content_string = 'Some ' + window.location.hash + ' text...<br><br><a href="#page_0">go to home screen</a>';
//append the new page onto the end of the body
$('#page_body').append('<div data-role="page" id="' + window.location.hash.replace('#','') + '"><div data-role="content">' + content_string + '</div></div>');
//add a link on the home screen to navaigate to the new page (just so nav isn't broken if user goes from new page to home screen)
$('#page_0 div[data-role="content"]').append('<br><br><a href="#' + window.location.hash.replace('#','') + '">go to ' + window.location.hash.replace('#','') + ' page</a>');
}
});
function create_page(page_id) {
//set whatever content you want to put into the new page
var string = 'FOO BAR page...<br><br><a href="#page_0">return to home screen</a>';
//append the new page onto the end of the body
$('#page_body').append('<div data-role="page" id="' + page_id + '"><div data-role="content">' + string + '</div></div>');
//initialize the new page
$.mobile.initializePage();
//navigate to the new page
$.mobile.changePage("#" + page_id, "pop", false, true);
//add a link on the home screen to navaigate to the new page (just so nav isn't broken if user goes from new page to home screen)
$('#page_0 div[data-role="content"]').append('<br><br><a href="#' + page_id + '">go to ' + page_id + ' page</a>');
//refresh the home screen so new link is given proper css
$('#page_0 div[data-role="content"]').page();
}
</script>
<title>Fixed Headers Example</title>
<script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
</head>
<body id="page_body">
<div data-role="page" id="page_0">
<div data-role="content">Some #page_0 text...<br><br><a href="javascript: create_page('foo_bar_page');">create new page</a></div>
</div>
</body>
</html>
Solution 2
To me Jasper solution doesn't work but i've found this solution that look cleaner and work fine
Solution 3
Here is my method for dynamically adding content to my Jquery Mobile websites:
-
First I create a "wrapper" data-role=page div like so:
<div data-role="page" id="my_page_id"> <div data-role="content"> <script> $('#my_page_id').live('pageshow', function() { my_data_loading_function('my_page_id'); }); </script> <div id="my_page_id-content"></div> </div><!--/content--> </div><!--/page-->
-
Next I load data from an external source into a div tag located in my "wrapper" page:
function my_data_loading_function(page) { if ($('#' + page + '-content').is(':empty')) { $.mobile.pageLoading(); $('#' + page + '-content').load("my_external_script.php", function() { $.mobile.pageLoading(true); $('#' + page + '-content ul').listview(); $('#' + page + '-content ul').page(); }); } }
Some Notes:
$.mobile.pageLoading(); and $.mobile.pageLoading(true); show and hide (respectively) the Jquery Mobile loading spinner.
if ($('#' + page + '-content').is(':empty')) { allows the user to navaigate away from the dynamically created page and then come back and not have to re-load the data until a full page refresh occurs.
My dynamically created page included mostly a list so listview() makes the jquery mobile framework refresh the list selected to add the proper css, page() does the same to other page elements; however you may only need to use one or the other depending on your content (or none at all if its just plain text).
-
I realize this isn't creating a whole page dynamically because the "wrapper" page is already hard-coded but if you want to add a whole new page you can probably use something like: (untested)
$(document).append('<div data-role="page" id="my_page_id"><div data-role="content">FOO BAR</div></div>'); $('#my_page_id').page();
If you really want to make it all dynamically created you can check for window.location.hash and create your data-role=page div with the id set as the window.location.hash.
Also I am using Jquery 1.6 and Jquery Mobile 1.0a4.1
I hope something in there can help someone out there :)
Witek
Updated on July 09, 2022Comments
-
Witek almost 2 years
My jQuery Mobile app consists of a single
index.html
page and contains only one page with a link on startup:<div data-role="page"> <div data-role="content"> <a id="startPageLink" href="startPage">start</a> </div> </div>
When the user clicks on the start link, I want to load the content for the
startPage
from my JSON api asynchronously. On the callback I would like to create all the required DOM elements forstartPage
via JavaScript and add the content to it. I have created acreateStartPage(data)
method for this.What is the right way to implement such dynamically created pages, so that opening
index.html#startPage
also works? I think there should be a way to hook into$.mobile.changePage()
to include custom loading/page-creation code, but I did not find anything. Or is there a better solution for this problem? -
Witek about 13 yearsThis solves the problem how to start with a specific, dynamic page. Thank you. But how to create additional pages on demand (after clicking a <li><a>)?.
-
Witek about 13 yearsThis solution still requires that all the page wrappers exist, before clicking the link. But I have potentially thousands of links, which go to thousands of different pages. Isn't there a way not to create thousands of unused pages?
-
Jasper about 13 yearscreate_page(page_id)... its a function for creating a page from a link. It creates the page, initializes it, then forwards the user to the new page. The specific function I wrote above also creates a link on the homepage so if the user back-tracks to the homepage they can again go forward to the newly created page. This was documented under NOTE #2.
<li><a href="javascript:create_page('page_id_here');">link text</a></li>
-
SharpC over 4 yearsThis is a much better solution.