jquery-archive / jquery-mobile

jQuery Mobile Framework
https://jquerymobile.com
Other
9.69k stars 2.41k forks source link

Parameter passing between pages does not work #450

Closed borismus closed 12 years ago

borismus commented 13 years ago

I'm attempting to pass parameters from one page (ex. with a list view of items, each with an id) to the sub-page corresponding to each item. I need to pass the id to the sub-page. I'm attempting to do this with get-style parameters resulting in the following URL:

.../index.html#item.html?id=1898432

I have a pageshow callback: $('[data-role=page]').live('pageshow') which triggers when the page is loaded. However, when this event fires, the window.location isn't updated to have the extra parameters in it.

I think there are two possibilities:

  1. I'm doing it wrong. Perhaps sub-hash URLs are the way to do what I'm trying to do: http://jquerymobile.com/demos/1.0a2/#docs/pages/docs-navmodel.html
  2. The event should fire after window.location is updated to reflect the URL with parameters.
tiegz commented 13 years ago

I ran into the same problem (wanted to load a nested page but with extra params to load a JSON resource in the background). The only way I can think of currently keeping it within 1 subpage is to save the "id" param in a cookie.

borismus commented 13 years ago

I'm currently hacking around this with a 50ms setTimeout just to let the URL change. But still the strategy of using GET-style params is problematic for other reasons: jQM treats each page.html?param=val as a separate page load, so you end up with many copies of the same HTML being loaded. This might be desirable in some cases, but clearly there must be a better way of doing it.

tiegz commented 13 years ago

Oh nice; I guess my main use case is that I want to be able to go to a page like "index.html#child?id=123" that would load the "index.html" file using the "child" page and store parameters "id=123" somewhere. Actually, it would also be really cool if we could intercept the event and pass it through some router before the event is fired.

fermion commented 13 years ago

Scott, Jesse (Streb) and I were talking about this one and we're wondering if this calls for either changing how the pageshow callback is fired or introducing an entirely new event (pagecomplete, for example) that's triggered at the end of changePage's internal transitionPages function right hereish:

https://github.com/jquery/jquery-mobile/blob/master/js/jquery.mobile.navigation.js#L250

I can't decide if the better thing to do is change when pageshow is triggered or if it's a case for introducing a new callback. I'd love some input so I can try to fix this!

fermion commented 13 years ago

Pretty sure this is a dupe of https://github.com/jquery/jquery-mobile/issues/issue/583 and was fixed in https://github.com/jquery/jquery-mobile/commit/54568271d93c40d6a9b33d029cd310d52fcf0b15

sam-meder commented 13 years ago

I know this is not quite the same issue, but we were expecting the code for changePage("#hash?param=value") to look for a page identified by #hash, i.e. we were expecting the parameters to be ignored. I realize this behavior is problematic with respect to deep linking (although for deep linking you could have the same code also work with ?param=value#hash), but how is one otherwise supposed to deal with parameterized pages?

The patch for enabling the behavior I describe can be found here: https://github.com/jivesoftware/jquery-mobile/commit/53e93efe3141554616ee6c587c4effac3b4d2573

thegrubbsian commented 13 years ago

I'd be happy if there were some reference to the original list element that triggered the page transition. At least then you could grab some data attribute or something from it. Or assign whatever HTML5/jquery data that was attached to the original anchor to the data property of the event argument. That way you could store data such as data-id="5" on the anchor and access it via e.data.id within the pageshow callback.

// JC

ghost commented 13 years ago

I'd like to remind you that a.html#b?c=1 is an invalid url. The valid version is a.html?c=1#b the search string comes before the hash, since hash is inside one page, while query is params to the server.

smeder commented 13 years ago

doom777:

It is at the very least a valid URI (according to http://tools.ietf.org/html/rfc3986). That said, the point here is really that one can encode parameters in the fragment value (whether those need encoding or not).

tiegz commented 13 years ago

Yeah, altho it's not as common as the "/" nowadays, here's a quote from that spec:

The characters slash ("/") and question mark ("?") are allowed to represent data within the fragment identifier. Beware that some older, erroneous implementations may not handle this data correctly when it is used as the base URI for relative references (Section 5.1).

I think when I initially wrote that comment I was thinking more about something like "index.html#child/123" (passing back template name and params thru a router). The only problem I can see with a question mark is that a lot of [older?] js libraries might do stuff like +document.location.href.split('?')+ without taking into account the fragment.

OpenGrid commented 13 years ago

I think this solution look much better than passing parameters after hash http://forum.jquery.com/topic/passing-parameters-to-a-page-in-a-mobile-jquery-app#14737000001858480

owain commented 12 years ago

It seems link this is still an issue after the navigation refractor in Beta 1.

ArtS commented 12 years ago

It looks like a lot of people are hitting this problem and end up inventing half-assed solutions using cookies, local storage, global variables etc - just have a look at the jQuery forum - searching for "pass parameters" brings up quite a few questions: http://forum.jquery.com/search/pass parameters (you will need to click on 'jQuery Mobile' in Refine Search)

I'd say this is a very common scenario and it would be really good if parameter passing gets implemented in some generic shape or form, say via data- attributes of the "a" tag.

If one could go:

<a href="#details" data-parameter="1900">Account N12394-12341</a>

and then have some function to call to retrieve the parameter value after page transition is finished.

ArtS commented 12 years ago

I just realised, however, that proposed solution (ie. keeping parameters in data-* attributes) will not work for cases when page is bookmarked.

So the original proposal of having parametrised hash is better in that regard.

owain commented 12 years ago

Looks like the guys are looking to include a potential solution in Beta 2...

https://github.com/jquery/jquery-mobile/wiki/Refactor:-navigation.js-A4.1-extensibility#template

The "URL handling hook (for data passing)" section

ArtS commented 12 years ago

So judging by https://developers.jivesoftware.com/community/blogs/engineering/2011/04/15/jivin-with-jquery-mobile-inter-page-navigationthis is resolved?

On Tue, Jul 5, 2011 at 10:45 AM, owilliams < reply@reply.github.com>wrote:

Looks like the guys are looking to include a potential solution in Beta 2...

https://github.com/jquery/jquery-mobile/wiki/Refactor:-navigation.js-A4.1-extensibility#template

The "URL handling hook (for data passing)" section

Reply to this email directly or view it on GitHub: https://github.com/jquery/jquery-mobile/issues/450#issuecomment-1500827

A 04 1639 4620

ArtS commented 12 years ago

I mean you can have urls like

page.html#myDiv?a=b

which will take you to the proper div, although you need to parse the hash params yourself.

ArtS commented 12 years ago

Although there seems to be a major flaw in the current implementation: whenever you click on one of the links, containing parametrised hashes, jQueryMobile creates a new div with appropriate data-url but same ID as the previous page's DIV

Here's an example: http://pastebin.com/2mMPcPJq

So you will quickly end up with pretty polluted DOM.

azicchetti commented 12 years ago

I'd love to have a clean way to use parameters in the hash part of the url as ArtS proposes, mainly for bookmarking purposes. This is also desirable because it gives us the opportunity to write cleaner code by means of a router/controller (listening for the pageshow or pagebeforeshow events, for example) instead of attaching events to anchors so that we can update internal application statuses in order to pass parameters between dynamic pages.

We were discussing almost the same thing in issue #2082 , maybe someone has something to add to the thread. As jQm is so close to having this feature working, it would be a pity if it's dropped now because it seems too "extreme" or not so useful.

ArtS commented 12 years ago

I beg you - please include that. It is essential for 'one-page' applications, which want to transfer all the templates in the first hit from the server and then only transfer data using JSON.

On Sat, Jul 16, 2011 at 12:40 PM, azicchetti < reply@reply.github.com>wrote:

I'd love to have a clean way to use parameters in the hash part of the url as ArtS proposes, mainly for bookmarking purposes. This is also desirable because it gives us the opportunity to write cleaner code by means of a router/controller (listening for the pageshow or pagebeforeshow events, for example) instead of attaching events to anchors so that we can update internal application statuses in order to pass parameters between dynamic pages.

We were discussing almost the same thing in issue 2082 , maybe someone has something to add to the thread. As jQm is so close to having this feature working, it would be a pity if it's dropped now because it seems too "extreme" or not so useful.

Reply to this email directly or view it on GitHub: https://github.com/jquery/jquery-mobile/issues/450#issuecomment-1585690

A 04 1639 4620

azicchetti commented 12 years ago

I wish I could do that, but I'm not a jQm developer... Please let scottjehl hear your voice in the issue #2082 thread, we might have a chance if we find some other people needing this feature...

ArtS wrote:

I beg you - please include that. It is essential for 'one-page' applications, which want to transfer all the templates in the first hit from the server and then only transfer data using JSON.

On Sat, Jul 16, 2011 at 12:40 PM, azicchetti < reply@reply.github.com>wrote:

I'd love to have a clean way to use parameters in the hash part of the url as ArtS proposes, mainly for bookmarking purposes. This is also desirable because it gives us the opportunity to write cleaner code by means of a router/controller (listening for the pageshow or pagebeforeshow events, for example) instead of attaching events to anchors so that we can update internal application statuses in order to pass parameters between dynamic pages.

We were discussing almost the same thing in issue 2082 , maybe someone has something to add to the thread. As jQm is so close to having this feature working, it would be a pity if it's dropped now because it seems too "extreme" or not so useful.

A 04 1639 4620

Reply to this email directly or view it on GitHub: https://github.com/jquery/jquery-mobile/issues/450#issuecomment-1585710

IgitBuh commented 12 years ago

Since #2082 is closed for some reason, I'd like to update the high need for this once again in this issue. You can't just overlook all the calls for this essential functionality!?

azicchetti commented 12 years ago

I think this is the only thing missing in this otherwise feature-complete framework. Unfortunately it's an essential feature that's preventing a lot of developers from doing things the "right" MVC way when developing client-side applications that make heavy use of javascript.

However it's possible to support parameters in the hash part of the url without patching jQuery Mobile by using a simple live() event. This technique should (as scottjehl told me in another post) work even with future jQuery Mobile versions so it might be safe to rely on it until it will be officially supported by the framework.

I've developed a small plugin (whose goal is completely different) that uses the technique mentioned above: https://github.com/azicchetti/jquerymobile-router

I hope you'll find it useful.

oleander commented 12 years ago

Any news on this one?

jblas commented 12 years ago

So @scottjehl and I put together some samples that show folks how to generate dynamic pages (with in-memory objects or JSON) ... one of the samples is very similar to what Jive is using for their URL schemes. You can find them here:

http://jquerymobile.com/test/docs/pages/dynamic-samples/

A description for the first sample is here:

http://jquerymobile.com/test/docs/pages/page-dynamic.html

I hope to describe the 2nd sample sometime in the near future. The key here is to take advantage of the "pagebeforechange" event notification so you can parse your urls, and tell the system what it should load.

jblas commented 12 years ago

Also, I should say that the framework should now preserve all query params and hashes now. If folks find that this is not true, please let me know.

IgitBuh commented 12 years ago

Great to hear there's progress! May I suggest to make this a little bit more easy to use by putting the logic inside jQM, so on each page you can access all GET parameters (if any present) by something like $.mobile.urlget("category")? I simply find it somehow awkward to create page event listeners to access a GET parameter. jm2c.

azicchetti commented 12 years ago

I like the idea of page event listeners, it's somehow the basic idea around haschange url routing. It's also the only way to put our code in the right place and have it executed at the right time.

For instance, we may want to perform 'our things' (fetching data from the internet, client side rendering, etc) in the background, before page transitions, in order to speed things up. However there are certain cases that require the page to be fully shown, because our javascript enhanced widgets (or google maps for that matter) don't work if the dom is hidden or with display:none. The only way to achieve this behaviour is using page events.

So, I think that the current proposed solution (supporting parameters in the hash part of the url and using page events to access the pageUrl) is enough to play with dynamically generated pages.

Thank you @jblas and @scottjehl.

smeder commented 12 years ago

Kin,

Thanks for putting together the mechanism/samples. Looks like it should be really easy for us to make use of it.

jblas commented 12 years ago

Given the feedback from folks I'm going to go ahead and close this one. If anyone still has a problem with a specific scenario, please file a separate issue and provide details such as:

and even better, provide a sample if possible.

mathiasconradt commented 12 years ago

Is there a solution now?

I find that basic changePage with url parameters (data) passed in combination with back link is still buggy. Here's what I got:

If I go back and forth a third or fourth time, the code in the 'pageshow' event handler will actually always be executed thrice or four times!

jblas commented 12 years ago

This is just an FYI, @mathiaslin filed his previous comment as separate issue 2618:

https://github.com/jquery/jquery-mobile/issues/2618

This issue (450) should remain closed.

andyl commented 12 years ago

It still doesn't work...

nisc commented 12 years ago

I also have no idea how to handle this properly. If I use GET parameters, I end up with really weird results:

The page shown in the browser is different/decoupled from what I'm interacting with in the javascript console.

Examples: (1) I call $('#someid').hide() on some element '#someid' which is clearly visible in the browser, but it does not disappear. (2) DOM elements that I can access with JQ selectors are not shown in the browser.

I have failed to isolate a test-case to submit as a bug report, though.

oleander commented 12 years ago

Why is this issue closed? The problem still remains.

jblas commented 12 years ago

@mathiaslin @andyl @nisc @oleander

The bug was closed because the original problem reported was actually fixed. I know the title of the bug is a bit generic, but we can't use this issue as a catch all. If you are still having issues, please file separate issues to cover what isn't working for you and provide details in terms of your setup/usage. Of particular importance are details like:

If you can provide a sample, that would also help things move a lot quicker towards a solution for you.

IgitBuh commented 12 years ago

I actually still don't understand why you strictly decline to make it easy for developers concerning GET parameters... I posted a suggestion a couple of times which unfortunately didn't get any attention.

May I suggest to make this a little bit more easy to use by putting the logic inside jQM, so on each page you can access all GET parameters (if any present) by something like $.mobile.urlget("category")?

nisc commented 12 years ago

@jblas

My report: https://github.com/jquery/jquery-mobile/issues/2784

jblas commented 12 years ago

@IJay

I think I see where the disconnect is with this issue ... the original issue was reported at a time when we were actually dropping query params when placing the path of an external page inside the hash. That bug has been fixed a while back. There have been other folks in this bug and other related bugs ... which some have been closed, not by me, in fact I wasn't involved in any of those discussions ... where folks are asking for the ability to specify query params for embedded pages.

I personally have been trying to make things easier for developers. I was the one that added the path parsing code that made it easier to parse URLs properly, even in the case when urls had query params and hashes in the document fragment of the URL. All of that is available in $.mobile.path.

That said, I'm still wondering what you are asking for. Are you asking for a utility function that can allow quick lookup of a given query parameter in a URL you supply? Or are you asking for the ability to pass data to an embedded page as a query string in the hash? In either case, we really need to file separate issues.

I'm sensing some frustration from folks. I'm willing to help, all I'm asking is for folks to file issues that clearly explain what problems they are having, and to help us with the details since not everyone is doing things the same way or proposing the same thing.

andyl commented 12 years ago

@jblas - in jQM, I'd like to use a href like this:

<a href="#basepage?city=a&state=b">link</a>

When you click on this link, jQM should:

The problem I see is inconsistent behavior on different browsers, especially when clicking multiple links with different query strings...

Let me know if you'd like me to create a new issue, add my comments to some other issue, supply more detail, etc.

Thanks for your support - IMHO solving this issue will benefit many developers.

jblas commented 12 years ago

@nisc

Thanks for filing a separate issue!

@andyl

Thanks for the details. Yes, please copy and paste what you said above into a separate issue. I'm trying to stop the continuous morphing of this issue, which is confusing some of us. Also is this different from what was proposed in 2082?

https://github.com/jquery/jquery-mobile/issues/2082

I haven't actually had the time today to sit down and read all the way through 2082 yet.

andyl commented 12 years ago

@jblas - OK I'll post my comments to issue 2082.

azicchetti commented 12 years ago

@andyl: I'm using the same url schema for many applications and it seems to work properly.

I totally agree that using the "pagechange technique", as described in the official doc, is quite "ugly" since it's nothing but an hack, but I'm _incredibly grateful_ to that someone who made this possible, since we've something reliable and officially supported now.

I suggest you develop or use a plugin that implements that "hack" in your application, because writing that thing every single time is quite boring.

As for the $.mobile.urlget() function proposed by @IJay, I'm not sure it should be included in the framework, at least not in that way.

The basic problem with jquery mobile is that it lacks an official hash router (cfr: backbone.js and sencha touch) for dynamic pages, although it's quite simple to write one now that hash parameters are supported. Without a router, every single developer will "cook" his own solution, leading to a total mess and that frustration @jblas was talking about.

nisc commented 12 years ago

@azicchetti

Do you still recommend using azicchetti/jquerymobile-router ?

azicchetti commented 12 years ago

Until we get something similar in the framework, I think it's a viable option.

The only problem is that it's built around my needs only, so it might be quite 'strange' to someone who's not used to work with Backbone.js, or simply is not familiar with javascript MVC routing.

I've tried to simplify things for people who don't want to learn regular expression by providing an utility to convert an hash with parameters to an object, which is quite close to the function @IJay proposed a few posts above.

mrzepinski commented 11 years ago

Is any clear solution for that feature? I don't want to use external library, like jquerymobile-router.

CameronAskew commented 10 years ago

@borismus @tiegz @fermion @thegrubbsian @doom777 @OpenGrid @owilliams @ArtS @azicchetti @oleander @IJay @smeder @mathiaslin @andyl @nisc @mrzepinski

If anybody still cares about this, I created a simple plug-in which allows you to pass and maintain URL parameters within embedded jQuery Mobile pages for the multi-page template. It works well but could probably use some touch-ups and improvements...which I'll do if people ask for them & time permits..or people can also contribute. You can find the plug-in here..

https://github.com/CameronAskew/jquery.mobile.paramsHandler