Dynamically create jQuery Mobile page via JavaScript after clicking

33,842

Solution 1

I had some time to mess around with this and I've found a solution that works (tested).

SOME NOTES:

  1. 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).
  2. The function, create_page(page_id) is for creating a page from a link (or programatically if you like).
  3. 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.
  4. 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:

  1. 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-->
    
  2. 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 :)

Share:
33,842
Witek
Author by

Witek

Updated on July 09, 2022

Comments

  • Witek
    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 for startPage via JavaScript and add the content to it. I have created a createStartPage(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
    Witek about 13 years
    This 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
    Witek about 13 years
    This 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
    Jasper about 13 years
    create_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
    SharpC over 4 years
    This is a much better solution.