How does RailsCasts do partial page ajax? - ajax

Railscasts (and I've seen this technique elsewhere) seems to be modifying the URL (by adding/changing a query string) but delivers back an ajax request without reloading the entire page. How are they modifying the URL without triggering a whole page refresh? It doesn't appear at least to be using HTML5 history, since there is no history created (can't go back/forward).
http://railscasts.com/episodes/81-fixtures-in-rails-2-0
Then click any of the tabs "Show Notes", "Comments", "Similar Episodes" and watch how the query string changes, but the page does not refresh (confirmed via Firebug).
Any ideas?

It uses history.replaceState(). Quoth MDC:
history.replaceState() operates exactly like history.pushState() except that replaceState() modifies the current history entry instead of creating a new one.
No new history entry, nothing to go back/forward to.

Related

Does a pages URL change with AJAX?

I'm taking an online course from a site that does not provide for asking questions about the content, so I am asking you.
This is one of the MUSTS for page titles:
"On a so-called single-page application — in which AJAX is used to bring in new content without refreshing or loading the entire web page — any time that the URL changes, the page title should be updated accordingly"
I always thought that if you used ajax to change part of a page the page itself would remain static. That is why would a URL change with an AJAX call. Are there any examples showing what this looks like?
AJAX requests don’t change the browser URL or history. To mimic the behaviour of traditional websites, single page apps will modify the URL and history and use the URL to change the view.
For more on changing the browser history, see Adding and modifying History entries.

Can bookmarket modify original page?

I have a bookmarklet that opens a dialog (in reality an iframe) and extracts some information. When the dialog is dismissed I want to put that information into edit text fields on the original page in the browser (like the way LastPass will automatically fill-in login forms on a page).
Is this possible? I'm thinking that same-origin-policy will prevent this, but maybe there is a way (without installing extensions such as greasemonkey, etc).
Edit: to be more precise: the bookmarklet appends a DIV to the original page; that DIV contains an IFRAME that loads my page; this page fetches some information; once this information is fetched within the IFRAME I want to remove the DIV and (somehow) put that information into the original page.
The issue I face is communicating the information in the IFRAME back to the original page.
What you are looking for are the functions addEventListener and postMessage.
Relevant links:
http://caniuse.com/#feat=x-doc-messaging
How do you use window.postMessage across domains?

Back button to ajax results, advice request

I am trying solve the back button issue within my app. The scenario is:
I have a home page with a search form which sends and receives data with $.ajax(), then the results loaded through ajax, their links points to a controller that won't be done by GET in ajax so that means that the page will be refreshed (so the home page with the results looks like this: http://url/en/home and a result link may look like this http://url/fetch/data/x123av).
The problem is which is the best way fix that when click back button to return the results from the search box?
I have found some answers in stackoverflow related to my question:
http://code.google.com/p/reallysimplehistory
http://tkyk.github.com/jquery-history-plugin
But from the documentation of those plugins, they all work by checking the hash change which I don't have.
Hope I have explained well enough, and I do have searched stackoverflow and google for a solution but I didn't find one that is close to this or either I've jumped over it...
Please just point me to the right way :D
But from the documentation of those plugins, they all work by checking
the hash change which I don't have.
If you want to handle the back button with AJAX request you will have to redesign your application so that it works with hashes as that's the only way. Changing the fragment portion of an url doesn't trigger a page reload but it is added to the history, so when you press the back button you are able to detect this change without navigating away from the page.
As mentioned by SLaks in the comments section another possibility is to use the HTML5 history API but obviously this assumes that the client browser supports it.

"Redirect" page without refresh (Facebook photos style)

I am trying to implement content browsing like it is done on Facebook when user is browsing the photos. I guess everyone is familiar with that photo browsing where you can click "next" and "previous" and immediately get the next or previous photo (you can also navigate using arrow keys).
When you click "next" for example you notice that the page does not refresh - only the content. At first I thought it is done using plain ajax calls which refresh only the "content" in this case the image, description and comments. But then I noticed that also URL in the "Location" toolbar of my browser is changed!
I tried to inspect this using Firebug and discovered that when you click "next" only the next photo is downloaded and I still don't know from where the comments & image meta data (description, time, tags,...) are loaded.
Can someone please explain how this technique is done - page URL changes without page refresh (or even without page "blinking" if it refreshes from cache).
I know how to change page content using ajax but URL of that page stays the same all the time. If I click on "refresh" button I get the first page again. But not on Facebook since even the "window.location" is changed every time without actual redirect.
The other thing I noticed is that the bottom toolbar (applications, chat, ...) is "always on top". Even if you change the page, this toolbar is not refreshed and always stays on top - it doesn't even "blink" like other pages that are refreshed (either from webserver or from local cache). I guess this is the same technique as above - some kind of "fake" redirects or something?
The Answer is pushState
if (window.history.pushState)
window.history.pushState([object or string], [title], [new link]);
You will smile :)
I've tried to change through facebook images, and this is what I saw:
In Firefox:
The page URL is not changing. Only the hash is changing. This is a technique used to allow crawlers to index the content. What happens is this:
User clicks on "next"
JS loads the next image with tags, comments, etc and replaces the old content with them.
JS changes the hash to correspond the new image
urls look like this:
http://www.facebook.com/home.php?#!/photo.php?fbid=1550005942528966&set=a.1514725882151300.28042.100000570788121&pid=3829033&id=1000001570788121 (notice the hash)
As for the second question, this is just a benefit of the technique above. When you are on facebook, the page rarely gets actually refreshed. Only the hash is changed so that you can send links to other people and crawlers can index the content.
In Google Chrome:
It seems that chrome hassome way to change urls without refreshing the page. It does that by using window.history.pushState. Read about it here.
urls look like this: http://www.facebook.com/photo.php?fbid=1613802157224343&set=a.1514725288215100.28042.1000005707388121&pid=426541&id=1000001570788121 (notice that there is no hash here, but still the url is changing along with images)
In Epiphany:
Epiphany doesn't change the URL when the image changes.
urls look like this: http://www.facebook.com/photo.php?fbid=1441817122377521&set=a.1514725882215100.28042.1000005707848121&pid=3251944&id=1000200570788121 (there is no hash, and the URL stays the same when changing the image)
(don't have other browsers to verify right now)
The one technique not mentioned here is the window.onhashchange() method (supported in ie8+ and most others) which they might have used
You may noticed that the page url remain the same. What is changed, however, is page hash (the part after # in the url).
You need something like this: http://code.google.com/p/reallysimplehistory/

Modify Address Bar URL in AJAX App to Match Current State

I'm writing an AJAX app, but as the user moves through the app, I'd like the URL in the address bar to update despite the lack of page reloads. Basically, I'd like for them to be able to bookmark at any point and thereby return to the current state.
How are people handling maintaining RESTfulness in AJAX apps?
The way to do this is to manipulate location.hash when AJAX updates result in a state change that you'd like to have a discrete URL. For example, if your page's url is:
http://example.com/
If a client side function executed this code:
// AJAX code to display the "foo" state goes here.
location.hash = 'foo';
Then, the URL displayed in the browser would be updated to:
http://example.com/#foo
This allows users to bookmark the "foo" state of the page, and use the browser history to navigate between states.
With this mechanism in place, you'll then need to parse out the hash portion of the URL on the client side using JavaScript to create and display the appropriate initial state, as fragment identifiers (the part after the #) are not sent to the server.
Ben Alman's hashchange plugin makes the latter a breeze if you're using jQuery.
Look at sites like book.cakephp.org. This site changes the URL without using the hash and use AJAX. I'm not sure how it does it exactly but I've been trying to figure it out. If anyone knows, let me know.
Also github.com when looking at a navigating within a certain project.
It is unlikely the writer wants to reload or redirect his visitor when using Ajax.
But why not use HTML5's pushState/replaceState?
You'll be able to modify the addressbar as much as you like. Get natural looking urls, with AJAX.
Check out the code on my latest project:
http://iesus.se/
This is similar to what Kevin said. You can have your client state as some javascript object, and when you want to save the state, you serialize the object (using JSON and base64 encoding). You can then set the fragment of the href to this string.
var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;
document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history
The first way will treat the new state as a new location (so the back button will take them to the previous location). The latter does not.
SWFAddress works in Flash & Javascript projects and lets you create bookmarkable URLs (using the hash method mentioned above) as well as giving you back-button support.
http://www.asual.com/swfaddress/
The window.location.hash method is the preferred way of doing things. For an explanation of how to do it,
Ajax Patterns - Unique URLs.
YUI has an implementation of this pattern as a module, which includes IE specific work arounds for getting the back button working along with re-writing the address using the hash. YUI Browser History Manager.
Other frameworks have similar implementations as well. The important point is if you want the history to work along with the re-writing the address, the different browsers need different ways of handling it. (This is detailed in the first link article.)
IE needs an iframe based hack, where Firefox will produce double history using the same method.
If OP or others are still looking for a way to do modify browser history to enable state, using pushState and replaceState, as suggested by IESUS, is the 'right' way to do it now. It's main advantage over location.hash seems to be that it creates actual URLs, not just hashes. If browser history using hashes is saved, and then revisited with JavaScript disabled, the app won't work, since the hashes aren't sent to the server. However, if pushState has been used, the entire route will be sent to the server, which you can then build to respond appropriately to the routes. I saw an example where the same mustache templates were used on both the server and the client side. If the client had JavaScript enabled, he would get snappy responses by avoiding the roundtrip to the server, but the app would work perfectly fine without the JavaScript. Thus, the app can gracefully degrade in the absence of JavaScript.
Also, I believe there is some framework out there, with a name like history.js. For browsers that support HTML5, it uses pushState, but if the browser doesn't support that, it automatically falls back to using hashes.
Check if user is 'in' the page, when you click on the URL bar, JavaScript says you are out of page.
If you change the URL bar and press 'ENTER' with the symbol '#' within it then you go into the page again, without click on the page manually with mouse cursor, then a keyboard event command (document.onkeypress) from JavaScript will be able to check if it's enter and active the JavaScript for redirection.
You can check if user is IN the page with window.onfocus and check if he's out with window.onblur.
Yeah, it's possible.
;)

Resources