Recipe 8.12. Editing Fields in Place


Problem

You want to provide a way to edit some text on a page that avoids the overhead of a traditional web form. An Ajax solution that displays the form elements and saves the edits would be ideal.

Solution

Use Action Controller's in_place_edit_for method with Action View's in_place_editor_field to create a call to a Ajax.InPlaceEditor of the script.aculo.us library.

Set up this example by generating a Book model with:

$ ruby script/generate model Book             

and add the following to the generated migration:

db/migrate/001_create_books.rb:

class CreateBooks < ActiveRecord::Migration   def self.up     create_table :books do |t|       t.column :title, :string     end     Book.create :title => 'Perl Best Practices'     Book.create :title => 'Learning Python'     Book.create :title => 'Unix in a Nutshell'   end   def self.down     drop_table :books   end end

Next, include the script.aculo.us and Prototype libraries in your layout using javascript_include_tag:

app/views/layouts/books.rhtml:

<html>   <head>     <title>Books</title>     <%= javascript_include_tag :defaults %>   </head>   <body>     <%= yield  %>   </body> </html>

Call the in_place_edit_for method in the Books controller, passing the object and object attribute as symbols. The controller also defines index and show methods.

app/controllers/books_controller.rb:

class BooksController < ApplicationController   in_place_edit_for :book, :title   def index     @books = Book.find :all, :order => 'title'   end   def show     @book = Book.find(params['id'])   end end

The default view iterates over the array of books, displaying each as a link to the show action for each.

app/views/books/index.rhtml:

<h1>Books - list</h1> <ul> <% for book in @books %>   <li><%= link_to book.title, :action => 'show', :id => book.id %></li>  <% end %> </ul>

Finally, call the in_place_editor_field in the show.rhtml view helper, passing the object and attribute to be edited:

app/views/books/show.rhtml:

<h1>Books - edit</h1> <b>Title:</b>; <%= in_place_editor_field :book, :title %>;

Discussion

In-place editing, a feature used in the administration of photo collections on Flickr.com, can really speed up simple edits that shouldn't require a full page refresh. Flickr's use of this effect makes a lot of sense because of the cost of refreshing a page full of photos. Instead, Ajax allows you to update several elements per photorequiring very little bandwidth per edit (see Figure 8-12).

The solution demonstrates the relatively large amount of functionality that you get by including only two methods in your application; in_place_edit_for and in_place_editor_field. The default view (index.rhtml) lists the titles in the books table. Clicking a book link calls the show action, which retrieves a single book object, making it available to the show.rhtml view. The text in the show view initially appears in a span tag. Mousing over it highlights the text; clicking the text replaces the span tag with a form input tag. With the text now appearing in a text field, it can be modified and submitted with the OK button. The user can also cancel the action, which returns the text to a span tag.

There a slight usability issue to be aware of with this style of element editingit's often not obvious when in-place editing is enabled. The solution to this problem is to add instructions or images that make it clear that fields are, in fact, editable.

Figure 8-12. Using Ajax to update a page


See Also

  • For more on making an in-place editor, see

    http://api.rubyonrails.com/classes/ActionView/Helpers/JavaScriptHelper.html



Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

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