How to avoid ajax reload when you click the back button - javascript

I have a page that used Ajax to generate the a list of result. Then there is a link to click to another detail page. When I'm at the detail page, and click the back button. The list of results page will reload again. Is there anyway to stop the ajax to reload again and cache the result. Also is there anyway to cache the position also.
thank you for your help

A few projects I had bookmarked regarding the AJAX/back button management
https://github.com/browserstate/history.js
https://github.com/tkyk/jquery-history-plugin
Regarding your second question, if your browser supports local DB you may cache the result there. The following project provide a uniform API across browsers.
https://github.com/marcuswestin/store.js
https://github.com/alexmng/sticky
Position can also be stored in the localDB.

You can save state by changing the window.location.hash property. The hash is the only part of the URL that you can change and not force a reload of the URL.
window.location.hash = 'some-id'; will translate into your URL looking like this: index.html#some-id.
You can then get the hash when the page loads and set the UI to the proper state:
if (window.location.hash == 'some-id') {
//setup UI for `some-id` identifier
}

https://developer.mozilla.org/en/DOM/Storage
Store your data with a timestamp of some sort. Check to see if you have stored data and that it's not older than you would like it to be. If it's older, fetch new data. If not use the stored data.
(it's not mozilla specific)
http://caniuse.com/#search=local%20storage

You can use the new HTML5 LocalStorage system to build a cache. Here's a link: http://playground.html5rocks.com/#localstorage

Related

How to change browser url without changing anything in history

You might think this is a duplicate, but it's not. I've seen the other SO answers about changing the browser url with replaceState() but I have a problem...
On one webpage on my website, it receives a lot of parameters, so the link goes on and on and on... I did replaceState(), and it shortened the URL by a lot. That worked. If I go on another link, and I go back in history, the URL will still be the same that I defined on replaceState() and the page gives a 404 error. Is there a way to just load the link the way it is and then temporarily change the URL so the user doesn't see a huge link but the system uses the actual URL?
I'm using JSP, go ahead and give me answers in JavaScript, JQuery, or Java.
You could store the parameters in localstorage (ie a cookie) then have your next page un-pick them from localstorage, thus reducing the size needed of the URL in the frst place. Example code (stolen from Storing Objects in HTML5 localStorage) :
// add to storage
localStorage.setItem('myAttibute', 'acceptable');
// Retrieve the object from storage (on another page)
var sMyAttibute= localStorage.getItem('myAttibute');
alert("myAttibute=" + sMyAttibute);
Hopefully it'll tell you that my attribute is acceptable.

"last-update" time of an html document

This question is about pages like gmail or Facebook, which keep updating lively all the time.
If in a browser, such as UIWebView in iOS, where the live feeds do not seem to appear automatically, I wish to reload the page only if it was updated on the server. For this, is there a way to obtain last-update time of the document, something like the output of the unix command
ls -ltr filename
for an html document on the web server?
Or in general, how is this kind of problem tackled?
Thanks in advance,
Nikhil
Try this JS snippet:
javascript:alert(document.lastModified)
I would however suggest to implement something yourself as this may not give you accurate result all the time. You can generate a hash of some part of the live feeds and save the hash. Next time re-generate the hash and compare that hash with the saved hash and if the hash doesn't match, it means the content of the feeds has changed. Trigger the update method to fetch new live feeds and replace the old hash with the new hash in your local database.
I hope it helps.

(Temp) Storage of JSON Search Results in Web App

I'm working on a search function for my Web app (HTML, JS & CSS only). I'm using jQuery's .getjson() method to retrieve data from a feed and display those results on a page. Inside of an .each() statement I'm adding HTML markup to the results making some of the elements links to outside sources.
The issue is when a visitor initiates a search on my Web app and clicks on a link from the results to an outside page, then uses the Back button on the browser to go back to the results page, all of the search results are cleared and another search needs to be initiated.
I'd like to temporarily save the search results so if a user clicks on a link from the results, then presses the Back button to come back to the app, all of the results will be available without the new for another search.
Taking this one step further, it would also be cool is the results for past searchs also persists so if the visitor continues to press the Back button, they can see all of their previous searches (with a given limit of course).
HTML5 sessionStorage seems to be ideal for this, but the information that I found points to a tedious coding solution. Can't I just save all of the json results as a JS object and have them re-rendered by my each statement when the visitor presses the Back button? I'm definitely open to using a code library or plugin for this problem.
http://brian.io/lawnchair/ is a good little library for API for persistence. You can use the same syntax as an abstraction for different storage options http://brian.io/lawnchair/adapters/
You have two ways to approach this issue, one is caching the results on your server and populating the view on-demand, and number two is like you previously mentioned - use sessionStorage. sessionStorage (IMO) has a very straightforward API. You can either use sessionStorage.setItem(key, value) or sessionStorage.getItem(key) -- other methods are available as well such as sessionStorage.key(index), sessionStorage.removeItem(key) and sessionStorage.clear(). It would probably be useful to include a cross-browser polyfill solution for sessionStorage, you can check out the "Web Storage" polyfills section at Modernizr: https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills -- Have fun :-/
Off the top of my head:
Every time the user searches, change the hash in the url to a unique string (e.g. 'search-{userInput}' ... you could of course just forget about the 'search-', but I like my urls in pretty). This should give you back-button support. Then:
Alternative A:
Listen for the hashChange Event, parse the window.location.hash and resend the request to your search URL. Theoretically, unless adding the timestamp to the URL or crazy stuff like that, the caching mechanism of your browser should kick in here. If not, it means an additional request, but that should be ok, shouldn't it?
Alternative B:
Extend your existing search query mechanism by caching the results to localStorage (just don't forget to JSON.stringify it beforehand and use a something-{timestamp} key). Then listen for the hashChange Event and pull the results from your localStorage. Personally, I wouldn't recommend this solution as you're clogging up the localStorage (afaik there's a limit at 2.5mB for some browsers).
You're probably going to have to find ways to circumvent missing browser support for at least the hashChange Event, JSON stringify/parse and LocalStorage, but I'm optimistic that there are enough libs/plugins out there by now.
You think too complicated: your search form most likely does not change the url! Use GET instead of POST and you have the desired result. Right now the browser has no way of knowing which state of the website you want to show and by default shows the first - the empty search form
Caching could be added as suggested, but that really is not the problem here

changing window.location without triggering refresh

I have an AJAX form that submits GET requests. Because these are all GET requests these should be easily bookmark-able. Preferably I'd make my Ajax request, update the screen and then update window.location.href to be the URL for the new page.
Unfortunately this reloads the page. Is there any way I can get around this? Basically I'd like the URL bar to be a permalink bar, but it needs to be able to change to keep up with the state of the page.
window.location.hash is no good because that doesn't get sent to the server.
window.history.replaceState( {} , title, new_URL );
This will update the current page URL with a new one without refreshing.
Arguments:
Data object (must be one that could be serialized to text)
The new title of the changed window URL
The URL to change to (without refreshing)
The you could use the window.onpopstate = function(event){...} to listen to events when a user goes back or forward in the browser history and change things however you wish.
The hash is the way to go. Because, as you point out, changes to the hash don't get sent to the server, you have to send an async request to the server as well as updating the hash.
As a simple example, if your URL is http://server.com/page?id=4, when the user triggers the action you send an AJAX request for http://server.com/page?id=4, and set the page URL to http://server.com/page#id=4.
Furthermore, you have to have something to restore the state if the user reloads. This would usually be done by reading the hash value client-side and sending an async request to the server based on the state represented by the hash value.
if you want to do which works in current browser, you can't change window.location.href without reloading the page
your only option is to to change window.location.hash.
you can do that each time you make an ajax call. if you're using jquery, you can bind a function which update the hash each time an ajax call is made.
if you choose that you'll have to look for the hash on page load (actually don't know/think you can do that server side) and make that call to have your page on the state corresponding to the hash.
-- update
there is now an API which provide this functionality look for history.pushState, history.replaceState and window.onpopstate : https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries
it's not availlable everywhere yet ( http://caniuse.com/#feat=history ), there is a few polyfill that you can use for the moment that will use this API if it's available and fall back using the url hash
Consider this JavaScript library: https://github.com/browserstate/history.js
Use jquery. It can do ajax requests. You cant use window.location because that is made to change the url.

Could a page display diferrent content if the URL hash changes?

How could a page display different content based on the URL hash?
I'm not talking about the browser scrolling down to display the anchored section, but something like JavaScript reacting to that hash and loading different content via AJAX.
Is this common or even probable?
Oh yes - it's becoming a common pattern to handle page-state-to-URL persistence when content is AJAX driven.
Javascript can access this value via window.location.hash. Once that's done, you can perform any actions based on the value of that hash
Show/hide nodes
Makes other AJAX calls
Change page titles or colors
Swap images
etc
Really, any DHTML effect.
This is occasionally done. Youtube uses hashes to link to specific timestamps within a video.
EDIT: I had assumed that you might have an issue where if the user goes up and manually edits the hash in the address bar, the page doesn't reload and even javascript will not know that it changed. I was wrong. I tried it on Youtube it works.
I just built a system to do this a few weeks ago
depeding on the browser you need to detect the hash, heres how to do that
// test all possible places hash could be on different browsers
if(window.location.hash){
hash = window.location.hash;
} else if (document.location.hash){
hash = document.location.hash;
} else if (location.hash){
hash = location.hash;
}
// some browsers start the hash with #, remove it for consistency
if(hash.substring(0,1) == '#'){
hash = hash.substring(1,hash.length);
}
Then handle the value of the hash variable to trigger page changes as you please.
for example:
http://www.example.com#pageA
if(hash = 'pageA'){
document.getElementById('mainContentDiv').innerHTML = '<p> content for the page displayed when the hash sais pageA</p>';
}
Sammy is a javascript library that does just this.
As JavaScript has access to the URL-string it could of course act differently on the contents of the url.
I've occassionally seen something like this but I don't think that this is a good way to react unless in very specific uses.
One of the uses I remember was TiddlyWiki using the after-portion of the hash to set preferences for the page rendering and such.
It is fairly common among AJAX-heavy applications (think Gmail) to be able to have all the AJAXy stuff while still making it possible for you to bookmark a particular page or link someone to a particular page. If they didn't do this, it would be considered bad for usability. It is fairly easy to get the URL hash by doing window.location.hash - so you can then have a switch-like statement on page load to execute a particular set of Javascript functions if a hash is present.
Some jQuery plugins that achieve this functionality: history/remote, history.
The answer for this question will be more or less the same as my answers for these questions:
How to show Ajax requests in URL?
How does Gmail handle back/forward in rich JavaScript?
In summary, two projects that you'll probably want to look at which explain the whole hashchange process and using it with ajax are:
jQuery History (using hashes to manage your pages state and bind to changes to update your page).
jQuery Ajaxy (ajax extension for jQuery History, to allow for complete ajax websites while being completely unobtrusive and gracefully degradable).

Categories

Resources