Change value in URL without affecting history - javascript

I am pretty sure I am failing to find an answer to this just because I am not using the correct terminology when googling.
In my website I want to display some details about the user's state like selections or filters in the URL so it can be copied and sent to a colleague to replicate the state somewhere else. However, I don't want to enter a state in the history for each change to this so that the back buttons and refresh are affected. I want to make it so that if you navigate to a new place within the website or if you press back/forward/refresh in your browser, the extra parameters (to the extent I chose) will be discarded.
Whenever I try to google for this the topics are always "Change url without reloading page" where I want "Change url text superficially without affecting ANY behavior of the history or browser".
I am developing with GWT so I anticipate that a javascript approach will be most appropriate.

Related

How to detect url change using jquery (or javascript) for urls without a hash

I've been searching for an answer to this and the most I can find is to use window hashchange. However my urls do not contain hashes.
Please note that I do not have any control over the urls or the code for the sites.
So here is what I am doing. I create a drop down button with a few options.
Button A -> Option 1, Option 2, Option 3, etc....
How the site is designed is this. The base url is
http://example.com/12345zzzyyyxxx
To modify anything on that page, you need to click on the edit button. This will take you to the url (which is the edit page)
http://example.com/12345uuuyyyttt/e
As you can see above, 12345 is a constant and anything after that (up to the /e on the second url) is dynamic. But no hashes.
So I am trying to automate the following:
1. Click on Edit
2. Fill in the required fields based on option selected.
3. Save the changes. Once save is triggered, the site will take automatically take you back to /12345zzzyyyxxx base url.
So I have it working from the edit page, but that means you have to manually click on edit. I want to automate that.
I have tried using setTimeout and setInterval to detect when this happens, but what I have found out during debugging is that both of these go out of scope when the frame changes.
Also note that the entire page does not change, the frame changes keeping the logo and a few other items untouched and you can physically see that they stay while the frame changes.
History JS is basically the standard js-lib to handle all History state changes, check their github account for more information.
https://github.com/browserstate/history.js/

Clicking the browser Back button to return to an ajax page and have it look the same?

I've tried doing some research on the various jquery history plugins, but I can't find any examples for my situation, so I'm starting to think maybe what I'm trying to do is not possible.
We have a very complicated search page that updates with ajax. Users search using a ton of options, and they get back a list of results which they can sort, page etc. Then if they click on one of the results, it navigates them to another page to view the details. However, if they click Back they do not return back to how the page appeared after all the ajax and javascript updates. They see the search page with none of their results.
I was hoping that I could pull of something with adding a hash before they navigated away, or using one of the jquery history plugins to achieve something similar, so that when they clicked Back, it wouldn't RELOAD the search page, but would just show them their cached version (how it last looked when they clicked on one of the results).
From what I've seen, it looks like most of the examples I've found for ajax and back buttons use a hash value that tells the page how to arrange itself, even allowing for bookmarking the page that includes the hash. I think for me that would mean that I'd basically have to serialize everything in the search page into a hash value, which doesn't seem practical unless I am totally misunderstanding how it works.
Does anyone out there know if this possible?
There are at least 2 ways to do what you want:
"Classic" - store all user search options in cookie or in session, like "last search". So, when user navigates to search page during session, you can read cookie / session and show last search results with that options.
"Modern" way - use HTML5 history API - on each search form a search options object and push it in via history.pushState - when user navigate to other page and then presses "back", browser will use this state to perform a search.
If it's that complex, better you develop your own solution without any plugin. Just use location.hash to get and set hash value and store all form input elements and their values after hash like a querystring input1=a&input2=b
On every form submit update hash querystring
If user navigates back in history read hash value parse it and update your form fields and submit to get search results automatically.
you can check out SammyJS this is the plugin I used for ajax history. Hope it helps

appendChild() checkboxes: remember selections with browser back button

Thank you in advance to anyone who attempts to help me with this.
I have a form that I am adding checkboxes to via appendChild() - as selections for the user to chose from - based on a bunch of criteria.
When the user checks any of these boxes and then clicks the 'continue' button to post the selection to another page - and then clicks the back button - the checkboxes that were checked by the user - have now been forgotten by the browser (no longer checked).
If I use php to write the checkboxes or simply have static checkboxes - when the user checks any of these boxes and then clicks the 'continue' button to post the selection to another page - and then clicks the back button - the selected checkboxes are remembered (still checked)
My question is:
Why does the browser forget the selections the user made when I create the checkboxes with appendChild()
yet the same browser will remember the selections the user made when using static checkboxes
What is it about appendChild() that is not allowing the same browser to remember the checked selection?
[div id="mydiv"] here is where the checkboxes are going[div]
[script type="text/javascript"]
var newInput = document.createElement("INPUT");
newInput.id = "mycheckboxid";
newInput.name = "mycheckboxname";
newInput.type = "checkbox";
document.getElementById('mydiv').appendChild(newInput);
[/script]
The browser may "forget" dynamic changes to the DOM because different browsers use different strategies for caching web pages. When you hit the back button, the idea is that the browser can display its cached copy rather than re-request the page from the original web server.
It can accomplish this in (at least) two ways:
The browser caches the DOM itself of a page upon leaving it. Upon revisit (forward or back) dynamic changes will persist.
The browser caches only the original HTML of the page at load time (prior to any dynamic changes). This has the effect of losing those dynamic changes--further modification to the DOM with appendChild() or innerHTML is not recorded.
Note that some browsers additionally keep modified form data, and others do not. If your goal is 99+% compatibility across all browsers, then you have some work to do.
To work around this you need to persist the state somehow. You have a few options:
Save data about the modifications to the page to localstorage. Use a key that is generated randomly on first page load and then kept in the page, so that the state changes will only apply to that instance of the page. On page load, if this key already exists, read the change data out and re-apply the changes. Older browsers do not support local storage.
Do the prior thing with cookies. I don't recommend this, as it has the drawback of proliferating cookies. Cookies are sent and received in every request (including ajax ones), so you would be bloating the data being transmitted on every request. Old browsers would work fine with this.
Abandon your dynamic change model and make the changes occur through a post to the server. Then the page will contain the modified html when pulled from the browser's cache. You probably don't want this, but I thought I'd point it out for completeness' sake.
Save data about the modifications to the page via ajax behind the scenes to the server. This is not the same as actually round-tripping each change like the previous item. You still make changes dynamically, but you post an "advisement" file to the server. Then, on each page load, request any adjustment data from the server. This is similar to the first suggestion, but you are using the remote server as your storage. This makes extra net traffic occur on each page load, but the traffic can be minimal as it would be just about this page. It also makes extra net traffic occur that would not normally be sent (the advisement data). A clever system architecture, however, could use this information to persist a user's unsubmitted form data across computers and over time in a way that could be very handy (lets say your user does 199 out of a 200-question survey and then his power goes out--with this scheme he has a chance of painlessly continuing later exactly where he left off!).
Make your Continue button open a new browser window, preserving the original page intact.
Make your Continue button post the data without leaving the page, preserving it intact. You could do a simple lightbox-style overlay.
If the lightbox-style overlay will not work but you really have to display a new page and don't want it to be in a new window, then redesign your site to work similarly to gmail: where pages change only through javascript, and only through using #hash tags at the end of URLs to control behavior. This can be difficult but there are libraries out there that can accomplish it. (For some browsers one has to resort to polling to see if the hashtag has changed.) The basic idea is that when you click a link that points to the same page but has a tag on it such as About the browser will initiate a page load event, and will push a new context into the history forward/back stack, but will not actually load a new page. You then parse the updated URL for the hash code (which maps to some kind of command) and carry it out. Through careful choice of the proper hash codes for each link, you can hide and display the appropriate page dynamically through Javascript and it will appear as if the person is navigating around a real web site. The reason you do all this is that, because the page never loads, you not only can maintain state in Javascript, you can maintain your DOM state as well--you simply hide the page that was modified by the user, and when the back event occurs that means to visit that page again, you display it, and it is exactly how the user left it. Advantage: If your site requires Javascript to operate, then you are not taking a risk by using even more Javascript to accomplish it. Disadvantage: Completely changing the architecture of your site is a LOT of work and can be difficult to get working on older browsers. To get started with this see Unique URLs. You might try out the jQuery hashchange plugin. If your web site has wide distribution you will want to be sure to address search engine optimization and web usability issues. You may want to see this SO page on detecting back button hash changes.
Use the same strategy as in the prior point but instead of doing it with hashtags, use the new HTML5 history.pushState() and history.replaceState() methods--see Mozilla browser history.
If your goal is not 99% compatibility across 99% of the browsers in use, then please let us know what you are aiming at, as there may be a shortcut possible.
Update: added an option #8
Scripting pages doesn't stop at state management. It includes state management.
This means scripted state changes such as scripted page transitions(pages that internally navigate), content panes, popover menus , style changes and of course, form input and selections are all the responsibility of the scripter.
So, in answer to why .. it is because you did not manage the page state you scripted.
If you want your page to work as you seem to expect you can manage the page state changes you script yourself, use a js lib that manages page, or perhaps in your case form, state, or use the http(s) client/server state management and load up the session state, or in your case just the form state, at the server.

JS page formatting is not retained when navigating away from a page and back

I have a bit of an issue with page formatting when I navigate away, and then hit browser back to a page.
Here is an example:
I have security questions on a form in a drop down list like so:
http://i.stack.imgur.com/ib32z.jpg
When the user selects [Type in your own question] from the drop down list, I have some jquery that animates a CSS change that pushes the form down, and makes visible a hidden field for 'custom security question'. When selected, the form looks like this:
http://i.stack.imgur.com/uVPKo.jpg
Now my dilemma is when I navigate away from this page, and then navigate back using the browsers back button, my formatting gets screwed up and looks like this:
http://i.stack.imgur.com/5Xhpi.jpg
The javascript that I have written does not trigger again on the back button so the browser doesn't know to move the form back down to accomodate the change in spacing. Is there anyway I can force the document.ready to reload or clear some kind of cache?
Thanks!
EDIT: Sorry guys, I need to reupload the images to a host and repost. Sorry for the delay.
There are basically four mechanisms for persisting state on the web:
Browser-based - the browser, if you're lucky, will save answers to form fields and re-display them when it sees an INPUT with the same name; also, some browsers will preserve some state between forward<=>back navigation
Cookie-based - pretty self-explanatory; you save a cookie with the state info, and check it later to recover the state
URL-based - navigate to a different hash of your URL, with the info you want in it (eg. "?roll_down=true")
HTML5/Local Storage - Look it up if you're interested :-)
We can basically throw 1 and 4 out, because they both rely too much on browser behavior/support, and we can't reliably rely on all browsers to handle them the way we want. That leaves #2 or #3.
Cookies allow you to save more info (as much as a cookie holds, ie. about 4k). URLs allow less info, but they have the added benefit of bookmark-ability; if the user saves the URL as a bookmark (or as a link they send a friend, or whatever), the state still gets preserved.
So, take your pick of the above, decide on how to persist your "my form is rolled down" state ... and then comes the part that (I think) you're really interested in: how do you check this state and fix things when the user clicks "back"?
That part I humbly defer to another SO post, which has already answered it:
Is there a way to catch the back button event in javascript?

I am using hashes in my url but then my back button is broken

On my website I have some javascript which changes the URL by adding # and some information as the user takes some action.
for example:
www.mysite.com/index.html#shoes=23,books=12
www.mysite.com/index.html#shoes=24,books=12
The website works brilliantly but the back button appears to be broken
When the user presses back I don't want to move back to my previous values on the url with the hash but I really want to go back, like moving away from the page.
Can somebody help ?
This is a feature of the browser: visiting a new URL with a hash is a separate history item. You will not be able to solve this without changing how you handle URLs. From a UI perspective, this seriously makes sense. Imagine if gmail didn't do this (like in the old days). The user experience would be significantly diminished.
Unless this breaks your app, I suggest you leave it as it is; your users will thank you for it.

Categories