How to handle concurrently opened windows

In some situations I need to store contextinformation of the current window.

The simplest solution is to store this information in the session.

But what happens, if the user opens the application concurrently in two or more tabs? Worst case will be, that one window destroyes the context of another.

A quite cumbersome method is, to store window specific information as hidden fields inside the page. A more generic method would be very nice, but that probably means to distinguish concurrent windows on the client.

How to identify a window on the client?

The simplest case: A paginated index that offers an edit link, that returns to the current page of the index. The page number is stored in session.

Now the user opens the index in TAB 1, skips to page 5 and then duplicates the tab (TAB 2).

In TAB 2, he skips another 5 pages and clicks edit for one of the entries - 10 is stored in the page attribute of session

Then he opens TAB 1 again (with index page 5) and clicks edit for some entry - 5 is stored in the page attribute of session.

Then he decides to go to TAB 2 and stores the object, expecting to return to index page 10 and wondering, why he ends up in page 5.

In the case, that the edit form can refer some other subpage, stack like tracking can become a big deal.

A quite cumbersome solution is, to store the page number in a hidden field, or in the store link of the edit form.

Please quote when replying.

Fritz Trapper wrote in post #960981:

The simplest case: A paginated index that offers edit links, that return to the current page of the index. The page number is stored in session.

Why are you reinventing what the browser's Back button already does?

Best,

No that's no reinvention of the browser's Back button, since usually the rails update or show method redirects to the index. If it doesn't know about the page number, it returns to page 1.

Then you can use the back button twice or even more often, to return to the index page, from where you started.

This is all but convenient.

Store the page parameter in the query string instead of the session.

Tim Shaffer wrote in post #961029:

The simplest case: A paginated index that offers an edit link, that returns to the current page of the index. The page number is stored in session.

Store the page parameter in the query string instead of the session.

Exactly! That way you won't break the back button.

Right now, you're using session data in such a way that index pages do not have bookmarkable URLs. This is bad for many reasons, and is the root cause of your proximate problem.

Rule of thumb: if you think you need to track your user's clickstream in the session *to make your application work*, then your design is probably wrong.

(Note the emphasized phrase. If you want to track your user's clickstream for marketing or optimization purposes, that's quite another matter.)

Best,

Tim Shaffer wrote in post #961029:

Store the page parameter in the query string instead of the session.

Thats, what I currently do. It is managable, if I have to return one level to reach the index page, but I also have a situation, where two levels are possible. The latter case very ugly to implement: you have to track the page index in any link in level 1.

Is there really nothing in the DOM, that can be used to distinguish two tabs in the client?

Fritz Trapper wrote in post #961054:

Tim Shaffer wrote in post #961029:

Store the page parameter in the query string instead of the session.

Thats, what I currently do. It is managable, if I have to return one level to reach the index page, but I also have a situation, where two levels are possible. The latter case very ugly to implement: you have to track the page index in any link in level 1.

No. You don't. Just give all your pages bookmarkable URLs, and rely on the browser's back button to do the right thing. Forget about trying to do this in your app. The server shouldn't care how the user has his windows set up.

Is there really nothing in the DOM, that can be used to distinguish two tabs in the client?

Not that I can think of. Why would there be? This is purely a client-side concern and should be of no interest whatsoever to the server.

Best,

Marnen Laibow-Koser wrote in post #961055:

Not that I can think of. Why would there be? This is purely a client-side concern and should be of no interest whatsoever to the server.

But it would be a possibility for the server to identify individual tabs, if it could be submitted.

It is the same principle, than distinguishing two different clients.

Fritz Trapper wrote in post #961059:

Marnen Laibow-Koser wrote in post #961055:

Not that I can think of. Why would there be? This is purely a client-side concern and should be of no interest whatsoever to the server.

But it would be a possibility for the server to identify individual tabs, if it could be submitted.

It is quite the same principle, than distinguishing two different clients.

HTTP is stateless. The only way the server can distinguish different clients is by the use of cookies -- which are a stateful hack on top of stateless HTTP.

For browsers to implement what you suggest would require a different cookie store for different windows or tabs. I suppose there's no *theoretical* obstacle to doing that, but I don't think any browser implementer ever actually has.

Best,

Or by query string parameters (e.g. JSESSIONID) and url rewriting.

Marnen Laibow-Koser wrote in post #961071:

For browsers to implement what you suggest would require a different cookie store for different windows or tabs.

Exactly.

But I think, I found something like page private cookies:

- Use javascript_tag to inject an initialized array containing the   cookie data into the page. - Implement js functions to build submit the cookie data with requests

This will even work, if there is no form in the document.

Fritz Trapper wrote in post #961082:

Marnen Laibow-Koser wrote in post #961071:

For browsers to implement what you suggest would require a different cookie store for different windows or tabs.

Exactly.

But I think, I found something like page private cookies:

- Use javascript_tag to inject an initialized string variable containing   the cookie data into the page. - Implement js functions to submit the cookie data via request parameter

This will even work, if there is no form in the document.

I don't think that would work, unless you can keep track of the names of your different cookies. But don't ever do it; it's a ridiculous hack. Just make all your URLs bookmarkable, don't break the Back button, and the problem will go away.

Best,

Off topic:

Marnen Laibow-Koser wrote in post #961071:

... cookies -- which are a stateful hack on top of stateless HTTP.

It's not a hack, it is not implemented on top of HTTP and it doesn't make HTTP stateful. It is simply a data exchange subprotocol within HTTP.

Marnen Laibow-Koser wrote in post #961085:

I don't think that would work, unless you can keep track of the names of your different cookies.

That's not necessary, since the data is contained in the page itself.

If you clone such a browser tab, the data is cloned too and will be modified by subsequent requests without affecting the master copy of the cloned tab.

But don't ever do it; it's a ridiculous hack. Just make all your URLs bookmarkable,

OK, but take a look on the page source of an index containing a delete link: There they inject a form onclick into the page, containing some hidden field to submit data.

This trick could be used to post the page local cookie data, if there is no form in the document; otherwise the problem can be solved by adding a new hidden field on server side.

Rails is clever enough, to implement some generic code, that does this fully transparent to the programmer.

don't break the Back button, and the problem will go away.

This is not always possible - as pointed out above. It will work for quite plane HTML pages, but not for more complex applications.

Fritz Trapper wrote in post #961091:

Marnen Laibow-Koser wrote in post #961085:

I don't think that would work, unless you can keep track of the names of your different cookies.

That's not necessary, since the data is contained in the page itself.

Modern browsers that are not completely ignorant have per-window storage on the client side:

http://dev.w3.org/html5/webstorage/#the-sessionstorage-attribute

I'm only saying that per-window/per-tab storage is not out of the question. It's something that is coming standard in HTML5. Problem is that most sites can't reliably use this yet so this is really a moot point in most situations.

Robert Walker wrote in post #961102:

Fritz Trapper wrote in post #961091:

Marnen Laibow-Koser wrote in post #961085:

I don't think that would work, unless you can keep track of the names of your different cookies.

That's not necessary, since the data is contained in the page itself.

Modern browsers that are not completely ignorant have per-window storage on the client side:

http://dev.w3.org/html5/webstorage/#the-sessionstorage-attribute

I'm only saying that per-window/per-tab storage is not out of the question. It's something that is coming standard in HTML5. Problem is that most sites can't reliably use this yet so this is really a moot point in most situations.

Interesting. I didn't realize HTML 5 storage was per window.

Best,

Robert Walker wrote in post #961102:

Modern browsers that are not completely ignorant have per-window storage on the client side:

But I guess, it's still too early, to rely on ths feature.

Fritz Trapper wrote in post #961106:

Robert Walker wrote in post #961102:

Modern browsers that are not completely ignorant have per-window storage on the client side:

But I guess, it's still too early, to rely on ths feature.

As I said earlier... in all but a few cases it probably is too early:

http://www.quirksmode.org/dom/html5.html

OK, so it's no bad idea, to implement page local storage as described above.