1

I'd like to implement a AJAX navigation system such as the one in GMail or similar web apps. For example, I have a root store, and all of the navigation must be handled in the JavaScript by deep-linking. A few examples:

store/#/movies/star-wars
store/#/books/authors/tolkien

and so on. I have just begun using PathJS, which provides a simple mechanism for address routing.

The problem I encounter is that JQuery Mobile automatically strips my # hash character from the URL address bar, turning store/#/movies/star-wars into store/movies/star-wars.

I need address routing in order to save the application state, allowing bookmarking, etc. Is there any solution I can use?

frapontillo
  • 10,499
  • 11
  • 43
  • 54

4 Answers4

5

As you noticed, you need to set $.mobile.pushStateEnabled = false, but there is a lot more to being able to replace JQM's built-in navigation support.

I've created a complete example for enabling PathJS support here http://jsfiddle.net/kiliman/4dkP8/ and a live version here http://systemex.net/jqm/pathjs/ so you can see what the URLs look like. You can even book mark a hash link and it'll navigate to the correct page.

First you need to disable JQM's default hash support

$(document).bind('mobileinit', function() {

    // disable autoInit so we can navigate to bookmarked hash url    
    $.mobile.autoInitializePage = false;

    // let PathJS handle navigation
    $.mobile.ajaxEnabled = false;
    $.mobile.hashListeningEnabled = false;
    $.mobile.pushStateEnabled = false;

    $(document).bind('pagebeforechange', function(e, data) {
        var to = data.toPage;
        if (typeof to === 'string') {
            var u = $.mobile.path.parseUrl(to);
            to = u.hash || '#' + u.pathname;
            // manually set hash so PathJS will be triggered
            location.hash = to;
            // prevent JQM from handling navigation
            e.preventDefault();
        }
    });

});

Next build up your PathJS routes. For this example, I'm simply navigating to existing pages, but you can dynamically generate pages based on the current hash. Make sure you pass in the following options: dataUrl and changeHash.

    Path.map('#/store/movies/star-wars').to(function() {
        // setup options: update dataUrl and prevent JQM from changing hash        
        var options = {
            dataUrl: location.toString(),
            changeHash: false
        };
        // navigate to page object
        $.mobile.changePage($('#movies-star-wars'), options);
    });

    Path.map('#/store/books/authors/tolkien').to(function() {
        var options = {
            dataUrl: location.toString(),
            changeHash: false
        };
        $.mobile.changePage($('#books-authors-tolkien'), options);
    });

    Path.map('').to(function() {
        var options = {
            dataUrl: '',
            changeHash: false
        };
        $.mobile.changePage($('#home'), options);
    });

    Path.root('');

Finally, you need to initialize the page, then start PathJS.

$(function() {
    // initialize page
    $.mobile.initializePage();
    // startup PathJS
    Path.listen();
});

Hope this helps.

Kiliman
  • 18,460
  • 3
  • 39
  • 38
  • Thank you, but it does not fully work. I get an error on `initializePage()`, Chrome says: `Uncaught TypeError: Object # has no method 'initializePage'`. My web app does not get initialized and I see nothing. – frapontillo Mar 19 '12 at 17:01
  • Which version of Chrome? Mine is 17.0.963.79. Can you launch Developer Tools and see if you get any other errors? Sounds to me like JQM didn't load. – Kiliman Mar 19 '12 at 17:33
  • I also tested it on Firefox 10.0.3, Safari 5.1.2, and IE 9. Although I had to copy the path.js file to my server, since github.com was not returning the proper MIME type. – Kiliman Mar 19 '12 at 17:43
  • I need to point out that I'm using [jQuery Mobile Splitview plugin](https://github.com/asyraf9/jquery-mobile/), which uses a modified (and probably not updated) version of JQuery Mobile. Your example works fine in Chrome, it's my web page that has that strange behaviour. – frapontillo Mar 20 '12 at 07:01
  • By commenting `$.mobile.autoInitializePage = false;` and `$.mobile.ajaxEnabled = false;` I have managed to make it work. But I am using some Ajax calls to get json data, and even by calling `$.mobile.showPageLoadingMsg()` as suggested [here](http://stackoverflow.com/a/7208649/801065) no spinner is shown. – frapontillo Mar 21 '12 at 14:17
1

I have used knockoutjs + sammy . In fact knockoutjs has got a tutorial on how to implement the functionality that you're looking for.

Jishnu A P
  • 14,202
  • 8
  • 40
  • 50
  • I tried using Sammy, the routing works just as it works in PathJS, but as soon as Sammy handles the routing, JQuery Mobile strips away my # in the URL and I get redirected to its default action (I don't even know which one it is). – frapontillo Mar 19 '12 at 12:19
0

Though it's not currently supported in jQuery mobile, they point to some resources that may be of assistance in their FAQ, http://jquerymobile.com/test/docs/faq/pass-query-params-to-page.php

I'm currently using: https://github.com/azicchetti/jquerymobile-router

Irwin
  • 12,551
  • 11
  • 67
  • 97
0

The problem was solved by using the solution posted at https://stackoverflow.com/a/8159996/801065

$(document).on('mobileinit', function () {
    $.mobile.pushStateEnabled = false;
});

I needed to disable the pushState behaviour by JQuery Mobile. It looks like it's working now, even though I still have to make lots of improvements.

Community
  • 1
  • 1
frapontillo
  • 10,499
  • 11
  • 43
  • 54