SlideShare ist ein Scribd-Unternehmen logo
1 von 77
Downloaden Sie, um offline zu lesen
Unobtrusive Ajax
   With Rails
 Dan Webb (dan@danwebb.net)
Overview
    A bit of history
★

    What is unobtrusive scripting?
★

    The UJS Plugin
★

    Casestudy
★

    Ranting Upcoming UJS Features
★
The dark days of
    DHTML
Then web standards
      arrived
The Client-side Cake

        Style - CSS




     Content - (X)HTML
What web standards
          did for us
    More maintainable
★

    More accessible
★

    Leaner pages
★

    Platform independent (print, mobile...)
★

    'Future-proof' as well as backwards
★
    compatible
JavaScript got a
   bad name
It deserved it
Web 2.0
Folksonomies
Massive text boxes
Social software
and Ajax...
JavaScript is trendy
      again!
Browser support is
   much better
We learnt our
lessons from the
  DHTML days
What did we learn?
Unobtrusive DOM
   Scripting
It's an approach to
browser UI design
It's about separating
   content and style
    from behaviour
Behaviour: A new layer for
   the client-side cake
        Behaviour - JavaScript


             Style - CSS


        Content - (X)HTML
It's enhancing a
working application
so it degrades
 gracefully when
things don't work
It's not just about
putting JavaScript in
    a different file
It's not rocket
     science
It's not the
'Rails Way'
An example:
link_to_remote
<%= link_to_remote 'View description',
                   :controller => 'product',
                   :action => 'desc',
                   :id => @product.id %>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/
desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
# better...

<a href=quot;/product/desc/1quot; onclick=quot;new
Ajax.Request(this.href, {asynchronous:true,
evalScripts:true}); return false;quot;>View
description</a>
It's not possible to
     do that with
   link_to_remote
<% @products.each do |product| %>

<%= link_to_remote 'View description',
                   :controller => 'product',
                   :action => 'desc',
                   :id => @product.id %>

<% end %>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true});
return false;quot;>View description</a>
<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>

<a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>
Getting started
The UJS Plugin
    A plugin to aid unobtrusive scripting
★
    with Rails
    Allows you to define behaviours via
★
    CSS selectors
    Keeps script in an external, cacheable
★
    files
    www.ujs4rails.com - check it out!
★
Remote Links
<ul id=quot;outlinequot;>

  <% @items.each do |item| %>

  <li><%= link_to :action => 'more',
                  :id => @item.id %></li>

  <% end %>

</ul>
<ul id=quot;outlinequot;>

  <% @items.each do |item| %>

  <li><%= link_to :action => 'more',
                  :id => @item.id %></li>

  <% end %>

</ul>

<% apply_behaviour '#outline a:click',
   'new Ajax.Request(this.href); return false;' %>
<ul id=quot;outlinequot;>

  <% @items.each do |item| %>

  <li><%= link_to :action => 'more',
                  :id => @item.id %></li>

  <% end %>

</ul>

<% apply_behaviour '#outline a', make_remote_link %>
What about links
with side-effects?
Links should never
 have side effects
Use a button



<%= button_to 'Remove from basket',
              :method => :delete %>
<form class=quot;button-toquot; action=quot;/basket/2quot; method=quot;postquot;>

  <input type=quot;hiddenquot; name=quot;_methodquot; value=quot;deletequot; />

  <input type=quot;submitquot; value=quot;Remove from basketquot; />

</form>
Then attach the behaviour


<%= button_to 'Remove from basket',
              :method => :delete %>
<% apply_behaviour 'form.button-to',
                   make_remote_form %>
Hijacking forms
<%= form_tag :url => entries_url, :id => 'comment' %>

  <%= text_field :name %>

  <%= text_field :email %>

  <%= text_area :comment %>

  <%= submit_tag 'Post comment' %>

<%= end_form_tag %>
<%= form_tag :url => entries_url, :id => 'comment' %>

  <%= text_field :name %>

  <%= text_field :email %>

  <%= text_area :comment %>

  <%= submit_tag 'Post comment' %>

<%= end_form_tag %>



<% apply_behaviour '#comment:submit',
   'new Ajax.Request(this.action, { parameters :
   Form.serialize(this)}); return false;' %>
<%= form_tag :url => entries_url, :id => 'comment' %>

  <%= text_field :name %>

  <%= text_field :email %>

  <%= text_area :comment %>

  <%= submit_tag 'Post comment' %>

<%= end_form_tag %>



<% apply_behaviour '#comment', make_remote_form %>
A Case Study

Sneakr.com: A Web 2.0, Ajax Trainer Shop
routes.rb


map.resource :products

map.resource :basket, :controller => 'basket',

             :collection => {:clear => :post}
The Product Controller
class ProductController < ApplicationController

  def index # show all products

      @products = Product.find :all

  end

  def show # show the details of a product

      @product = Product.find params[:id]

  end

end
index.rhtml

<div id=quot;cataloguequot;>
  <%= render :partial => 'products' %>
</div>
<div id=quot;basketquot;>
  <%= render :partial => 'basket' %>
</div>
_products.rhtml

<ul>

  <% @products.each do |product| %>

    <li id=quot;<%= product.id %>_prodquot;>
    <%= link_to product.name, product_url(product) %>
    <%= product.description %>
    </li>

  <% end %>

</ul>
show.rhtml


<h1><%= @product.name %></h1>

<p><%= image_tag @product.photo.public_filename %></p>

<p><%= @product.description %></p>

<p><%= button_to 'Add To Basket', basket_url
(@product), :method => :put %></p>
The Basket Controller

class BasketController < ApplicationController

  def update

      @product = Product.find params[:id]
      @basket << @product

      redirect_to products_url

  end

end
We're done!
now to add the Ajax
<% apply_behaviours do


   on '#catalogue li',
       make_draggable(:revert => true)

    on '#basket', make_drop_receiving(
      :url => basket_url,
      :with => quot;'_method=put&id=' +
        encodeURIComponent(element.id)quot;

    )

end %>
<% apply_behaviours do


   on '#catalogue li',
       make_draggable(:revert => true)

    on '#basket', make_drop_receiving(
      :url => basket_url,
      :with => quot;'_method=put&id=' +
        encodeURIComponent(element.id)quot;

    )

end %>
So how do we deal
 with this on the
   server-side?
respond_to
class BasketController < ApplicationController

  def update

      @product = Product.find params[:id]
      @basket << @product

      redirect_to products_url

  end

end
class BasketController < ApplicationController

  def update

      @product = Product.find params[:id]
      @basket << @product

      respond_to do |type|
        type.html { redirect_to products_url }
        type.js
      end

  end

end
update.rjs



page.replace_html 'basket',
                  :partial => 'basket'
Take a look for
           yourself...
http://www.danwebb.net/railsconf2006/ujs_shopping.zip
We have no control
     over the
 environment our
 JavaScript runs in
Code defensively
The path to enlightenment
    Write a working application using
★
    semantic HTML
    Style it with CSS
★

    Write JavaScript that 'hijacks' the page
★
    elements to enhance the UI
    Learn JavaScript and DOM Scripting
★
Further Reading
    The JavaScript articles on A List Apart
★
    (alistapart.com)
    Unobtrusive Scripting by Christian
★
    Heilmann (onlinetools.org)
    Jeremy Keith's presentations, book and
★
    articles (domscripting.com)
    Google it!
★
Upcoming in UJS
    Improved testing (custom assertions)
★

    Improved debugging
★

    More behaviour helpers
★

    More tutorials on ujs4rails.com
★
And finally...



<%= apply_behaviour @products, make_draggable %>
<% div_for @product, :behavior => make_draggable do %>

<h2><%= @product.name %></h2>
<p><%= @product.description %></p>

<% end %>
Questions?

Weitere ähnliche Inhalte

Was ist angesagt?

Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleKaty Slemon
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsJulien Lecomte
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Eric Palakovich Carr
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Jazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
Jazz up your JavaScript: Unobtrusive scripting with JavaScript librariesJazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
Jazz up your JavaScript: Unobtrusive scripting with JavaScript librariesSimon Willison
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Libraryjeresig
 
Grails Simple Login
Grails Simple LoginGrails Simple Login
Grails Simple Loginmoniguna
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJSAll Things Open
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widgetTudor Barbu
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript FrameworkAll Things Open
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux IntroductionNikolaus Graf
 
React Facebook JavaScript Library
React Facebook JavaScript LibraryReact Facebook JavaScript Library
React Facebook JavaScript LibraryTakami Kazuya
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Ryan Weaver
 
SproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFestSproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFesttomdale
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentationnishasowdri
 
REACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptREACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptDeepu S Nath
 

Was ist angesagt? (20)

Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Jazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
Jazz up your JavaScript: Unobtrusive scripting with JavaScript librariesJazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
Jazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Library
 
Grails Simple Login
Grails Simple LoginGrails Simple Login
Grails Simple Login
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
React Facebook JavaScript Library
React Facebook JavaScript LibraryReact Facebook JavaScript Library
React Facebook JavaScript Library
 
WordPress and Ajax
WordPress and AjaxWordPress and Ajax
WordPress and Ajax
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
SproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFestSproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFest
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
 
REACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptREACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScript
 

Andere mochten auch (8)

Secretsofrubyonrails
SecretsofrubyonrailsSecretsofrubyonrails
Secretsofrubyonrails
 
State Of Rails 05
State Of Rails 05State Of Rails 05
State Of Rails 05
 
Fisl6
Fisl6Fisl6
Fisl6
 
Rails Conf Talk Slides
Rails Conf Talk SlidesRails Conf Talk Slides
Rails Conf Talk Slides
 
Ugo Cei Presentation
Ugo Cei PresentationUgo Cei Presentation
Ugo Cei Presentation
 
Extractingrails
ExtractingrailsExtractingrails
Extractingrails
 
Our Opinions!
Our Opinions!Our Opinions!
Our Opinions!
 
Workin On The Rails Road
Workin On The Rails RoadWorkin On The Rails Road
Workin On The Rails Road
 

Ähnlich wie Dan Webb Presentation

Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in RailsSeungkyun Nam
 
Unobtrusive JavaScript
Unobtrusive JavaScriptUnobtrusive JavaScript
Unobtrusive JavaScriptVitaly Baum
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
Course CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.jsCourse CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.jsVinícius de Moraes
 
1 ppt-ajax with-j_query
1 ppt-ajax with-j_query1 ppt-ajax with-j_query
1 ppt-ajax with-j_queryFajar Baskoro
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Treeadamlogic
 
Kakunin E2E framework showcase
Kakunin E2E framework showcaseKakunin E2E framework showcase
Kakunin E2E framework showcaseThe Software House
 
243329387 angular-docs
243329387 angular-docs243329387 angular-docs
243329387 angular-docsAbhi166803
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The HoodWO Community
 
Remote code-with-expression-language-injection
Remote code-with-expression-language-injectionRemote code-with-expression-language-injection
Remote code-with-expression-language-injectionMickey Jack
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesNCCOMMS
 
Bulletproof Ajax
Bulletproof AjaxBulletproof Ajax
Bulletproof Ajaxadactio
 
Bulletproof Ajax
Bulletproof AjaxBulletproof Ajax
Bulletproof Ajax2tique
 
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016Nicolás Bouhid
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...Ben Teese
 
Introduction to angular js july 6th 2014
Introduction to angular js   july 6th 2014Introduction to angular js   july 6th 2014
Introduction to angular js july 6th 2014Simona Clapan
 

Ähnlich wie Dan Webb Presentation (20)

Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in Rails
 
Unobtrusive JavaScript
Unobtrusive JavaScriptUnobtrusive JavaScript
Unobtrusive JavaScript
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
Course CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.jsCourse CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.js
 
1 ppt-ajax with-j_query
1 ppt-ajax with-j_query1 ppt-ajax with-j_query
1 ppt-ajax with-j_query
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Tree
 
Kakunin E2E framework showcase
Kakunin E2E framework showcaseKakunin E2E framework showcase
Kakunin E2E framework showcase
 
243329387 angular-docs
243329387 angular-docs243329387 angular-docs
243329387 angular-docs
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The Hood
 
Remote code-with-expression-language-injection
Remote code-with-expression-language-injectionRemote code-with-expression-language-injection
Remote code-with-expression-language-injection
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_libraries
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Bulletproof Ajax
Bulletproof AjaxBulletproof Ajax
Bulletproof Ajax
 
Bulletproof Ajax
Bulletproof AjaxBulletproof Ajax
Bulletproof Ajax
 
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
 
Unit 2.4
Unit 2.4Unit 2.4
Unit 2.4
 
Introduction to angular js july 6th 2014
Introduction to angular js   july 6th 2014Introduction to angular js   july 6th 2014
Introduction to angular js july 6th 2014
 

Mehr von RubyOnRails_dude

Mehr von RubyOnRails_dude (7)

Slides
SlidesSlides
Slides
 
Marcel Molina Jr. Presentation
Marcel Molina Jr. PresentationMarcel Molina Jr. Presentation
Marcel Molina Jr. Presentation
 
Rails4 Days
Rails4 DaysRails4 Days
Rails4 Days
 
Till Vollmer Presentation
Till Vollmer PresentationTill Vollmer Presentation
Till Vollmer Presentation
 
Programminghappiness
ProgramminghappinessProgramminghappiness
Programminghappiness
 
Pursuitofbeauty
PursuitofbeautyPursuitofbeauty
Pursuitofbeauty
 
Worldofresources
WorldofresourcesWorldofresources
Worldofresources
 

Kürzlich hochgeladen

A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMANIlamathiKannappan
 
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...lizamodels9
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageMatteo Carbone
 
Progress Report - Oracle Database Analyst Summit
Progress  Report - Oracle Database Analyst SummitProgress  Report - Oracle Database Analyst Summit
Progress Report - Oracle Database Analyst SummitHolger Mueller
 
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service AvailableCall Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service AvailableDipal Arora
 
Cracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptxCracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptxWorkforce Group
 
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsValue Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsP&CO
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...amitlee9823
 
Understanding the Pakistan Budgeting Process: Basics and Key Insights
Understanding the Pakistan Budgeting Process: Basics and Key InsightsUnderstanding the Pakistan Budgeting Process: Basics and Key Insights
Understanding the Pakistan Budgeting Process: Basics and Key Insightsseri bangash
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communicationskarancommunications
 
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesDipal Arora
 
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Lviv Startup Club
 
Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfPaul Menig
 
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒anilsa9823
 
Unlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdfUnlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdfOnline Income Engine
 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyEthan lee
 
Best Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaBest Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaShree Krishna Exports
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Dave Litwiller
 
Boost the utilization of your HCL environment by reevaluating use cases and f...
Boost the utilization of your HCL environment by reevaluating use cases and f...Boost the utilization of your HCL environment by reevaluating use cases and f...
Boost the utilization of your HCL environment by reevaluating use cases and f...Roland Driesen
 

Kürzlich hochgeladen (20)

A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMAN
 
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usage
 
Progress Report - Oracle Database Analyst Summit
Progress  Report - Oracle Database Analyst SummitProgress  Report - Oracle Database Analyst Summit
Progress Report - Oracle Database Analyst Summit
 
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service AvailableCall Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
 
Cracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptxCracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptx
 
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsValue Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and pains
 
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
 
Understanding the Pakistan Budgeting Process: Basics and Key Insights
Understanding the Pakistan Budgeting Process: Basics and Key InsightsUnderstanding the Pakistan Budgeting Process: Basics and Key Insights
Understanding the Pakistan Budgeting Process: Basics and Key Insights
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communications
 
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
 
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
 
Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdf
 
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒
 
Unlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdfUnlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdf
 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
 
Best Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaBest Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in India
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
 
Boost the utilization of your HCL environment by reevaluating use cases and f...
Boost the utilization of your HCL environment by reevaluating use cases and f...Boost the utilization of your HCL environment by reevaluating use cases and f...
Boost the utilization of your HCL environment by reevaluating use cases and f...
 

Dan Webb Presentation

  • 1. Unobtrusive Ajax With Rails Dan Webb (dan@danwebb.net)
  • 2. Overview A bit of history ★ What is unobtrusive scripting? ★ The UJS Plugin ★ Casestudy ★ Ranting Upcoming UJS Features ★
  • 3. The dark days of DHTML
  • 4.
  • 5.
  • 6.
  • 8. The Client-side Cake Style - CSS Content - (X)HTML
  • 9. What web standards did for us More maintainable ★ More accessible ★ Leaner pages ★ Platform independent (print, mobile...) ★ 'Future-proof' as well as backwards ★ compatible
  • 10. JavaScript got a bad name
  • 18. Browser support is much better
  • 19. We learnt our lessons from the DHTML days
  • 20. What did we learn?
  • 21. Unobtrusive DOM Scripting
  • 22. It's an approach to browser UI design
  • 23. It's about separating content and style from behaviour
  • 24. Behaviour: A new layer for the client-side cake Behaviour - JavaScript Style - CSS Content - (X)HTML
  • 26. so it degrades gracefully when things don't work
  • 27. It's not just about putting JavaScript in a different file
  • 28. It's not rocket science
  • 31. <%= link_to_remote 'View description', :controller => 'product', :action => 'desc', :id => @product.id %>
  • 32. <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/ desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>
  • 33. # better... <a href=quot;/product/desc/1quot; onclick=quot;new Ajax.Request(this.href, {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>
  • 34. It's not possible to do that with link_to_remote
  • 35. <% @products.each do |product| %> <%= link_to_remote 'View description', :controller => 'product', :action => 'desc', :id => @product.id %> <% end %>
  • 36. <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>
  • 37. <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a> <a href=quot;#quot; onclick=quot;new Ajax.Request('/product/desc/1', {asynchronous:true, evalScripts:true}); return false;quot;>View description</a>
  • 39. The UJS Plugin A plugin to aid unobtrusive scripting ★ with Rails Allows you to define behaviours via ★ CSS selectors Keeps script in an external, cacheable ★ files www.ujs4rails.com - check it out! ★
  • 41. <ul id=quot;outlinequot;> <% @items.each do |item| %> <li><%= link_to :action => 'more', :id => @item.id %></li> <% end %> </ul>
  • 42. <ul id=quot;outlinequot;> <% @items.each do |item| %> <li><%= link_to :action => 'more', :id => @item.id %></li> <% end %> </ul> <% apply_behaviour '#outline a:click', 'new Ajax.Request(this.href); return false;' %>
  • 43. <ul id=quot;outlinequot;> <% @items.each do |item| %> <li><%= link_to :action => 'more', :id => @item.id %></li> <% end %> </ul> <% apply_behaviour '#outline a', make_remote_link %>
  • 44. What about links with side-effects?
  • 45. Links should never have side effects
  • 46. Use a button <%= button_to 'Remove from basket', :method => :delete %>
  • 47. <form class=quot;button-toquot; action=quot;/basket/2quot; method=quot;postquot;> <input type=quot;hiddenquot; name=quot;_methodquot; value=quot;deletequot; /> <input type=quot;submitquot; value=quot;Remove from basketquot; /> </form>
  • 48. Then attach the behaviour <%= button_to 'Remove from basket', :method => :delete %> <% apply_behaviour 'form.button-to', make_remote_form %>
  • 50. <%= form_tag :url => entries_url, :id => 'comment' %> <%= text_field :name %> <%= text_field :email %> <%= text_area :comment %> <%= submit_tag 'Post comment' %> <%= end_form_tag %>
  • 51. <%= form_tag :url => entries_url, :id => 'comment' %> <%= text_field :name %> <%= text_field :email %> <%= text_area :comment %> <%= submit_tag 'Post comment' %> <%= end_form_tag %> <% apply_behaviour '#comment:submit', 'new Ajax.Request(this.action, { parameters : Form.serialize(this)}); return false;' %>
  • 52. <%= form_tag :url => entries_url, :id => 'comment' %> <%= text_field :name %> <%= text_field :email %> <%= text_area :comment %> <%= submit_tag 'Post comment' %> <%= end_form_tag %> <% apply_behaviour '#comment', make_remote_form %>
  • 53. A Case Study Sneakr.com: A Web 2.0, Ajax Trainer Shop
  • 54. routes.rb map.resource :products map.resource :basket, :controller => 'basket', :collection => {:clear => :post}
  • 55. The Product Controller class ProductController < ApplicationController def index # show all products @products = Product.find :all end def show # show the details of a product @product = Product.find params[:id] end end
  • 56. index.rhtml <div id=quot;cataloguequot;> <%= render :partial => 'products' %> </div> <div id=quot;basketquot;> <%= render :partial => 'basket' %> </div>
  • 57. _products.rhtml <ul> <% @products.each do |product| %> <li id=quot;<%= product.id %>_prodquot;> <%= link_to product.name, product_url(product) %> <%= product.description %> </li> <% end %> </ul>
  • 58. show.rhtml <h1><%= @product.name %></h1> <p><%= image_tag @product.photo.public_filename %></p> <p><%= @product.description %></p> <p><%= button_to 'Add To Basket', basket_url (@product), :method => :put %></p>
  • 59. The Basket Controller class BasketController < ApplicationController def update @product = Product.find params[:id] @basket << @product redirect_to products_url end end
  • 61. now to add the Ajax
  • 62. <% apply_behaviours do on '#catalogue li', make_draggable(:revert => true) on '#basket', make_drop_receiving( :url => basket_url, :with => quot;'_method=put&id=' + encodeURIComponent(element.id)quot; ) end %>
  • 63. <% apply_behaviours do on '#catalogue li', make_draggable(:revert => true) on '#basket', make_drop_receiving( :url => basket_url, :with => quot;'_method=put&id=' + encodeURIComponent(element.id)quot; ) end %>
  • 64. So how do we deal with this on the server-side?
  • 66. class BasketController < ApplicationController def update @product = Product.find params[:id] @basket << @product redirect_to products_url end end
  • 67. class BasketController < ApplicationController def update @product = Product.find params[:id] @basket << @product respond_to do |type| type.html { redirect_to products_url } type.js end end end
  • 69. Take a look for yourself... http://www.danwebb.net/railsconf2006/ujs_shopping.zip
  • 70. We have no control over the environment our JavaScript runs in
  • 72. The path to enlightenment Write a working application using ★ semantic HTML Style it with CSS ★ Write JavaScript that 'hijacks' the page ★ elements to enhance the UI Learn JavaScript and DOM Scripting ★
  • 73. Further Reading The JavaScript articles on A List Apart ★ (alistapart.com) Unobtrusive Scripting by Christian ★ Heilmann (onlinetools.org) Jeremy Keith's presentations, book and ★ articles (domscripting.com) Google it! ★
  • 74. Upcoming in UJS Improved testing (custom assertions) ★ Improved debugging ★ More behaviour helpers ★ More tutorials on ujs4rails.com ★
  • 75. And finally... <%= apply_behaviour @products, make_draggable %>
  • 76. <% div_for @product, :behavior => make_draggable do %> <h2><%= @product.name %></h2> <p><%= @product.description %></p> <% end %>