Creating an Ajax Form

Problem

You want to build a web application thats responsive and easy to use. You don want your users to spend lots of time waiting around for the browser to redraw the screen.

Solution

You can use JavaScript to make the browsers XMLHTTPRequest object send data to the server, without dragging the user through the familiar (but slow) page refresh. This technique is called Ajax,[6] and Rails makes it easy to use Ajax without writing or knowing any JavaScript.

[6] This doesn quite stand for Asynchronous JavaScript and XML. The origins of the term Ajax are now a part of computing mythology, but it is not an acronym.

Before you can do Ajax in your web application, you must edit your applications main layout template so that it calls the javascript_include_tag method within its tag. This is the same change made in Recipe 15.15:

	

	
	 
	 My Web App
	 <%= javascript_include_tag "prototype", "effects" %>
	 
	 
	 <%= @content_for_layout %>
	 
	

Lets change the application from Recipe 15.16 so that the new action is AJAXenabled (if you followed that recipe all the way through, and made the edit action use new.rhtml instead of edit.rhtml, youll need to undo that change and make edit use its own view template).

Well start with the view template. Edit app/views/items/new.rhtml to look like this:

	
	
	
	 <%= form_remote_tag :url => { :action => :create },
	 :update => "show_item",
	 :complete => visual_effect(:highlight, "show_item") %>

	 Name: <%= text_field "item", "name" %>
Value: <%= text_field "item", "value" %>
<%= submit_tag %> <%= end_form_tag %>

Those small changes make a standard HTML form into an Ajax form. The main difference is that we call form_remote_tag instead of form_tag. The other differences are the arguments we pass into that method.

The first change is that we put the :action parameter inside a hash passed into the :url option. Ajax forms have more options associated with them than a normal form, so you can describe its form action as simply as you can with form_tag.

When the user clicks the submit button, the form values are serialized and sent to the destination action (in this case, create) in the background. The create action processes the form submission as before, and returns a snippet of HTML.

What happens to this HTML? Thats what the :update option is for. It tells Rails to take the result of the form submission, and stick it into the element with the HTML ID of "show_item". This is why we added that tag to the top of the template: thats where the response from the server goes.

The last change to the new.rhtml view is the :complete option. This is a callback argument: it lets you specify a string of JavaScript code that will be run once an Ajax request is complete. We use it to highlight the response from the server once it shows up.

Thats the view. We also need to modify the create action in the controller so that when you make an Ajax form submission, the server returns a snippet of HTML. This is the snippet thats inserted into the "show_item" element on the browser side. If you make a regular (nonAjax) form submission, the server can behave as it does in Recipe 15.16, and send an HTTP redirect.[7] Heres what the controller class needs to look like:

[7] This will happen if someones using your application with JavaScript turned off.

	class ItemsController < ApplicationController
	 def new
	 @item = Item.new
	 end
	
	 def create
	 @item = Item.create(params[:item])
	 if request.xml_http_request?
	 render :action => show, :layout => false
	 else
	 redirect_to :action => edit, :id => @item.id
	 end
	 end
	
	 def edit
	 @item = Item.find(params[:id])

	 if request.post?
	 @item.update_attributes(params[:item])
	 redirect_to :action => edit, :id => @item.id
	 end
	 end
	end

This code references a new view, show. Its the tiny HTML snippet thats returned by the server, and stuck into the "show_element" tag by the web browser. We need to define it:

	
	
	Your most recently created item:
Name: <%= @item.name %>
Value: <%= @item.value %>


Now when you use http://localhost:3000/items/new to add new items to the database, you won be redirected to the edit action. Youll stay on the new page, and the results of your form submission will be displayed above the form. This makes it easy to create many new items at once.

Discussion

Recipe 15.16 shows how to submit data to a form in the traditional way: the user clicks a "submit" button, the browser sends a request to the server, the server returns a response page, and the browser renders the response page.

Recently, sites like Gmail and Google Maps have popularized techniques for sending and receiving data without a page refresh. Collectively, these techniques are called Ajax. Ajax is a very useful tool for improving your applications response time and usability.

An Ajax request is a real HTTP request to one of your applications actions, and you can deal with it as you would any other request. Most of the time, though, you won be returning a full HTML page. Youll just be returning a snippet of data. The web browser will be sending the Ajax request in the context of a full web page (which you served up earlier) that knows how to handle the response snippet.

You can define JavaScript callbacks at several points throughout the lifecycle of an Ajax request. One callback, :complete, was used above to highlight the snippet after inserting it into the page. This table lists the other callbacks.

Table 15-2.

Callback name

Callback description

:loading

Called when the web browser begins to load the remote document.

:loaded

Called when the browser has finished loading the remote document.

:interactive

Called when the user can interact with the remote document, even if it has not finished loading.

:success

Called when the XMLHttpRequest is completed, and the HTTP status code is in the 2XX range.

:failure

Called when the XMLHttpRequest is completed, and the HTTP status code is not in the 2XX range.

:complete

Called when the XMLHttpRequest is complete. If :successand/or :failure are also present, runs after they do.




Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net