ajax rails

54
Ajax on Rails Stuart Halloway and Justin Gehtland Copyright 2005-6 Relevance, LLC Ajax on Rails www.codecite.com Slide 1 of 54

Upload: hot

Post on 15-May-2015

2.417 views

Category:

Technology


2 download

DESCRIPTION

a very good ajax use in the rails

TRANSCRIPT

Page 1: Ajax Rails

Ajax on Rails

Stuart Halloway and Justin GehtlandCopyright 2005-6 Relevance, LLC

Ajax on Rails www.codecite.comSlide 1 of 54

Page 2: Ajax Rails

License To Sample Code

This presentation is Copyright 2005-6, Relevance LLC. You may use any code you find here, subject to the terms below. If you want to deliver this presentation, please send email to [email protected] for permission and details.Sample code associated with this presentation is Copyright (c) 2005-6 Relevance, LLC (www.relevancellc.com), unless otherwise marked. Code citations from other projects are subject to the license(s) appropriate to those projects. You are responsible for complying with licenses for code you use.Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Ajax on Rails www.codecite.comSlide 2 of 54

Page 3: Ajax Rails

Rails's Role in Ajax

Ajax on Rails www.codecite.comSlide 3 of 54

Page 4: Ajax Rails

Agenda

Prototype Support

Ajax requests

auto-update

UI observers

Scriptaculous Helpers

effects

widgets

JavaScript Generation

JavaScriptGenerator

rjs

JSONAjax on Rails www.codecite.comSlide 4 of 54

Page 5: Ajax Rails

What is Prototype?

Core Support for Dynamic Web Apps

Hides Browser Oddities

Used by Scriptaculous and Rico

Driven and Inspired by Ruby on Rails

Simple and Elegant

Ajax on Rails www.codecite.comSlide 5 of 54

Page 6: Ajax Rails

Prototype's Role in Ajax

Ajax on Rails www.codecite.comSlide 6 of 54

Page 7: Ajax Rails

Example: Ajax Search

Create a No-Op Form

Prototype Helper Observes User Action

Prototype Helper Submits Ajax Request

Server Renders a Partial

Update innerHTML of a Single Page Element

Ajax on Rails www.codecite.comSlide 7 of 54

Page 8: Ajax Rails

Creating a No-Op Form

<%= start_form_tag('javascript:void%200', {:method=> 'filter'}) %>

Ajax on Rails www.codecite.comSlide 8 of 54

Page 9: Ajax Rails

Observing a Field By DOM ID

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Ajax on Rails www.codecite.comSlide 9 of 54

Page 10: Ajax Rails

Frequency to Check for Field Changes

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Ajax on Rails www.codecite.comSlide 10 of 54

Page 11: Ajax Rails

DOM ID to Update With Results

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Ajax on Rails www.codecite.comSlide 11 of 54

Page 12: Ajax Rails

Show/Hide Progress Indicator

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Ajax on Rails www.codecite.comSlide 12 of 54

Page 13: Ajax Rails

Query Parameters

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Ajax on Rails www.codecite.comSlide 13 of 54

Page 14: Ajax Rails

Server URL

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Ajax on Rails www.codecite.comSlide 14 of 54

Page 15: Ajax Rails

Why Full Path?

<%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>"Element.hide('spinner')", :before=>"Element.show('spinner')", :with=>"'search=' + encodeURIComponent(value)", :url=>{:action=>'search', :only_path => false} %>

Pragforms Intended for Cross-Site Scripting

Most Ajax Apps Will Not Need This

Ajax on Rails www.codecite.comSlide 15 of 54

Page 16: Ajax Rails

Rendered HTML + JavaScript

<input id="search" name="search" type="text" value="" /><script type="text/javascript">//<![CDATA[new Form.Element.Observer('search', 0.5, function(element, value) { Element.show('spinner'); new Ajax.Updater('ajaxWrapper', 'http://localhost:3010/user/search', { onComplete:function(request){ Element.hide('spinner'); }, parameters:'search=' + encodeURIComponent(value) })})//]]></script>

Ajax on Rails www.codecite.comSlide 16 of 54

Page 17: Ajax Rails

Server Side Renders a Partial

def search if params[:search] && params[:search].size>0 @user_pages, @users = paginate :users, :per_page => 10, :order => order_from_params, :conditions=>User.conditions_by_like(params[:search]) logger.info @users.size else list end # params[:action] lets search and sort get _search and _sort render :partial=>params[:action], :layout=>false end

Ajax on Rails www.codecite.comSlide 17 of 54

Page 18: Ajax Rails

Server Side Implementation Does Not Use Layout

def search if params[:search] && params[:search].size>0 @user_pages, @users = paginate :users, :per_page => 10, :order => order_from_params, :conditions=>User.conditions_by_like(params[:search]) logger.info @users.size else list end # params[:action] lets search and sort get _search and _sort render :partial=>params[:action], :layout=>false end

Ajax on Rails www.codecite.comSlide 18 of 54

Page 19: Ajax Rails

Generalizing From The Search Example

Rails Providers Helper Methods Like observe_field

Helpers Generate JavaScript Code

Options Passed Through to Prototype/Scriptaculous

ruby hashes become JSON notation

Helpers Share Many Common Options

Ajax on Rails www.codecite.comSlide 19 of 54

Page 20: Ajax Rails

XHR Helper Methods

Method Trigger

Ajax on Rails www.codecite.comSlide 20 of 54

link_to_remote user clicks a linkform_remote_tag user submits a formremote_form_for user submits a formobserve_field user changes a fieldobserve_form user changes any field in a formsubmit_to_remote user clicks button

Page 21: Ajax Rails

Degradable Ajax

Ajax Apps That Also Function as Plain Old Web Pages

'Same URL' Strategy

pass Ajax-specific header

use partial for Ajax

wrap partial in template/layout for POW

'Different URL' Strategy

Ajax requests to one URL

Non-Ajax requests to a different URL

Ajax on Rails www.codecite.comSlide 21 of 54

Page 22: Ajax Rails

Degrading on Same URL

Ajax on Rails www.codecite.comSlide 22 of 54

Page 23: Ajax Rails

Degrading to Different URL

<%= link_to_remote('link', {:update=>'jscheck'}, :href=>url_for(:action=>'no_javascript')) %> <%= form_remote_tag(:update=>'jscheck', :url=>{:action=>'yes_javascript'}, :html=>{:action=>'no_javascript', :method=>'post'}) %>

Ajax on Rails www.codecite.comSlide 23 of 54

Page 24: Ajax Rails

What is Scriptaculous?

Effects and Widgets Library

Builds on Prototype

Driven and Inspired by Ruby on Rails

Simple and Elegant

Ajax on Rails www.codecite.comSlide 24 of 54

Page 25: Ajax Rails

Scriptaculous's Role in Ajax

Ajax on Rails www.codecite.comSlide 25 of 54

Page 26: Ajax Rails

Autocomplete

Popup List of Choices

Load Possible Matches While User Edits

Several Helper Methods

Simplest Version Assumes AR-Style Model Object

Ajax on Rails www.codecite.comSlide 26 of 54

Page 27: Ajax Rails

Text Input

<%= text_field 'user', 'favorite_language' %></p> <div class="auto_complete" id="user_favorite_language_auto_complete"></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %>

Ajax on Rails www.codecite.comSlide 27 of 54

Page 28: Ajax Rails

DOM ID To AutoComplete

<%= text_field 'user', 'favorite_language' %></p> <div class="auto_complete" id="user_favorite_language_auto_complete"></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %>

Ajax on Rails www.codecite.comSlide 28 of 54

Page 29: Ajax Rails

Placeholder DIV For Suggestions

<%= text_field 'user', 'favorite_language' %></p> <div class="auto_complete" id="user_favorite_language_auto_complete"></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %>

Ajax on Rails www.codecite.comSlide 29 of 54

Page 30: Ajax Rails

Ajax Options (URL Required)

<%= text_field 'user', 'favorite_language' %></p> <div class="auto_complete" id="user_favorite_language_auto_complete"></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %>

Ajax on Rails www.codecite.comSlide 30 of 54

Page 31: Ajax Rails

Server Returns Simple HTML List

<ul class="autocomplete_list"> <% @languages.each do |l| %> <li class="autocomplete_item"><%= l %></li> <% end %></ul>

Ajax on Rails www.codecite.comSlide 31 of 54

Page 32: Ajax Rails

Drag and Drop

Mark Elements as Draggable

Mark Elements as Drop Targets

Specify Callbacks

Ajax on Rails www.codecite.comSlide 32 of 54

Page 33: Ajax Rails

Naming Convention: Model_Id

<ul id='pending_todo_list'> <% @pending_todos.each do |item| %> <% domid = "todo_#{item.id}" %> <li class="pending_todo" id='<%= domid %>'><%= item.name %></li> <%= draggable_element(domid, :ghosting=>true, :revert=>true) %> <% end %> </ul>

Ajax on Rails www.codecite.comSlide 33 of 54

Page 34: Ajax Rails

Show Ghost Image While Dragging

<ul id='pending_todo_list'> <% @pending_todos.each do |item| %> <% domid = "todo_#{item.id}" %> <li class="pending_todo" id='<%= domid %>'><%= item.name %></li> <%= draggable_element(domid, :ghosting=>true, :revert=>true) %> <% end %> </ul>

Ajax on Rails www.codecite.comSlide 34 of 54

Page 35: Ajax Rails

Snap Image Back After Drag

<ul id='pending_todo_list'> <% @pending_todos.each do |item| %> <% domid = "todo_#{item.id}" %> <li class="pending_todo" id='<%= domid %>'><%= item.name %></li> <%= draggable_element(domid, :ghosting=>true, :revert=>true) %> <% end %> </ul>

Ajax on Rails www.codecite.comSlide 35 of 54

Page 36: Ajax Rails

DOM ID of Drop Target

<%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>"$('spinner').hide();", :before=>"$('spinner').show();", :hoverclass=>'hover', :with=>"'todo=' + encodeURIComponent(element.id.split('_').last())", :url=>{:action=>:todo_pending, :id=>@user})%>

Ajax on Rails www.codecite.comSlide 36 of 54

Page 37: Ajax Rails

Only Accept Drops With Certain CSS Styles

<%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>"$('spinner').hide();", :before=>"$('spinner').show();", :hoverclass=>'hover', :with=>"'todo=' + encodeURIComponent(element.id.split('_').last())", :url=>{:action=>:todo_pending, :id=>@user})%>

Ajax on Rails www.codecite.comSlide 37 of 54

Page 38: Ajax Rails

Various Ajax Options

<%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>"$('spinner').hide();", :before=>"$('spinner').show();", :hoverclass=>'hover', :with=>"'todo=' + encodeURIComponent(element.id.split('_').last())", :url=>{:action=>:todo_pending, :id=>@user})%>

Ajax on Rails www.codecite.comSlide 38 of 54

Page 39: Ajax Rails

Set This CSS Class When a Valid Droppable Hovers

<%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>"$('spinner').hide();", :before=>"$('spinner').show();", :hoverclass=>'hover', :with=>"'todo=' + encodeURIComponent(element.id.split('_').last())", :url=>{:action=>:todo_pending, :id=>@user})%>

Ajax on Rails www.codecite.comSlide 39 of 54

Page 40: Ajax Rails

Query Follows Naming Convention

<%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>"$('spinner').hide();", :before=>"$('spinner').show();", :hoverclass=>'hover', :with=>"'todo=' + encodeURIComponent(element.id.split('_').last())", :url=>{:action=>:todo_pending, :id=>@user})%>

Ajax on Rails www.codecite.comSlide 40 of 54

Page 41: Ajax Rails

Distinct Style for Drop Areas

<style>.hover { background-color: #888888;}#pending_todos ul li, #completed_todos ul li { list-style: none; cursor: -moz-grab;}#pending_todos, #completed_todos { border: 1px solid gray;}

Ajax on Rails www.codecite.comSlide 41 of 54

Page 42: Ajax Rails

Distinct Style for Valid Drops on Hover

<style>.hover { background-color: #888888;}#pending_todos ul li, #completed_todos ul li { list-style: none; cursor: -moz-grab;}#pending_todos, #completed_todos { border: 1px solid gray;}

Ajax on Rails www.codecite.comSlide 42 of 54

Page 43: Ajax Rails

JavaScriptGenerator and RJS Templates

Added to Edge November 2005

Call Ruby Methods on Server-Side page Object

Generates JavaScript to Execute on Client

Methods for Prototype and Scriptaculous

Easy to Add Your Own

Ajax on Rails www.codecite.comSlide 43 of 54

Page 44: Ajax Rails

Some Basic Generator Calls

RJS Expression (Server) Generated JavaScript on Client

Ajax on Rails www.codecite.comSlide 44 of 54

page.alert('someMessage') alert("someMessage");page.redirect_to(:action=>'foo') window.location.href = "http://www.example.com/foo";page.call('myFunc', 'a_string', 42) myFunc("a_string", 42);page.assign('myVar', 42) myVar = 42;

Page 45: Ajax Rails

Some Prototype Generator Calls

RJS Expression (Server) Generated JavaScript on Client

Ajax on Rails www.codecite.comSlide 45 of 54

page.show('someDomId') Element.show("someDomId");page.hide('someDomId') Element.hide("someDomId");page.toggle('someDomId') Element.toggle("someDomId");

Page 46: Ajax Rails

Uses For JavaScriptGenerator

Update More Than One DOM Element

Update Element And Apply Behavior

Server Takes Control of The Page

Ajax on Rails www.codecite.comSlide 46 of 54

Page 47: Ajax Rails

Rendering JavaScript From the Controller

render :update do |page| page.replace_html 'pending_todos', :partial => 'pending_todos' page.replace_html 'completed_todos', :partial => 'completed_todos' page.sortable "pending_todo_list", :url=>{:action=>:sort_pending_todos, :id=>@user} end

Ajax on Rails www.codecite.comSlide 47 of 54

Page 48: Ajax Rails

Drag Move Updates More Than One Element

render :update do |page| page.replace_html 'pending_todos', :partial => 'pending_todos' page.replace_html 'completed_todos', :partial => 'completed_todos' page.sortable "pending_todo_list", :url=>{:action=>:sort_pending_todos, :id=>@user} end

Ajax on Rails www.codecite.comSlide 48 of 54

Page 49: Ajax Rails

Drag Move Resets Sortable Behavior

render :update do |page| page.replace_html 'pending_todos', :partial => 'pending_todos' page.replace_html 'completed_todos', :partial => 'completed_todos' page.sortable "pending_todo_list", :url=>{:action=>:sort_pending_todos, :id=>@user} end

Ajax on Rails www.codecite.comSlide 49 of 54

Page 50: Ajax Rails

Invoking UI Effects

def update_many(options) render :update do |page| options.each do |k,v| page.replace_html k, :partial=>v page.visual_effect :highlight, k end end end

Ajax on Rails www.codecite.comSlide 50 of 54

Page 51: Ajax Rails

RJS Templates

View Files That End in .rjs

Same Object Model as render :update

Invoke Methods on page

Generated JavaScript Executes on Client

Ajax on Rails www.codecite.comSlide 51 of 54

Page 52: Ajax Rails

JSON Support

Rails Adds to_json to Objects

implemented in ActiveSupport::JSON

Used For Model-Centric Ajax

Ajax on Rails www.codecite.comSlide 52 of 54

Page 53: Ajax Rails

JSON Example: Periodically Updating Chat

class ChatJsonController < ApplicationController def retrieve_chats headers['Content-Type'] = "text/json" @chats = get_chats render :text=>@chats.to_json endend

Ajax on Rails www.codecite.comSlide 53 of 54

Page 54: Ajax Rails

References

ResourcesCodecite (Presentations and Code Samples), http://www.codecite.com

Relevance Consulting and Development, http://www.relevancellc.com/main/services

Relevance Training, http://www.relevancellc.com/main/training

Relevance Weblog, http://blogs.relevancellc.com

Projects CitedAjax Labs, http://codecite.com/projects/ajax_labs.zip

Rails Exploration Application, http://codecite.com/projects/rails_xt.zip

Pragmatic Chat Sample Application, http://codecite.com/projects/pragmatic_chat.zip

Ajax on Rails www.codecite.comSlide 54 of 54