Oliver Spryn
Oliver Spryn

Reputation: 17348

jQuery Mobile Internal Pages Issue

I am using the internal pages feature within jQuery Mobile that works fine, but only in specific cases. Most of the links within the application use the "standard" loading features of jQuery (where the desired page is loaded via AJAX, and the first container with data-role="page" is placed in the DOM).

However, there are several pages that contain multiple containers with a data-role="page", which are intended to used as internal pages. In other words, the first page container in the HTML document contains links which will internally link to the other pages within the DOM.

Using the "standard" loading method described above, the internal links do not work. However, reloading the page so that the entire DOM is loaded solves this issue.

I know I could link to this page by adding a rel="external" attribute the link, but doing it that way removes all of the nice transitions that jQuery Mobile provides via the "standard" method of loading.

How can I solve this issue without adding a rel="external" attribute?

Thank you for your time.

Upvotes: 2

Views: 1970

Answers (2)

Oliver Spryn
Oliver Spryn

Reputation: 17348

I have found this solution to be the most efficient manner for handling my situation. It does not require the use of classes on anchor tags to indicate whether or not the link will include separate pages. This code will simply look for additional pages, all within a single HTTP request.

Jasper got my wheels spinning in the right direction.

(function($) {
/**
 * This code will load all of the internal pages within the DOM of an HTML element
 * and transition the first one into place, just as the "standard" way of loading
 * a page, but it includes all internal pages
*/

  $(document).bind('pageload', function(event, ui) {
  //Find all of the pages and dialogs in the DOM
    var response = ui.xhr.responseText;
    var data = $(response).filter('section[data-role="page"], section[data-role="dialog"]');

  //Make sure that the given psuedo page does not already exist before adding it
  //Skip the first matched element, since jQM automatically inserted it for us
    for (var i = 1; i <= data.length - 1; i++) {
      var current = data.eq(i);

      if (current.attr('id') && !document.getElementById(current.attr('id'))) {
        current.appendTo('body');
      }
    }
  });
})(jQuery);

Upvotes: 2

Jasper
Jasper

Reputation: 75993

jQuery Mobile by default only loads the first data-role="page" or the first data-role="dialog" element from an external document. The <head> section is even omitted.

A fix would be to either put all pages into a single HTML document or place each pseudo-page in it's own HTML document.

You could write some code that manually grabbed all of the pseudo-pages in an external document:

HTML --

<a class="multi-page-link" href="some-external-document.html"></a>

JS --

//when a pseudo-page initializes this code will run
$(document).delegate('.ui-page', 'pageinit', function () {

    //find elements tagged with the above class and bind to their `click` events
    $(this).find('.multi-page-link').bind('click', function () {

        //show the loading spinner
        $.mobile.showPageLoadingMsg();

        //create AJAX request for href of link
        $.ajax({
            url      : this.href,
            dataType : 'html',
            success  : function (response) {

                //on successful response, find all the pseudo-page elements in the external document and append them to the `<BODY>`
                var $pseudoPages = $(response).filter('[data-role="page"], [data-role="dialog"]').appendTo('body');

                //now hide the loading spinner
                $.mobile.hidePageLoadingMsg();

                //and navigate to the first pseudo-page that was just added to the DOM
                $.mobile.changePage($pseudoPages.eq(0));
            },
            error    : function (a, b, c) { /*Don't for get to handle errors*/ }
        });
        return false;
    });
});

I think there is a plugin for this but I don't know where it is or if it's being supported.

Upvotes: 1

Related Questions