200 likes | 240 Views
Learn how to seamlessly integrate AJAX using Ruby on Rails with libraries like jQuery and Prototype for dynamic web applications. Explore client-side interactions and server-side handling effortlessly.
E N D
Ruby on Rails and AJAX • AJAX can be done with just Javascript • Easier if you use libraries • Prototype • SAJAX • jQuery • Libraries only handle the client side • Ruby on Rails also makes it easy on the server side
Simple Consistent Model • A trigger action occurs • button or link, javascript event • Data is sent asynchronously • Server side action handler takes some action and returns data • may be HTML partial • Client side receives the data/HTML and updates the view
Client Side • Based on the prototype library • Simple Ruby functions • link_to_remote • form_remote_tag • periodically_call_remote • submit_to_remote • remote_function • View uses these functions which generate appropriate HTML tags and javascript function calls
View <html> <head> <title>Ajax Demo</title> <%= javascript_include_tag :defaults %> </head> <body> <h1>What time is it?</h1> <div id="time_div"> I don't have the time, but <%= link_to_remote( "click here", :update => "time_div", :url =>{ :action => :say_when }) %> and I will look it up. </div> </body> </html>
Details • javascript_include_tag • includes the appropriate javascript libraries • :defaults includes a few • may also just include specific libraries • link_to_remote (can be complex) • most often need • text for link name • id of the DOM element to update • url • may also specify • :method - default is POST • :position - must be one of :before, :top, :bottom, :after • :complete, :success, :failure • javascript callback functions
Server Side • AJAX calls are treated just like any other HTTP request • However, we don’t want full response • layout, css, etc. • To suppress full response use • render(:text => “string”) • may also use render_text • render(:layout => false) • .js.rjs file with partial • controller with no layout
Example class DemoController < ApplicationController def index end def say_when render_text "<p>The time is <b>" + DateTime.now.to_s + "</b></p>” end end In this case, there is no view connected to the action method
form_remote_tag <% form_remote_tag :url => { :action => :add_to_cart, :id => product } do -%> <%= submit_tag "Add to Cart" %> <% end -%>
More complex <%= link_to_remote("Logout", :url => {:controller => "Ajax", :action => "logout" }, :update => 'loginmessage', :complete => remote_function( :url => {:controller => "Ajax", :action => "menu"}, :update => 'sidemenu', :complete => remote_function( :url => {:controller => "Main", :action => "index"} ) ) )
.js.rjs templates • Controller action methods are paired by name with view files • in app/views/controller_name directory • Typically, .html.erb files • May also be .js.rjs • ruby javascript • javascript to be executed on load • allows for multiple page updates • written in Ruby • Paired with controller action method that doesn’t contain calls to render
.js.rjs example view code <%= link_to_remote("Test out RJS!", :url =>{ :controller => "shop", :action => "hello" }) %> controller code def hello end hello.js.rjs - goes into app/views/shop page.alert "Hello from RJS!"
Updating the DOM with .js.rjs • Mark the location to be updated • <div id=“someid”> or <span id=“someid”> • </div> or </span> • Now replace the stuff in that location using page.replace_html • page.replace_html “someid”, “<b>HI</b>” • .js.rjs file is interpreted into javascript and the javascript is executed when it is loaded
Other page methods • alert(message) • replace_html(id, *options_for_render) • options for render may be string with html • insert_html(position, id, *options_for_render) • position must be :before, :after, :top, :bottom • show( *ids ), hide( *ids ), & toggle( *ids ) • toggles the visibility of the html elements • visual_effect(effectname, id, options) • page.visual_effect(:fade, ‘someid’, :duration => 0.5) • page.visual_effect(:appear, ‘someid’, :duration => 0.5) • page.visual_effect(:highlight, ‘someid’, :duration => 1)
.js.rjs • Much of what you can do is based on the scriptaculous library • http://script.aculo.us/ • Also look at the Ruby on Rails api • ActionView::Helpers::ScriptaculousHelper • ActionView::Helpers::PrototypeHelper
Another Example - View • Dynamically populate form elements <% form_remote_tag(:update => "sel_con",:url => { :action => :create_select }, :position => "top", :success => "$('sel_con').innerHTML=''" ) do -%> <p> Please select a sports category: </p> <p> <%= select_tag "categories", "<option>Team</option><option>Individual</option>" %> </p> <div id="sel_con"></div> <p> <%= submit_tag "Show Sports" %> </p> <% end %>
Another Example cont - controller def create_select indArr=["Nordic Skiing", "Inline Skating","Tennis", "Triathlon","Road Racing","Figure Skating", "Weight Lifting","Speed Skating","Snowboarding"]; teamArr=["Soccer","Basketball","Football","Hockey", "Baseball","Lacrosse"]; str=""; if (params[:categories].index('Team') != nil) render :partial => "options", :locals => { :sports => teamArr,:sptype => "team"} elsif (params[:categories].index('Individual') != nil) render :partial => "options", :locals => { :sports => indArr, :sptype => "individual" } else str="<select id='individual' name='individual'> <option>unknown</option></select>"; render :text => str; end end
Another Example cont - partial _options <select id="<%= sptype %>" name="<%= sptype %>"> <% sports.each do |sport| %> <option><%= sport %></option> <% end %> </select>