5

I am having an issue with jQuery and how to dynamically process urls. What I would like to do is this if I have a page with links and each one has an id to call a function and an id. How can I change the url for the specific link and have that url work as a bookmark. Below is my code

<div data-role="page" id="#listview">
<div data-role="header">
    <h1>List</h1>
</div>

<div data-role="content">   
<ul data-role="listview" id="carlist">
  <li><a href="#" onclick="cardetails('1')">Acura</a></li>
  <li><a href="#" onclick="cardetails('2')>Audi</a></li>
  <li><a href="#" onclick="cardetails('3')>BMW</a></li>
</ul>
</div>

<div data-role="footer">
    <h4>Page Footer</h4>
</div>

So when you click on a car in the list a function called cardetails with a parameter of 1 will go back to the server and get cardetails for the car with id=1. My issue is not that but when the JSON data has returned I want the url to change to cardetails#1 or something like that. So it can identify where the user is, the browser can add it to its history and if the user bookmarks the url the browser will be able to find that exact page with the same data displayed.

Apostolos Emmanouilidis
  • 7,179
  • 1
  • 24
  • 35
Kern Elliott
  • 1,659
  • 5
  • 41
  • 65
  • If you're still having issues and you want full URL navigation feature, feel free to try my [plug-in](https://github.com/CameronAskew/jquery.mobile.paramsHandler) that I recently created for jQM 1.4+ – Cameron Askew Apr 04 '14 at 22:03

1 Answers1

9

This example uses the jQM changePage() to send data with an Ajax page request. It can be used only when the 'to' argument of changePage() is a URL. Check the jQM documentation for more info.

Instructions to test the example:

  • Create a folder
  • Create a file with name cars.js inside the folder
  • Create a file with name cars.html inside the folder
  • Create a file with name car-details.html inside the folder
  • Fill each file with the corresponding code that you can find below
  • Open the cars.html which is the first page and navigate

Add the following code inside the car.js file:

$(document).on( "pageinit", "#car-page", function( e ) {
    $('#car-list a').on('click', function(e) {
        e.preventDefault();
        $.mobile.changePage('car-details.html', {
            data: {
                id: this.id
            }
        });
    });
});

$(document).on( "pageinit", "#car-details-page", function( e ) {
    var passedId = (($(this).data("url").indexOf("?") > 0) ? $(this).data("url") : window.location.href ).replace( /.*id=/, "" );
    $("#details").html(["Selected id is: '", passedId, "'"].join(""));
});

Add the following code inside the cars.html page.

<!doctype html>
<html lang="en">
   <head>
        <title>Cars example</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
        <script src="./cars.js"></script>
    </head>
    <body>
        <div id="car-page" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">Car list</a></h1>
            </div>
            <div data-role="content">   
                <ul data-role="listview" id="car-list">
                    <li><a href="#" data-transition="flip" id="acura">Acura</a></li>
                    <li><a href="#" data-transition="flip" id="audi">Audi</a></li>
                    <li><a href="#" data-transition="flip" id="bmw">BMW</a></li>
                </ul>
            </div>
        </div>
    </body>
</html>

Add the following code inside the car-details.html page.

<!doctype html>
<html lang="en">
   <head>
        <title>Car Example</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
        <script src="./cars.js"></script>
    </head>
    <body>
        <div id="car-details-page" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">Car details</a></h1>
                <a data-rel="back">Back</a>
            </div>
            <div data-role="content">   
                <div id="details"></div>
            </div>
        </div>
    </body>
</html>

EXAMPLE 2

Solution using a shared JS object:

On the second page the selected id appears on a div. Moreover the URL contains the id so it can be bookmarked. In the case where the user navigates to the second page through the first page then the id is passed to the second page through a shared JS variable. In case the user opens a bookmarked page then the id is extracted from the window.location.href.

Please note that instead of passing the href value in the shared variable you could pass the id or any other value that will help you identify the user's selection.

Instructions to test the example:

  • Create a folder
  • Create a file with name cars.js inside the folder
  • Create a file with name cars.html inside the folder
  • Create a file with name car-details.html inside the folder
  • Fill each file with the corresponding code that you can find below
  • Open the cars.html which is the first page and navigate

Add the following code inside the car.js file:

var passDataObject = { selectedHref: null }

$(document).on( "pageinit", "#car-page", function( e ) {
    $(this).find('a').unbind('click').click(function() {
        passDataObject.selectedHref = this.href;
    });
});

$(document).on( "pageinit", "#car-details-page", function( e ) {
    var passedId = (passDataObject.selectedHref != null ? passDataObject.selectedHref : window.location.href).replace( /.*id=/, "" );
    $("#details").html(["Selected id is: '", passedId, "'"].join(""));
});

Add the following code inside the cars.html page:

<!doctype html>
<html lang="en">
   <head>
        <title>Cars example</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
        <script src="./cars.js"></script>
    </head>
    <body>
        <div id="car-page" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">Car list</a></h1>
            </div>
            <div data-role="content">   
                <ul data-role="listview" id="car-list">
                    <li><a href="./car-details.html?id=1" data-transition="flip" id="acura">Acura</a></li>
                    <li><a href="./car-details.html?id=2" data-transition="flip" id="audi">Audi</a></li>
                    <li><a href="./car-details.html?id=3" data-transition="flip" id="bmw">BMW</a></li>
                </ul>
            </div>
        </div>
    </body>
</html>

Add the following code inside the car-details.html:

<!doctype html>
<html lang="en">
   <head>
        <title>Car Example</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
        <script src="./cars.js"></script>
    </head>
    <body>
        <div id="car-details-page" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">Car details</a></h1>
                <a data-rel="back">Back</a>
            </div>
            <div data-role="content">   
                <div id="details"></div>
            </div>
        </div>
    </body>
</html>

EXAMPLE 3

Multipage Example (The address bar URL is not changed based on the car selection)

<!doctype html>
<html lang="en">
   <head>
        <title>Cars example</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
        <script>
            var passDataObject = { selectedId: null }

            $(document).on( "pageinit", "#car-page", function( e ) {
                $(this).find('a').unbind('click').click(function(e) {
                    e.preventDefault();
                    passDataObject.selectedId = this.id;
                    $.mobile.changePage('#car-details-page', { transition: 'flip'} );
                });
            });

            $(document).on( "pagebeforeshow", "#car-details-page", function( e ) {
                $("#details").html(["Selected id is: '", passDataObject.selectedId, "'"].join(""));
            });
        </script>
    </head>
    <body>
        <div id="car-page" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">Car list</a></h1>
                <a data-rel="back">Back</a>
            </div>
            <div data-role="content">   
                <ul data-role="listview" id="car-list">
                    <li><a href="#" id="acura">Acura</a></li>
                    <li><a href="#" id="audi">Audi</a></li>
                    <li><a href="#" id="bmw">BMW</a></li>
                </ul>
            </div>
        </div>
        <div id="car-details-page" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">Car details</a></h1>
                <a data-rel="back">Back</a>
            </div>
            <div data-role="content">   
                <div id="details"></div>
            </div>
        </div>
    </body>
</html>

I hope this helps.

Apostolos Emmanouilidis
  • 7,179
  • 1
  • 24
  • 35
  • am getting an error loading page anytime I click on a link within cars.html why is that? – Kern Elliott Feb 27 '13 at 13:21
  • Oh I have one question is it possible to put all of this in one file? I tried but it only works in one instance and all the rest it keeps the first variable. – Kern Elliott Feb 28 '13 at 00:29
  • I added a multipage example but the address bar URL does not contain the id parameter. – Apostolos Emmanouilidis Feb 28 '13 at 20:19
  • yes the link does but if i put all the code in one fill it only works once and keeps the value all the time in fact the bookmarks don't even work. Should I change the pageinit into something else like pageshow? – Kern Elliott Feb 28 '13 at 22:21
  • In the posted multipage example (check the edited section in my answer) the selected car id is passed correctly to the second page. However, it is not possible to create bookmarked URL. – Apostolos Emmanouilidis Feb 28 '13 at 22:32
  • I need the bookmark but I also need the one page for performance any other suggestions? – Kern Elliott Mar 01 '13 at 04:29
  • @Tolis. I used your approach but I'm having problem when user refresh the page (like pressing F5) in multipage. If the current page is #car-details-page, after refresh passDataObject.selectedId is obviously undefined. Is there some trick to apply in these situations? I force a navigation to the car-page on beforepageshow event, but user see an empty details page for a while. – Marco Mar 22 '13 at 15:11
  • @Marco Yes, obviously this solution is not working on page refresh. To deal such cases you can use the sessionStorage. Replace line passDataObject.selectedId = this.id; with sessionStorage.selectedId = this.id; and line $("#details").html(["Selected id is: '", passDataObject.selectedId, "'"].join("")); with $("#details").html(["Selected id is: '", sessionStorage.selectedId, "'"].join("")); You may check this answer http://stackoverflow.com/questions/12058248/how-to-pass-parameters-while-changing-the-page-in-jquery-mobile/12059780#12059780 and the concerns regarding the Web Storage usage. – Apostolos Emmanouilidis Mar 31 '13 at 18:21
  • @TolisEmmanouilidis or could use my [plug-in](https://github.com/CameronAskew/jquery.mobile.paramsHandler) and just pass variables through the URL. – Cameron Askew Apr 04 '14 at 22:01
  • @Marco Please see previous comment about plug-in. Let me know if it has any value for you – Cameron Askew Apr 04 '14 at 22:02
  • This worked for me for 1.4 https://jqmtricks.wordpress.com/2014/01/22/passing-parameters-between-pages-multi-page-model/ Passing data – jQuery Mobile 1.4.x (Demo) $.mobile.pageContainer.pagecontainer( "change", "#pageX", { myData: "Hello World!" } ); Retrieve data – jQuery Mobile all versions $( document ).on( "pagebeforechange" , function ( event, data ) { if ( data.toPage[0].id == "pageX" ) { var stuff = data.options.myData; console.log(stuff); } }); – my account_ram Jul 18 '15 at 11:22