AJAX in Rails 4, HTML5 history API and caching - ruby-on-rails

I'm moving a Rails app which loads new views through URLs to a completely AJAX version. The way we're doing this is that loading all views through AJAX and changing the URL through HTML5 History API. We also want to use HTTP caching throughout so that we can cache each partial.
But now we're stuck on one issue. There are now essentially two ways to load each page - through the URL or by clicking on something which loads that partial via AJAX. But this has lead us to create two different views and controllers for essentially loading the same thing - one directly from URL and one by clicking in the main page and loading via AJAX and history API. So how do we ensure that the same view loads from the browser cache when loading directly via URL and with AJAX?
To give an example, GitHub uses in their tree slider. You can access code directly by browsing to it in the window or directly using the URL path for it. I'm sure if the page has been loaded before, they get parts of it from the browser cache.
Is there a way to send requests to the same URL but just render a partial or load the whole page depending on whether the request is sent by clicking on the tab or entered in the address bar? It should use cached partials if they are already there in the browser.
Thanks

If I got it right you want to have different behaviours for the same action, one if the request is get and other one with an ajax request.
You can do it doing this:
mypage_controller.rb
def my_page
...(your logic here)
respond_to do |format|
format.js
format.html
end
end
my_page.js.erb
alert('testing');
.... (further ajax code here)
Here is an article that does this behaviour Rails 4: How to partials & AJAX, dead easy
This way you can have the same action responding for ajax and get request

Related

Refreshing page from browser (Backbone.js and ASP.NET MVC)

I have a single page application with several controllers and actions in each controller all of which return a json result if the page is accessed from a mobile device.
Backbone than loads the correct view according the specified url and parses the json. Using underscore.js than I am compiling the template and finally showing it inside a div.
This works fines until I refresh the browser. On refresh the action from the REST application is sending the JSON back to the browser but obviously without loading any templates.
Is there a workaround to this problem for example I have tried Redirecting to the index page with a hash behind it ("Index#MyPage").
In this case backbone loads the Index page than recognizes that it needs to go the "MyPage" route and load it's Json (and it does), but the template is still not being loaded.

How to build Preview functionality before form submit in Rails ?

I have a simple scaffold and I want the user to see (preview) the form data before he submits it. It looks to be fairly straight forward problem but surprisingly I am not able to figure out how to do it. I found this but it looks to be somewhat dated (2010 question)
Is there any gem or jquery plugin which can simplify this preview functionality ? any suggestions on how to do it in rails 3.2.x ?
Thanks
It really depends on what kind of "preview" you want to include - either "preview page" or "rendered fragment":
Preview page is what some services are showing: summary of all inputs shown in form of separate page with button "confirm". It doesn't require javascript or anything fancy - just click "next" on form page, see data typed just a second ago and click "confirm" or "back to edit". If this is what you require then you can do it simply by creating new controller action(preview?) which would initialize model with passed parameters(just like "create" action would, but without saving) and generate template with "preview" shown and hidden form that will be passed to "create" action after clicking "confirm". Alternatively you can simply modify "new" form so it would hide form depending on called action and show preview instead.
Second option is "render fragment" - it will live-update part of your current page via javascript. Depending on how complicated this view will be and what kind of operations you will need to do before showing template it might be good to use some javascript plugin or send request to server and obtain rendered partial. In former case you can select from very easy implementations(like this) up to complete solutions dedicated to it. On the other hand if you choose to render it on server then simple ajax request with all params of form should be enough to provide you with HTML output that can be put directly into DOM element.
I don't know about any gem which can do that.
I think showing a modal with jquery and getting data from data-elements is a simple way to go.

jQuery Mobile and Rails RESTful actions

I'm having a problem with how jQuery mobile works with RESTful actions in Rails.
For this explaination, let's assume I have a resource called Planet and a PlanetsController and I'm attempting to create a new Planet by sending a post request from /planets/new to /planets. If this action succeeds, my URL is now /planets even though it's actually showing /planets/1. If the action failed, my URL is also now /planets/ instead of /planets/new.
In both of these cases, if I click the Back button to go back to the index action, it won't work because jQuery Mobile thinks I'm already on /planets. I have to reload the page in order to get back.
Is there a way to fix this so normal Rails RESTful actions can be used?
I had the same issue as well, I just added data-ajax = "false" to my form with the downside of having no transitions. Or you can follow another solution I found here: http://www.adobe.com/devnet/html5/articles/jquery-mobile-and-rails.html#articlecontentAdobe_numberedheader_1

Grails: Rendering two Views simultaneously with one Controller Action

One action of one of my controllers needs to generate(redirect/render) two separate views simultaneously and show both the pages to the client. It will be like when the user submits his info, the page will redirect to a new page with a list. At the same time another page needs to pop up in a new window containing some additional info (user would print this page). I know, I can resolve the issue with a single page, but I was wondering whether there is any ways to produce two separate pages/windows simultaneously from a single controller action.
Thanks in anticipation
The simple answer is NO. Grails isn't doing anything magical. It's still constrained to normal HTTP request/response lifecycle. A single request gets a single response. What you're asking for sounds like you want grails to be able to generate 2 responses for a single HTTP request which is impossible. The response is either a page for the browser to render or it's a redirect message for the browser to go to another URL.
You could write your action that it can handle normal and ajax requests. See the docs here:
Responding to both Ajax and non-Ajax requests
Then you could generate your "normal" view. After that you call the same action by using ajax on the client side and load the data for your pop up page.
why not use a <script>window.open()</script> in your main view in order to open the popup?

#rails_folks | ''http://twitter.com/#!/user/followers" | Please explain

How would you achieve this route in rails 3 and the last stable version 2.3.9 or soish?
Explained
I don't really care about the followers action. What I'm really after is how to create '!#' in the routing.
Also, What's the point of this. Is it syntax or semantics?
Rails doesnt directly get anything after the #. Instead the index page checks that value with javascript and makes an AJAX request to the server based on the url after the #. What routes they use internally to handle that AJAX request I am not sure.
The point is to have a Javascript powered interface, where everyone is on the same "page" but the data in the hashtag allows it to load any custom data on the fly, and without loading a whole new page if you decide to view a different user, for instance.
The hash part is never sent to the URL, but it is a common practice to manipulate the hash to maintain history, and bookmarking for AJAX applications. The only problem being that by using a hash to avoid page reloads, search engines are left behind.
If you had a site with some links,
http://example.com/#home
http://example.com/#movies
http://example.com/#songs
Your AJAXy JavaScript application sees the #home, #movies, and #songs, and knows what kind of data it must load from the server and everything works fine.
However, when a search engine tries to open the same URL, the hash is discarded, and it always sends them to http://example.com/. As a result the inner pages of your site - home, movies, and songs never get indexed because there was no way to get to them until now.
Google has creating an AJAX crawling specification or more like a contract that allows sites to take full advantage of AJAX while still reaping the benefits of indexing by searching engines. You can read the spec if you want, but the jist of it is a translation process of taking everything that appears after #! and adding it as a querystring parameter.
So if your AJAX links were using #!, then a search engine would translate a URL like,
http://example.com/#!movies
to
http://example.com/?_escaped_fragment_=movies
Your server is supposed to look at this _escaped_fragment_ parameter and respond the same way that your AJAX does.
Note that HTML5's History interface now provides methods to change the address bar path without needing to rely upon the hash fragment to avoid page reloads.
Using the pushState and popState methods
history.pushState(null, "Movies page", "/movies");
you could directly change the URL to http://example.com/movies without causing a page refresh. Search engines can continue to use the same URL that you would be using in that case.
The part after the # in a URI is called the fragment identifier, and it is interpreted by the client, not the server. You cannot route this, because it will never leave the browser.

Resources