Ajax Rails
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Ajax Rails

  • 3,696 views
Uploaded on

a very good ajax use in the rails

a very good ajax use in the rails

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
3,696
On Slideshare
3,688
From Embeds
8
Number of Embeds
2

Actions

Shares
Downloads
35
Comments
0
Likes
0

Embeds 8

http://www.slideshare.net 7
http://localhost 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Ajax on Rails Stuart Halloway and Justin Gehtland Copyright 2005-6 Relevance, LLC Ajax on Rails Slide 1 of 54 www.codecite.com
  • 2. 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 contact@relevancellc.com 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 quot;Softwarequot;), 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 quot;AS ISquot;, 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 Slide 2 of 54 www.codecite.com
  • 3. Rails's Role in Ajax Ajax on Rails Slide 3 of 54 www.codecite.com
  • 4. Agenda Prototype Support Ajax requests auto-update UI observers Scriptaculous Helpers effects widgets JavaScript Generation JavaScriptGenerator rjs JSON Ajax on Rails Slide 4 of 54 www.codecite.com
  • 5. 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 Slide 5 of 54 www.codecite.com
  • 6. Prototype's Role in Ajax Ajax on Rails Slide 6 of 54 www.codecite.com
  • 7. 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 Slide 7 of 54 www.codecite.com
  • 8. Creating a No-Op Form <%= start_form_tag('javascript:void%200', {:method=> 'filter'}) %> Ajax on Rails Slide 8 of 54 www.codecite.com
  • 9. Observing a Field By DOM ID <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Ajax on Rails Slide 9 of 54 www.codecite.com
  • 10. Frequency to Check for Field Changes <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Ajax on Rails Slide 10 of 54 www.codecite.com
  • 11. DOM ID to Update With Results <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Ajax on Rails Slide 11 of 54 www.codecite.com
  • 12. Show/Hide Progress Indicator <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Ajax on Rails Slide 12 of 54 www.codecite.com
  • 13. Query Parameters <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Ajax on Rails Slide 13 of 54 www.codecite.com
  • 14. Server URL <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Ajax on Rails Slide 14 of 54 www.codecite.com
  • 15. Why Full Path? <%= observe_field :search, :frequency => 0.5, :update => 'ajaxWrapper', :complete=>quot;Element.hide('spinner')quot;, :before=>quot;Element.show('spinner')quot;, :with=>quot;'search=' + encodeURIComponent(value)quot;, :url=>{:action=>'search', :only_path => false} %> Pragforms Intended for Cross-Site Scripting Most Ajax Apps Will Not Need This Ajax on Rails Slide 15 of 54 www.codecite.com
  • 16. Rendered HTML + JavaScript <input id=quot;searchquot; name=quot;searchquot; type=quot;textquot; value=quot;quot; /> <script type=quot;text/javascriptquot;> //<![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 Slide 16 of 54 www.codecite.com
  • 17. 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 Slide 17 of 54 www.codecite.com
  • 18. 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 Slide 18 of 54 www.codecite.com
  • 19. 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 Slide 19 of 54 www.codecite.com
  • 20. XHR Helper Methods Method Trigger link_to_remote user clicks a link form_remote_tag user submits a form remote_form_for user submits a form observe_field user changes a field observe_form user changes any field in a form submit_to_remote user clicks button Ajax on Rails Slide 20 of 54 www.codecite.com
  • 21. 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 Slide 21 of 54 www.codecite.com
  • 22. Degrading on Same URL Ajax on Rails Slide 22 of 54 www.codecite.com
  • 23. 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 Slide 23 of 54 www.codecite.com
  • 24. What is Scriptaculous? Effects and Widgets Library Builds on Prototype Driven and Inspired by Ruby on Rails Simple and Elegant Ajax on Rails Slide 24 of 54 www.codecite.com
  • 25. Scriptaculous's Role in Ajax Ajax on Rails Slide 25 of 54 www.codecite.com
  • 26. Autocomplete Popup List of Choices Load Possible Matches While User Edits Several Helper Methods Simplest Version Assumes AR-Style Model Object Ajax on Rails Slide 26 of 54 www.codecite.com
  • 27. Text Input <%= text_field 'user', 'favorite_language' %></p> <div class=quot;auto_completequot; id=quot;user_favorite_language_auto_completequot;></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %> Ajax on Rails Slide 27 of 54 www.codecite.com
  • 28. DOM ID To AutoComplete <%= text_field 'user', 'favorite_language' %></p> <div class=quot;auto_completequot; id=quot;user_favorite_language_auto_completequot;></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %> Ajax on Rails Slide 28 of 54 www.codecite.com
  • 29. Placeholder DIV For Suggestions <%= text_field 'user', 'favorite_language' %></p> <div class=quot;auto_completequot; id=quot;user_favorite_language_auto_completequot;></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %> Ajax on Rails Slide 29 of 54 www.codecite.com
  • 30. Ajax Options (URL Required) <%= text_field 'user', 'favorite_language' %></p> <div class=quot;auto_completequot; id=quot;user_favorite_language_auto_completequot;></div> <%= auto_complete_field :user_favorite_language, :url=>{:action=>'autocomplete_favorite_language'} %> Ajax on Rails Slide 30 of 54 www.codecite.com
  • 31. Server Returns Simple HTML List <ul class=quot;autocomplete_listquot;> <% @languages.each do |l| %> <li class=quot;autocomplete_itemquot;><%= l %></li> <% end %> </ul> Ajax on Rails Slide 31 of 54 www.codecite.com
  • 32. Drag and Drop Mark Elements as Draggable Mark Elements as Drop Targets Specify Callbacks Ajax on Rails Slide 32 of 54 www.codecite.com
  • 33. Naming Convention: Model_Id <ul id='pending_todo_list'> <% @pending_todos.each do |item| %> <% domid = quot;todo_#{item.id}quot; %> <li class=quot;pending_todoquot; id='<%= domid %>'><%= item.name %></li> <%= draggable_element(domid, :ghosting=>true, :revert=>true) %> <% end %> </ul> Ajax on Rails Slide 33 of 54 www.codecite.com
  • 34. Show Ghost Image While Dragging <ul id='pending_todo_list'> <% @pending_todos.each do |item| %> <% domid = quot;todo_#{item.id}quot; %> <li class=quot;pending_todoquot; id='<%= domid %>'><%= item.name %></li> <%= draggable_element(domid, :ghosting=>true, :revert=>true) %> <% end %> </ul> Ajax on Rails Slide 34 of 54 www.codecite.com
  • 35. Snap Image Back After Drag <ul id='pending_todo_list'> <% @pending_todos.each do |item| %> <% domid = quot;todo_#{item.id}quot; %> <li class=quot;pending_todoquot; id='<%= domid %>'><%= item.name %></li> <%= draggable_element(domid, :ghosting=>true, :revert=>true) %> <% end %> </ul> Ajax on Rails Slide 35 of 54 www.codecite.com
  • 36. DOM ID of Drop Target <%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>quot;$('spinner').hide();quot;, :before=>quot;$('spinner').show();quot;, :hoverclass=>'hover', :with=>quot;'todo=' + encodeURIComponent(element.id.split('_').last())quot;, :url=>{:action=>:todo_pending, :id=>@user})%> Ajax on Rails Slide 36 of 54 www.codecite.com
  • 37. Only Accept Drops With Certain CSS Styles <%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>quot;$('spinner').hide();quot;, :before=>quot;$('spinner').show();quot;, :hoverclass=>'hover', :with=>quot;'todo=' + encodeURIComponent(element.id.split('_').last())quot;, :url=>{:action=>:todo_pending, :id=>@user})%> Ajax on Rails Slide 37 of 54 www.codecite.com
  • 38. Various Ajax Options <%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>quot;$('spinner').hide();quot;, :before=>quot;$('spinner').show();quot;, :hoverclass=>'hover', :with=>quot;'todo=' + encodeURIComponent(element.id.split('_').last())quot;, :url=>{:action=>:todo_pending, :id=>@user})%> Ajax on Rails Slide 38 of 54 www.codecite.com
  • 39. Set This CSS Class When a Valid Droppable Hovers <%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>quot;$('spinner').hide();quot;, :before=>quot;$('spinner').show();quot;, :hoverclass=>'hover', :with=>quot;'todo=' + encodeURIComponent(element.id.split('_').last())quot;, :url=>{:action=>:todo_pending, :id=>@user})%> Ajax on Rails Slide 39 of 54 www.codecite.com
  • 40. Query Follows Naming Convention <%= drop_receiving_element('pending_todos', :accept=>'completed_todo', :complete=>quot;$('spinner').hide();quot;, :before=>quot;$('spinner').show();quot;, :hoverclass=>'hover', :with=>quot;'todo=' + encodeURIComponent(element.id.split('_').last())quot;, :url=>{:action=>:todo_pending, :id=>@user})%> Ajax on Rails Slide 40 of 54 www.codecite.com
  • 41. 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 Slide 41 of 54 www.codecite.com
  • 42. 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 Slide 42 of 54 www.codecite.com
  • 43. 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 Slide 43 of 54 www.codecite.com
  • 44. Some Basic Generator Calls RJS Expression (Server) Generated JavaScript on Client page.alert('someMessage') alert(quot;someMessagequot;); page.redirect_to(:action=>'foo') window.location.href = quot;http://www.example.com/fooquot;; page.call('myFunc', 'a_string', 42) myFunc(quot;a_stringquot;, 42); page.assign('myVar', 42) myVar = 42; Ajax on Rails Slide 44 of 54 www.codecite.com
  • 45. Some Prototype Generator Calls RJS Expression (Server) Generated JavaScript on Client page.show('someDomId') Element.show(quot;someDomIdquot;); page.hide('someDomId') Element.hide(quot;someDomIdquot;); page.toggle('someDomId') Element.toggle(quot;someDomIdquot;); Ajax on Rails Slide 45 of 54 www.codecite.com
  • 46. Uses For JavaScriptGenerator Update More Than One DOM Element Update Element And Apply Behavior Server Takes Control of The Page Ajax on Rails Slide 46 of 54 www.codecite.com
  • 47. 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 quot;pending_todo_listquot;, :url=>{:action=>:sort_pending_todos, :id=>@user} end Ajax on Rails Slide 47 of 54 www.codecite.com
  • 48. 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 quot;pending_todo_listquot;, :url=>{:action=>:sort_pending_todos, :id=>@user} end Ajax on Rails Slide 48 of 54 www.codecite.com
  • 49. 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 quot;pending_todo_listquot;, :url=>{:action=>:sort_pending_todos, :id=>@user} end Ajax on Rails Slide 49 of 54 www.codecite.com
  • 50. 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 Slide 50 of 54 www.codecite.com
  • 51. 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 Slide 51 of 54 www.codecite.com
  • 52. JSON Support Rails Adds to_json to Objects implemented in ActiveSupport::JSON Used For Model-Centric Ajax Ajax on Rails Slide 52 of 54 www.codecite.com
  • 53. JSON Example: Periodically Updating Chat class ChatJsonController < ApplicationController def retrieve_chats headers['Content-Type'] = quot;text/jsonquot; @chats = get_chats render :text=>@chats.to_json end end Ajax on Rails Slide 53 of 54 www.codecite.com
  • 54. References Resources Codecite (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 Cited Ajax 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 Slide 54 of 54 www.codecite.com