azicchetti / jquerymobile-router

A router/controller for jquery mobile. Also adds support for client-side parameters in the hash part of the url. The routes handles regexp based routes. This plugin can be used alone or (better) with Backbone.js or Spine.js, because it's originally meant to replace their router with something integrated with jQM.
GNU General Public License v2.0
402 stars 69 forks source link

Clean "REST" Like url matching problem #58

Closed tdurand closed 11 years ago

tdurand commented 11 years ago

Hi,

Thanks for this great project.

I'm trying to solve a problem, i want jquerymobile-router to match this kind of url:

mysite.com/#category/28

My regexp is :

#category/\\d+

I'd tried it with

"#category/28".match(new RegExp("#category/\\d+"))     

and it worked, but i don't why jquerymobile-router is not triggering my handler... I have this error:

Uncaught Error: Syntax error, unrecognized expression: #category/28[data-role="page"] 

My router code.

function($, _, Backbone,jqmr,IndexView) {
    var Router=new $.mobile.Router({
    "#index":   { handler: 'index', events: "bc" },
    "#category/\\d+":   { handler: 'category', events: "bc" },
  }, {
    index:function(){
        console.log("index");
        // will render home view and navigate to homeView
        var indexView=new IndexView();
        indexView.render();
    },

    category:function(e,m) {
        var params=m;
        console.log(m);
    },

    default: function(){
      console.log('No route found.');
    }
  }, {
    ajaxApp: true,
    defaultHandler: 'default'
  });

Thanks a lot for your help

azicchetti commented 11 years ago

Hi, thank you for your appreciation and feedback for this project.

I guess this url:

mysite.com/#category/28

isn't supported by jquery mobile itself due to the slash in the page id.

That is to say, you can't define an "internal" page like the following one:

<div data-role="page" id="#category/28">
[...]
</div>

and use a link to it such as:

<a href="#category/28">28</a>

Remember that if you want to use internal pages: * the ajaxApp parameter must be set to false * regular expression should start with the # character * page id must not contain slashes

Slashes (and subdirectories) are only supported for ajax pages that are fetched dynamically by the framework, such as:

www.example.com/myapp/category/28

This url can become (when pushstate is disabled in jQM):

www.example.com/myapp/index.html#/myapp/category/28

Please note that the "28" page must exist (at least as a skeleton ) and must also be returned by the webserver as a regular html page.

To match such a url, you just have to strip the "#" sign from your regular expression an set ajaxApp to true.

If you want to use dynamic urls in your jQM application with internal pages you should switch to the query parameters model, for instance:

www.example.com/myapp/#internal-page?id=28

You can refer to the (really really trivial) examples in the examples/ directory (test.html and testAjax.html).

Please get back to me if there's something I'm missing in your request or if your problem persists.

tdurand commented 11 years ago

Ok, thanks for your quick anwser, i have an another question.

I'm succeeded to make my dynamic url work when navigating from a link:

<a href="#category?id=0">Link</a>

But i also want to be able to navigate directly to this url: (ie: refresh the browser here)

http://localhost:8080/#category?id=0

And this doesn't works...

Uncaught Error: Syntax error, unrecognized expression: #category?id=0[data-role="page"] 

My router file is:

var Router=new $.mobile.Router({
    "index":   { handler: 'index', events: "bc" },
    "category(?:[?/](.*))?": { handler: 'category', events: "bc" },
  }, {
    index:function(){
        console.log("index");
        // will render home view and navigate to homeView
        var indexView=new IndexView();
        indexView.render();
    },

    category:function(type,match) {
        //TODO: figure out when succeed to understand how to route
        var idCategory=RegExp("\\d+").exec(match);
        var categoryView=new CategoryView({idCategory:idCategory});
    },

    default: function(){
      console.log('No route found.');
    }
  }, {
    defaultHandler: 'default',
    ajaxApp:true
  });

And my index.html:

<body>
<div data-role="page" id="index" data-url="index">
<!-- Dynamic filling -->
</div>
<div data-role="page" data-add-back-btn="true" id="category" data-url="category"> 
<!-- Dynamic filling -->
</div>
</body>

Thanks a lot for your help

azicchetti commented 11 years ago

Hi, there are a couple of changes to perform:

<div data-role="page" id="index">
<!-- Dynamic filling -->
</div>
<div data-role="page" data-add-back-btn="true" id="category"> 
<!-- Dynamic filling -->
</div>
var Router=new $.mobile.Router({
    "#index":   { handler: 'index', events: "bc" },
    "#category(?:[?](.*))?": { handler: 'category', events: "bc" }
  }, {
    index:function(){
        console.log("index");
        // will render home view and navigate to homeView
        var indexView=new IndexView();
        indexView.render();
    },

    category:function(type,match) {
        var params=Router.getParams(match[1]);
        var categoryView=new CategoryView({ idCategory: params.id });
    },

    default: function(){
      console.log('No route found.');
    }
  }, {
    defaultHandler: 'default'
  });

Hopefully the code above will fix your issues

tdurand commented 11 years ago

Hi, thanks again for this quick response.

My code is much more cleaner with your changes but i'm facing the same issue, i cannot refresh the page on:

http://localhost:8080/#category?id=0

It triggers the same error:

Error: Syntax error, unrecognized expression: #category?id=1[data-role="page"]
azicchetti commented 11 years ago

Send me a zipfile with your code, the problem is probably well hidden...

There's also a bug in the latest jquery mobile 1.2.0-rc2 that prevents a direct access to a subpage when arguments are used in the url. If you're using this version I think we've found the issue. If that's the case, do you want to submit the issue to jquerymobile?

tdurand commented 11 years ago

I'm using the jquerymobile 1.1.1 version.

I just send you the code on your email.

I can submit an issue on jquery-mobile project if you give me the inputs

tdurand commented 11 years ago

An other issue with the new code, the router is called just one time.

For example, if i follow this link

http://localhost:8080/#category?id=0

And then i go to this link

http://localhost:8080/#category?id=1

The category function in the router.js is not triggered, jquerymobile load the page that was created at the first request

azicchetti commented 11 years ago

I've seen the code briefly, the problem seems to be the jquery version. jQM 1.1.1 should be used with jquery 1.7.1, with the newest version it goes crazy (by the way, jquery 1.8.1 seems very buggy to me).

As per the other question, you've installed the "pagebeforecreate" route, which is triggered just one time per each "internal" page (a page is created and initialized once).

Just switch to the pagebeforeshow event:

var Router=new $.mobile.Router({
    "#index":   { handler: 'index', events: "bs" },
    "#category(?:[?](.*))?": { handler: 'category', events: "bs" }
tdurand commented 11 years ago

Great solve the issues, i need to learn more about event on jquery mobile.

Thanks a lot ! I'm working on an open source project, so i will send you the link when it will be finished, you can add as an external example.

azicchetti commented 11 years ago

An opensource real-life example would be great!