aboutsummaryrefslogtreecommitdiffstats
path: root/railties/guides/source/ajax_on_rails.textile
diff options
context:
space:
mode:
Diffstat (limited to 'railties/guides/source/ajax_on_rails.textile')
-rw-r--r--railties/guides/source/ajax_on_rails.textile76
1 files changed, 68 insertions, 8 deletions
diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile
index 8b72e20c33..3a0ccfe9b2 100644
--- a/railties/guides/source/ajax_on_rails.textile
+++ b/railties/guides/source/ajax_on_rails.textile
@@ -3,7 +3,7 @@ h2. AJAX on Rails
This guide covers the built-in Ajax/JavaScript functionality of Rails (and more); it will enable you to create rich and dynamic AJAX applications with ease! We will cover the following topics:
* Quick introduction to AJAX and related technologies
-* Handling JavaScript the Rails way: Rails helpers, Prototype and script.aculo.us
+* Unobtrusive JavaScript helpers with drivers for Prototype, jQuery etc
* Testing JavaScript functionality
endprologue.
@@ -24,20 +24,80 @@ h4. Standard HTML communication vs AJAX
How do 'standard' and AJAX requests differ, why does this matter for understanding AJAX on Rails (tie in for *_remote helpers, the next section)
+h3. Built-in Rails Helpers
+Rails 3.1 ships with "jQuery":http://jquery.com as the default JavaScript library. The Gemfile contains <tt>gem 'jquery-rails'</tt> which makes the jQuery files available to the application automatically. This can be accessed as:
+<ruby>
+javascript_include_tag :defaults
+</ruby>
+h4. Examples
+All the remote_method helpers has been removed. To make them working with AJAX, simply pass the <tt>:remote => true</tt> option to the original non-remote method.
-h3. Built-in Rails Helpers
+<ruby>
+button_to "New", :action => "new", :form_class => "new-thing"
+</ruby>
+
+will produce
-Rails' JavaScript framework of choice is "Prototype":http://www.prototypejs.org. Prototype is a generic-purpose JavaScript framework that aims to ease the development of dynamic web applications by offering DOM manipulation, AJAX and other JavaScript functionality ranging from utility functions to object oriented constructs. It is not specifically written for any language, so Rails provides a set of helpers to enable seamless integration of Prototype with your Rails views.
+<html>
+<form method="post" action="/controller/new" class="new-thing">
+ <div><input value="New" type="submit" /></div>
+</form>
+</html>
-To get access to these helpers, all you have to do is to include the prototype framework in your pages - typically in your master layout, application.html.erb - like so:
<ruby>
-javascript_include_tag 'prototype'
+button_to "Create", :action => "create", :remote => true, :form => { "data-type" => "json" }
</ruby>
+will produce
+
+<html>
+<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
+ <div><input value="Create" type="submit" /></div>
+</form>
+</html>
+
+<ruby>
+button_to "Delete Image", { :action => "delete", :id => @image.id },
+ :confirm => "Are you sure?", :method => :delete
+</ruby>
+
+will produce
+
+<html>
+<form method="post" action="/images/delete/1" class="button_to">
+ <div>
+ <input type="hidden" name="_method" value="delete" />
+ <input data-confirm='Are you sure?' value="Delete" type="submit" />
+ </div>
+</form>
+</html>
+
+<ruby>
+button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
+ :method => "delete", :remote => true, :disable_with => 'loading...')
+</ruby>
+
+will produce
+
+<html>
+<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
+ <div>
+ <input name='_method' value='delete' type='hidden' />
+ <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
+ </div>
+</form>
+</html>
+
+You can also choose to use Prototype instead of jQuery and specify the option using +-j+ switch while generating the application.
+
+<shell>
+rails new app_name -j prototype
+</shell>
+
You are ready to add some AJAX love to your Rails app!
h4. The Quintessential AJAX Rails Helper: link_to_remote
@@ -59,7 +119,6 @@ link_to_remote "Add to cart",
</ruby>
* The very first parameter, a string, is the text of the link which appears on the page.
-
* The second parameter, the +options+ hash is the most interesting part as it has the AJAX specific stuff:
** *:url* This is the only parameter that is always required to generate the simplest remote link (technically speaking, it is not required, you can pass an empty +options+ hash to +link_to_remote+ - but in this case the URL used for the POST request will be equal to your current URL which is probably not your intention). This URL points to your AJAX action handler. The URL is typically specified by Rails REST view helpers, but you can use the +url_for+ format too.
** *:update* Specifying a DOM id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this - however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation:
@@ -109,7 +168,7 @@ Note that if we wouldn't override the default behavior (POST), the above snippet
link_to_remote "Update record",
:url => record_url(record),
:method => :put,
- :with => "'status=' + 'encodeURIComponent($('status').value) + '&completed=' + $('completed')"
+ :with => "'status=' <plus> 'encodeURIComponent($('status').value) <plus> '&completed=' <plus> $('completed')"
</ruby>
This generates a remote link which adds 2 parameters to the standard URL generated by Rails, taken from the page (contained in the elements matched by the 'status' and 'completed' DOM id).
@@ -129,6 +188,7 @@ link_to_remote "Add new item",
404 => "alert('Item not found!')"
</ruby>
Let's see a typical example for the most frequent callbacks, +:success+, +:failure+ and +:complete+ in action:
+
<ruby>
link_to_remote "Add new item",
:url => items_url,
@@ -138,6 +198,7 @@ link_to_remote "Add new item",
:success => "display_item_added(request)",
:failure => "display_error(request)"
</ruby>
+
** *:type* If you want to fire a synchronous request for some obscure reason (blocking the browser while the request is processed and doesn't return a status code), you can use the +:type+ option with the value of +:synchronous+.
* Finally, using the +html_options+ parameter you can add HTML attributes to the generated tag. It works like the same parameter of the +link_to+ helper. There are interesting side effects for the +href+ and +onclick+ parameters though:
** If you specify the +href+ parameter, the AJAX link will degrade gracefully, i.e. the link will point to the URL even if JavaScript is disabled in the client browser
@@ -193,7 +254,6 @@ end
What happens here is that by specifying the Content-Type header variable, we instruct the browser to evaluate the text we are sending over (rather than displaying it as plain text, which is the default behavior).
-
h3. Testing JavaScript
JavaScript testing reminds me the definition of the world 'classic' by Mark Twain: "A classic is something that everybody wants to have read and nobody wants to read." It's similar with JavaScript testing: everyone would like to have it, yet it's not done by too much developers as it is tedious, complicated, there is a proliferation of tools and no consensus/accepted best practices, but we will nevertheless take a stab at it: