SlideShare ist ein Scribd-Unternehmen logo
1 von 72
NinjaScript
JavaScript so unobtrusive, you’ll never see it coming.
Evan Dorn
Owner and Lead Developer,
 Logical Reality Design
Credits
NinjaScript was invented and (almost) entirely coded by


               Judson Lester
     Co-owner and Senior Developer
NinjaScript Provides

• A behavior layer built on jQuery
• Easy UJS AJAX that degrades gracefully
• Persistent behavior that just works
• CSS-like syntax for rich JS behavior
• Cool prepackaged behaviors
What do we want?
(In an AJAXy, RESTful Rails app)
What do we want?
    (In an AJAXy, RESTful Rails app)


• JavaScript should be unobtrusive
What do we want?
    (In an AJAXy, RESTful Rails app)


• JavaScript should be unobtrusive
• AJAX actions should degrade gracefully
What do we want?
    (In an AJAXy, RESTful Rails app)


• JavaScript should be unobtrusive
• AJAX actions should degrade gracefully
• RESTful methods should degrade gracefully
What do we want?
    (In an AJAXy, RESTful Rails app)


• JavaScript should be unobtrusive
• AJAX actions should degrade gracefully
• RESTful methods should degrade gracefully
• This shouldn’t take any extra work!
Rails 2 Approach

• AJAX helpers: link_to_remote and
  form_remote_for
• REST methods (PUT and DELETE)
  simulated via a hidden form field
• link_to_remote() arguments aren’t the
  same format as link_to()
Rails 2 Approach: links
link_to_remote(‘click me’, :url => some_path)
<a href=”#” onclick=”bleaaaaaaaaaaaaaaaaaaaarghh oh please
just kill me now my eyes are bleeding”>
  click me
</a>
Rails 2 Approach: links
link_to_remote(‘click me’, :url => some_path)
<a href=”#” onclick=”bleaaaaaaaaaaaaaaaaaaaarghh oh please
just kill me now my eyes are bleeding”>
  click me
</a>



Graceful degradation requires an extra argument:
link_to_remote(‘click me’, { :url => some_path },
    { :href => some_path } )
Rails 2 Approach: forms
form_remote_for(@object)
<form action=”/objects/1” method=”post” onsubmit=”lots
   more. Horrible_JavaScript_crap_here uglifying_my_html”>

  <input name=”_method” type=”hidden” value=”put”>

   ... your fields here ...

</a>


Non - POST/GET requests simulated via hidden
input.
Rails 3 Approach: links
link_to with :remote => true
<%= link_to ‘click me’, ‘/foo’, :remote => true,
    :method => :delete %>


Generates:
<a href=”/foo” data-method=”delete” data-remote=”true”>
  click me
</a>


Unobtrusive invisible form created by rails.js
Rails 3 Approach: forms
form_for with :remote => true
<%= form_for @product, :remote => true do |form| %>
    <%= ... your inputs here ... %>


Generates:
<form action=”/products/1” data-method=”put” data-
remote=”true”>

  ... your inputs here ...

</form>

Hidden _method input added by rails.js upon submit
Rails 3 Approach: forms
Rails 3 Approach: forms
• So Rails 3 gives us UJS ...
Rails 3 Approach: forms
• So Rails 3 gives us UJS ...
• ... At the cost of making REST dependent
  on JavaScript
Rails 3 Approach: forms
• So Rails 3 gives us UJS ...
• ... At the cost of making REST dependent
  on JavaScript
• A fresh scaffold - non AJAX - won’t even
  work without JS in Rails 3
Rails 3 Approach: forms
• So Rails 3 gives us UJS ...
• ... At the cost of making REST dependent
  on JavaScript
• A fresh scaffold - non AJAX - won’t even
  work without JS in Rails 3
• End-to-end integration testing can’t be
  done without Selenium or similar
Rails 3 Approach: forms
• So Rails 3 gives us UJS ...
• ... At the cost of making REST dependent
  on JavaScript
• A fresh scaffold - non AJAX - won’t even
  work without JS in Rails 3
• End-to-end integration testing can’t be
  done without Selenium or similar
• ... oops
Use jQuery?


• Bind event handler to each form that
  submits via AJAX.
• ... kind of a pain, though ...
Use jQuery?
$(document.ready(function() {
  $(‘form#make_me_ajax’).submit(function (){
    $.post(
      ”/products”,
      $(“form#make_me_ajax”).serialize(),
      function(data) {
        ... some return behavior ...
         }
      );
  });
});


( To be fair, there are plugins that make this easier,
like jQuery Form etc. )
The NinjaScript Way


Here’s what it looks like in NinjaScript.

Don’t change your form (or link) at all.
The NinjaScript Way

$.behavior({
  'form#product':   submits_as_ajax()
})
The NinjaScript Way
      Specify behaviors of many elements in a
                  CSS-like format.

$.behavior({
  'form#product':   submits_as_ajax(),

 ‘a.delete_link’:   submits_as_ajax(),

  ‘flash.error’:    decays()
})
Let’s see it in action



       ( Demo )
What’s the Score?
                           AJAX     REST
              Unobtrusive                     Easy
                          degrades degrades
  Rails 2

  Rails 3

 jQuery

NinjaScript
Persistent Behavior
Persistent Behavior
     (CSS is awesome,
      JavaScript sucks)
Persistent Behavior
Persistent Behavior

• We take CSS’s default behavior for granted.
• CSS styles apply to everything in the DOM,
  even if it changes.
• Why aren’t JS behaviors the same way?
DOM Reconstruction and
   Event Bindings
DOM Reconstruction and
   Event Bindings

                         div#content




             a.has_tooltip        a.has_tooltip
DOM Reconstruction and
       Event Bindings
•   Bind a tooltip behavior
                                          div#content
    to $(‘.has_tooltip’)


                              a.has_tooltip        a.has_tooltip
DOM Reconstruction and
       Event Bindings
•   Bind a tooltip behavior
                                          div#content
    to $(‘.has_tooltip’)

•   Dynamically add a
    new .tooltip element      a.has_tooltip        a.has_tooltip



                              a.has_tooltip
DOM Reconstruction and
       Event Bindings
•   Bind a tooltip behavior
                                          div#content
    to $(‘.has_tooltip’)

•   Dynamically add a
    new .tooltip element      a.has_tooltip        a.has_tooltip

•   New element has no
    bound event handler!
                              a.has_tooltip
DOM Reconstruction and
       Event Bindings
•   Bind a tooltip behavior
                                          div#content
    to $(‘.has_tooltip’)

•   Dynamically add a
    new .tooltip element      a.has_tooltip        a.has_tooltip

•   New element has no
    bound event handler!
                              a.has_tooltip

•   This is really lame ...
What we want
What we want

• Our JS should specify, via CSS selectors,
  behaviors that apply to elements
What we want

• Our JS should specify, via CSS selectors,
  behaviors that apply to elements
• Those behaviors should always apply in all
  conditions
What we want

• Our JS should specify, via CSS selectors,
  behaviors that apply to elements
• Those behaviors should always apply in all
  conditions
• The coder shouldn’t have to waste
  braincycles on it
Solution 1:
Event Delegation
Solution 1:
           Event Delegation

• jQuery live() and similar
Solution 1:
          Event Delegation

• jQuery live() and similar
• Bind handlers to root element of the DOM
Solution 1:
          Event Delegation

• jQuery live() and similar
• Bind handlers to root element of the DOM
• Since browsers bubble unhandled events up
  the DOM, the root handles all events
Solution 1:
          Event Delegation

• jQuery live() and similar
• Bind handlers to root element of the DOM
• Since browsers bubble unhandled events up
  the DOM, the root handles all events
  This is pretty awesome.
The Problem with
Event Delegation
The Problem with
          Event Delegation

• live() can’t handle element transformations
The Problem with
          Event Delegation

• live() can’t handle element transformations
• ... like giving <div>s rounded corners ...
The Problem with
          Event Delegation

• live() can’t handle element transformations
• ... like giving <div>s rounded corners ...
• Because there’s no event to process when
  we insert new elements into the DOM
The Problem with
            Event Delegation

• live() can’t handle element transformations
• ... like giving <div>s rounded corners ...
• Because there’s no event to process when
    we insert new elements into the DOM
•   ECMA-compliant browsers are suppossed to send
    DOMSubtreeModified and DOMNodeInserted
The Problem with
            Event Delegation

• live() can’t handle element transformations
• ... like giving <div>s rounded corners ...
• Because there’s no event to process when
    we insert new elements into the DOM
•   ECMA-compliant browsers are suppossed to send
    DOMSubtreeModified and DOMNodeInserted
                 (Bad IE! No Biscuit!)
Any other transformations?
Any other transformations?



• How about taking degradable DELETE forms
  and turning them into links?
                     (demo)
Solution 1I:
      Automatic Rebinding

• Bind to and/or transform the element, not
  the root.
• NinjaScript examines new DOM elements
  to see if any known behaviors match.
• NinjaScript fires its own event when the
  DOM is reconstructed so it works in IE.
How do I use it?
Defining a Behavior
Defining a Behavior
• Make a mapping of selectors to behaviors
  and pass it to $.behavior()
Defining a Behavior
• Make a mapping of selectors to behaviors
  and pass it to $.behavior()
• Each behavior can include an events block
  and a transform.
Defining a Behavior
• Make a mapping of selectors to behaviors
  and pass it to $.behavior()
• Each behavior can include an events block
  and a transform.
• Transform is applied as soon as the element
  is in the DOM.
Defining a Behavior
• Make a mapping of selectors to behaviors
  and pass it to $.behavior()
• Each behavior can include an events block
  and a transform.
• Transform is applied as soon as the element
  is in the DOM.
• Events blocks are a mapping of click:,
  focus:, mouseover: etc. to behaviors.
Defining a Behavior
$.behavior({
  '.awesome': {
    transform:  function(elem){... do something ...},

      events: {
        click:     function(evnt,elem){... handle click ...},
        mouseover: function(evnt,elem){... pop tooltip ...}
      }
  }
})


      All awesome elements will get the transform
         applied, no matter when they’re added.
Defining a Behavior
Shortcut: skip the ‘events:’ mapping if you’re just
handling an event.

$.behavior({
  '.awesome': {
      click: function(event,elem){ ... handle click ...},
  }
})
Reusable Behaviors
You can easily define and name behaviors for
reuse.
Reusable Behaviors
You can easily define and name behaviors for
reuse.
function sings_and_dances(){
  return new behavior({
    transform: function(elem)     { elem.add_a_tutu() },
    click:     function(evnt,elem){ elem.pirouette() },
    mouseover: function(evnt,elem){ elem.sing_an_aria()}
  })
}
Reusable Behaviors
You can easily define and name behaviors for
reuse.
function sings_and_dances(){
  return new behavior({
    transform: function(elem)     { elem.add_a_tutu() },
    click:     function(evnt,elem){ elem.pirouette() },
    mouseover: function(evnt,elem){ elem.sing_an_aria()}
  })
}

$.behavior({
  ‘#dhh’:         sings_and_dances(),
  ‘#katz’:        sings_and_dances(),
  ‘.code_monkey’: signs_and_dances()
})
Pre-Defined Behaviors
 These work today - built into NinjaScript

• submits_as_ajax
• submits_as_ajax_form
• submits_as_ajax_link
• becomes_ajax_link (for forms)
• decays (fades away after 10 sec)
Nifty Feature: ‘Busy’ spinner



           ( Demo )
Planned Behaviors
                Coming Soon!

• pops_tooltip          • gets_round_corners
• validates_local       • gets_drop_shadow
• validates_via_ajax    • replaced_by_image
• autocompletes         • watermarked
• has_ajax_observer     • sortable
• editable_via_ajax     • sortable_via_ajax
Future Plans

• Complete replacement for rails.js
• NinjaHelper Rails plugin/gem to make links
  and forms with non GET/POST methods
  degrade gracefully
• Prototype / MooTools / YUI support
  (maybe)
Come Help Us!

NinjaScript is at version 0.6
fork: http://github.com/lrdesign/NinjaScript
http://groups.google.com/group/lrd-ninjascript

Weitere ähnliche Inhalte

Was ist angesagt?

JQUERY TUTORIALS
JQUERY TUTORIALSJQUERY TUTORIALS
JQUERY TUTORIALS
Moize Roxas
 
#pragma conf 2013 - UIKit dynamics
#pragma conf 2013  - UIKit dynamics#pragma conf 2013  - UIKit dynamics
#pragma conf 2013 - UIKit dynamics
Renzo G. Pretto
 

Was ist angesagt? (19)

JQUERY TUTORIALS
JQUERY TUTORIALSJQUERY TUTORIALS
JQUERY TUTORIALS
 
Lets go vanilla
Lets go vanillaLets go vanilla
Lets go vanilla
 
jQuery basics for Beginners
jQuery basics for BeginnersjQuery basics for Beginners
jQuery basics for Beginners
 
Learning About JavaScript (…and its little buddy, JQuery!)
Learning About JavaScript (…and its little buddy, JQuery!)Learning About JavaScript (…and its little buddy, JQuery!)
Learning About JavaScript (…and its little buddy, JQuery!)
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
 
JsViews - Next Generation jQuery Templates
JsViews - Next Generation jQuery TemplatesJsViews - Next Generation jQuery Templates
JsViews - Next Generation jQuery Templates
 
Accessibility Hacks Wordcamp Manchester October 2018
Accessibility Hacks Wordcamp Manchester October 2018Accessibility Hacks Wordcamp Manchester October 2018
Accessibility Hacks Wordcamp Manchester October 2018
 
jQuery Objects
jQuery ObjectsjQuery Objects
jQuery Objects
 
Accessibility Hacks version 2
Accessibility Hacks version 2Accessibility Hacks version 2
Accessibility Hacks version 2
 
Mvc - Model: the great forgotten
Mvc - Model: the great forgottenMvc - Model: the great forgotten
Mvc - Model: the great forgotten
 
#pragma conf 2013 - UIKit dynamics
#pragma conf 2013  - UIKit dynamics#pragma conf 2013  - UIKit dynamics
#pragma conf 2013 - UIKit dynamics
 
JQuery
JQueryJQuery
JQuery
 
Framework dead
Framework deadFramework dead
Framework dead
 
Styling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS EditionStyling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS Edition
 
J Query Presentation of David
J Query Presentation of DavidJ Query Presentation of David
J Query Presentation of David
 
The Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQueryThe Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQuery
 
Learning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesLearning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User Interfaces
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
Styling components with JavaScript
Styling components with JavaScriptStyling components with JavaScript
Styling components with JavaScript
 

Andere mochten auch

RAJESH - GRAPHIC DESIGNER- RESUME 2016
RAJESH - GRAPHIC DESIGNER- RESUME 2016RAJESH - GRAPHIC DESIGNER- RESUME 2016
RAJESH - GRAPHIC DESIGNER- RESUME 2016
Rajesh Ravi
 
Pharma24bd.DELAR QUOTATION
Pharma24bd.DELAR QUOTATIONPharma24bd.DELAR QUOTATION
Pharma24bd.DELAR QUOTATION
G M ISLAM
 
Sample code to create files on your desktop using APEX
Sample code to create files on your desktop using APEXSample code to create files on your desktop using APEX
Sample code to create files on your desktop using APEX
Deepak Balur
 
The 2015 Sony world photography awards entries
The 2015 Sony world photography awards entriesThe 2015 Sony world photography awards entries
The 2015 Sony world photography awards entries
Makala D.
 

Andere mochten auch (18)

DIGITAL DIVIDE IN THAILAND: ANALYSIS AND RECOMMENDATIONS
DIGITAL DIVIDE IN THAILAND: ANALYSIS AND RECOMMENDATIONSDIGITAL DIVIDE IN THAILAND: ANALYSIS AND RECOMMENDATIONS
DIGITAL DIVIDE IN THAILAND: ANALYSIS AND RECOMMENDATIONS
 
Humanoid robot by mitesh kumar
Humanoid robot by mitesh kumarHumanoid robot by mitesh kumar
Humanoid robot by mitesh kumar
 
Stunning Glasswing Butterfly - Greta oto
Stunning Glasswing Butterfly  -  Greta otoStunning Glasswing Butterfly  -  Greta oto
Stunning Glasswing Butterfly - Greta oto
 
Web 2 - Gastronomia
Web 2 - GastronomiaWeb 2 - Gastronomia
Web 2 - Gastronomia
 
RAJESH - GRAPHIC DESIGNER- RESUME 2016
RAJESH - GRAPHIC DESIGNER- RESUME 2016RAJESH - GRAPHIC DESIGNER- RESUME 2016
RAJESH - GRAPHIC DESIGNER- RESUME 2016
 
Pharma24bd.DELAR QUOTATION
Pharma24bd.DELAR QUOTATIONPharma24bd.DELAR QUOTATION
Pharma24bd.DELAR QUOTATION
 
Sample code to create files on your desktop using APEX
Sample code to create files on your desktop using APEXSample code to create files on your desktop using APEX
Sample code to create files on your desktop using APEX
 
Lkti aaaaa
Lkti aaaaaLkti aaaaa
Lkti aaaaa
 
ION Bangladesh - IPv6 Experiences at Sri Lanka Telecom
ION Bangladesh - IPv6 Experiences at Sri Lanka TelecomION Bangladesh - IPv6 Experiences at Sri Lanka Telecom
ION Bangladesh - IPv6 Experiences at Sri Lanka Telecom
 
ION Bangladesh - ISOC Dhaka Chapter Welcome
ION Bangladesh - ISOC Dhaka Chapter WelcomeION Bangladesh - ISOC Dhaka Chapter Welcome
ION Bangladesh - ISOC Dhaka Chapter Welcome
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
 
ICH S4 (Duration of Chronic Toxicity Testing in Animals (Rodent and Non Roden...
ICH S4 (Duration of Chronic Toxicity Testing in Animals (Rodent and Non Roden...ICH S4 (Duration of Chronic Toxicity Testing in Animals (Rodent and Non Roden...
ICH S4 (Duration of Chronic Toxicity Testing in Animals (Rodent and Non Roden...
 
Menus 5
Menus 5Menus 5
Menus 5
 
A Ferrovia em Portugal
A Ferrovia em PortugalA Ferrovia em Portugal
A Ferrovia em Portugal
 
Οι κάψουλες της Ιαπωνίας
Οι κάψουλες της ΙαπωνίαςΟι κάψουλες της Ιαπωνίας
Οι κάψουλες της Ιαπωνίας
 
BSSML16 L3. Clusters and Anomaly Detection
BSSML16 L3. Clusters and Anomaly DetectionBSSML16 L3. Clusters and Anomaly Detection
BSSML16 L3. Clusters and Anomaly Detection
 
The 2015 Sony world photography awards entries
The 2015 Sony world photography awards entriesThe 2015 Sony world photography awards entries
The 2015 Sony world photography awards entries
 
BSSML16 L2. Ensembles and Logistic Regressions
BSSML16 L2. Ensembles and Logistic RegressionsBSSML16 L2. Ensembles and Logistic Regressions
BSSML16 L2. Ensembles and Logistic Regressions
 

Ähnlich wie NinjaScript 2010-10-14

React.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UIReact.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UI
Marcin Grzywaczewski
 
Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)
Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)
Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)
Thinkful
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jquery
Kostas Mavridis
 
J query presentation
J query presentationJ query presentation
J query presentation
akanksha17
 
J query presentation
J query presentationJ query presentation
J query presentation
sawarkar17
 
Javascript spaghetti stirtrek_5_17
Javascript  spaghetti stirtrek_5_17Javascript  spaghetti stirtrek_5_17
Javascript spaghetti stirtrek_5_17
Jared Faris
 
jQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesjQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPages
Mark Roden
 

Ähnlich wie NinjaScript 2010-10-14 (20)

Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationLotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshop
 
Flexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework WorldFlexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework World
 
Flexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework WorldFlexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework World
 
J query
J queryJ query
J query
 
DirectToWeb 2.0
DirectToWeb 2.0DirectToWeb 2.0
DirectToWeb 2.0
 
React.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UIReact.js - and how it changed our thinking about UI
React.js - and how it changed our thinking about UI
 
Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)
Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)
Build a Web App with JavaScript and jQuery (5:18:17, Los Angeles)
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
Building Rich User Experiences Without JavaScript Spaghetti
Building Rich User Experiences Without JavaScript SpaghettiBuilding Rich User Experiences Without JavaScript Spaghetti
Building Rich User Experiences Without JavaScript Spaghetti
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jquery
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architecture
 
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
 
J query presentation
J query presentationJ query presentation
J query presentation
 
J query presentation
J query presentationJ query presentation
J query presentation
 
Javascript spaghetti stirtrek_5_17
Javascript  spaghetti stirtrek_5_17Javascript  spaghetti stirtrek_5_17
Javascript spaghetti stirtrek_5_17
 
JavaScript for ASP.NET programmers (webcast) upload
JavaScript for ASP.NET programmers (webcast) uploadJavaScript for ASP.NET programmers (webcast) upload
JavaScript for ASP.NET programmers (webcast) upload
 
jQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesjQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPages
 
Building Better Web Apps with Angular.js (SXSW 2014)
Building Better Web Apps with Angular.js (SXSW 2014)Building Better Web Apps with Angular.js (SXSW 2014)
Building Better Web Apps with Angular.js (SXSW 2014)
 
KnockoutJS and MVVM
KnockoutJS and MVVMKnockoutJS and MVVM
KnockoutJS and MVVM
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 

NinjaScript 2010-10-14

  • 1. NinjaScript JavaScript so unobtrusive, you’ll never see it coming.
  • 2. Evan Dorn Owner and Lead Developer, Logical Reality Design
  • 3. Credits NinjaScript was invented and (almost) entirely coded by Judson Lester Co-owner and Senior Developer
  • 4. NinjaScript Provides • A behavior layer built on jQuery • Easy UJS AJAX that degrades gracefully • Persistent behavior that just works • CSS-like syntax for rich JS behavior • Cool prepackaged behaviors
  • 5. What do we want? (In an AJAXy, RESTful Rails app)
  • 6. What do we want? (In an AJAXy, RESTful Rails app) • JavaScript should be unobtrusive
  • 7. What do we want? (In an AJAXy, RESTful Rails app) • JavaScript should be unobtrusive • AJAX actions should degrade gracefully
  • 8. What do we want? (In an AJAXy, RESTful Rails app) • JavaScript should be unobtrusive • AJAX actions should degrade gracefully • RESTful methods should degrade gracefully
  • 9. What do we want? (In an AJAXy, RESTful Rails app) • JavaScript should be unobtrusive • AJAX actions should degrade gracefully • RESTful methods should degrade gracefully • This shouldn’t take any extra work!
  • 10. Rails 2 Approach • AJAX helpers: link_to_remote and form_remote_for • REST methods (PUT and DELETE) simulated via a hidden form field • link_to_remote() arguments aren’t the same format as link_to()
  • 11. Rails 2 Approach: links link_to_remote(‘click me’, :url => some_path) <a href=”#” onclick=”bleaaaaaaaaaaaaaaaaaaaarghh oh please just kill me now my eyes are bleeding”> click me </a>
  • 12. Rails 2 Approach: links link_to_remote(‘click me’, :url => some_path) <a href=”#” onclick=”bleaaaaaaaaaaaaaaaaaaaarghh oh please just kill me now my eyes are bleeding”> click me </a> Graceful degradation requires an extra argument: link_to_remote(‘click me’, { :url => some_path }, { :href => some_path } )
  • 13. Rails 2 Approach: forms form_remote_for(@object) <form action=”/objects/1” method=”post” onsubmit=”lots more. Horrible_JavaScript_crap_here uglifying_my_html”> <input name=”_method” type=”hidden” value=”put”> ... your fields here ... </a> Non - POST/GET requests simulated via hidden input.
  • 14. Rails 3 Approach: links link_to with :remote => true <%= link_to ‘click me’, ‘/foo’, :remote => true, :method => :delete %> Generates: <a href=”/foo” data-method=”delete” data-remote=”true”> click me </a> Unobtrusive invisible form created by rails.js
  • 15. Rails 3 Approach: forms form_for with :remote => true <%= form_for @product, :remote => true do |form| %> <%= ... your inputs here ... %> Generates: <form action=”/products/1” data-method=”put” data- remote=”true”> ... your inputs here ... </form> Hidden _method input added by rails.js upon submit
  • 17. Rails 3 Approach: forms • So Rails 3 gives us UJS ...
  • 18. Rails 3 Approach: forms • So Rails 3 gives us UJS ... • ... At the cost of making REST dependent on JavaScript
  • 19. Rails 3 Approach: forms • So Rails 3 gives us UJS ... • ... At the cost of making REST dependent on JavaScript • A fresh scaffold - non AJAX - won’t even work without JS in Rails 3
  • 20. Rails 3 Approach: forms • So Rails 3 gives us UJS ... • ... At the cost of making REST dependent on JavaScript • A fresh scaffold - non AJAX - won’t even work without JS in Rails 3 • End-to-end integration testing can’t be done without Selenium or similar
  • 21. Rails 3 Approach: forms • So Rails 3 gives us UJS ... • ... At the cost of making REST dependent on JavaScript • A fresh scaffold - non AJAX - won’t even work without JS in Rails 3 • End-to-end integration testing can’t be done without Selenium or similar • ... oops
  • 22. Use jQuery? • Bind event handler to each form that submits via AJAX. • ... kind of a pain, though ...
  • 23. Use jQuery? $(document.ready(function() { $(‘form#make_me_ajax’).submit(function (){ $.post( ”/products”, $(“form#make_me_ajax”).serialize(), function(data) { ... some return behavior ... } ); }); }); ( To be fair, there are plugins that make this easier, like jQuery Form etc. )
  • 24. The NinjaScript Way Here’s what it looks like in NinjaScript. Don’t change your form (or link) at all.
  • 25. The NinjaScript Way $.behavior({ 'form#product': submits_as_ajax() })
  • 26. The NinjaScript Way Specify behaviors of many elements in a CSS-like format. $.behavior({ 'form#product': submits_as_ajax(), ‘a.delete_link’: submits_as_ajax(), ‘flash.error’: decays() })
  • 27. Let’s see it in action ( Demo )
  • 28. What’s the Score? AJAX REST Unobtrusive Easy degrades degrades Rails 2 Rails 3 jQuery NinjaScript
  • 30. Persistent Behavior (CSS is awesome, JavaScript sucks)
  • 32. Persistent Behavior • We take CSS’s default behavior for granted. • CSS styles apply to everything in the DOM, even if it changes. • Why aren’t JS behaviors the same way?
  • 33. DOM Reconstruction and Event Bindings
  • 34. DOM Reconstruction and Event Bindings div#content a.has_tooltip a.has_tooltip
  • 35. DOM Reconstruction and Event Bindings • Bind a tooltip behavior div#content to $(‘.has_tooltip’) a.has_tooltip a.has_tooltip
  • 36. DOM Reconstruction and Event Bindings • Bind a tooltip behavior div#content to $(‘.has_tooltip’) • Dynamically add a new .tooltip element a.has_tooltip a.has_tooltip a.has_tooltip
  • 37. DOM Reconstruction and Event Bindings • Bind a tooltip behavior div#content to $(‘.has_tooltip’) • Dynamically add a new .tooltip element a.has_tooltip a.has_tooltip • New element has no bound event handler! a.has_tooltip
  • 38. DOM Reconstruction and Event Bindings • Bind a tooltip behavior div#content to $(‘.has_tooltip’) • Dynamically add a new .tooltip element a.has_tooltip a.has_tooltip • New element has no bound event handler! a.has_tooltip • This is really lame ...
  • 40. What we want • Our JS should specify, via CSS selectors, behaviors that apply to elements
  • 41. What we want • Our JS should specify, via CSS selectors, behaviors that apply to elements • Those behaviors should always apply in all conditions
  • 42. What we want • Our JS should specify, via CSS selectors, behaviors that apply to elements • Those behaviors should always apply in all conditions • The coder shouldn’t have to waste braincycles on it
  • 44. Solution 1: Event Delegation • jQuery live() and similar
  • 45. Solution 1: Event Delegation • jQuery live() and similar • Bind handlers to root element of the DOM
  • 46. Solution 1: Event Delegation • jQuery live() and similar • Bind handlers to root element of the DOM • Since browsers bubble unhandled events up the DOM, the root handles all events
  • 47. Solution 1: Event Delegation • jQuery live() and similar • Bind handlers to root element of the DOM • Since browsers bubble unhandled events up the DOM, the root handles all events This is pretty awesome.
  • 49. The Problem with Event Delegation • live() can’t handle element transformations
  • 50. The Problem with Event Delegation • live() can’t handle element transformations • ... like giving <div>s rounded corners ...
  • 51. The Problem with Event Delegation • live() can’t handle element transformations • ... like giving <div>s rounded corners ... • Because there’s no event to process when we insert new elements into the DOM
  • 52. The Problem with Event Delegation • live() can’t handle element transformations • ... like giving <div>s rounded corners ... • Because there’s no event to process when we insert new elements into the DOM • ECMA-compliant browsers are suppossed to send DOMSubtreeModified and DOMNodeInserted
  • 53. The Problem with Event Delegation • live() can’t handle element transformations • ... like giving <div>s rounded corners ... • Because there’s no event to process when we insert new elements into the DOM • ECMA-compliant browsers are suppossed to send DOMSubtreeModified and DOMNodeInserted (Bad IE! No Biscuit!)
  • 55. Any other transformations? • How about taking degradable DELETE forms and turning them into links? (demo)
  • 56. Solution 1I: Automatic Rebinding • Bind to and/or transform the element, not the root. • NinjaScript examines new DOM elements to see if any known behaviors match. • NinjaScript fires its own event when the DOM is reconstructed so it works in IE.
  • 57. How do I use it?
  • 59. Defining a Behavior • Make a mapping of selectors to behaviors and pass it to $.behavior()
  • 60. Defining a Behavior • Make a mapping of selectors to behaviors and pass it to $.behavior() • Each behavior can include an events block and a transform.
  • 61. Defining a Behavior • Make a mapping of selectors to behaviors and pass it to $.behavior() • Each behavior can include an events block and a transform. • Transform is applied as soon as the element is in the DOM.
  • 62. Defining a Behavior • Make a mapping of selectors to behaviors and pass it to $.behavior() • Each behavior can include an events block and a transform. • Transform is applied as soon as the element is in the DOM. • Events blocks are a mapping of click:, focus:, mouseover: etc. to behaviors.
  • 63. Defining a Behavior $.behavior({ '.awesome': { transform: function(elem){... do something ...}, events: { click: function(evnt,elem){... handle click ...}, mouseover: function(evnt,elem){... pop tooltip ...} } } }) All awesome elements will get the transform applied, no matter when they’re added.
  • 64. Defining a Behavior Shortcut: skip the ‘events:’ mapping if you’re just handling an event. $.behavior({ '.awesome': { click: function(event,elem){ ... handle click ...}, } })
  • 65. Reusable Behaviors You can easily define and name behaviors for reuse.
  • 66. Reusable Behaviors You can easily define and name behaviors for reuse. function sings_and_dances(){ return new behavior({ transform: function(elem) { elem.add_a_tutu() }, click: function(evnt,elem){ elem.pirouette() }, mouseover: function(evnt,elem){ elem.sing_an_aria()} }) }
  • 67. Reusable Behaviors You can easily define and name behaviors for reuse. function sings_and_dances(){ return new behavior({ transform: function(elem) { elem.add_a_tutu() }, click: function(evnt,elem){ elem.pirouette() }, mouseover: function(evnt,elem){ elem.sing_an_aria()} }) } $.behavior({ ‘#dhh’: sings_and_dances(), ‘#katz’: sings_and_dances(), ‘.code_monkey’: signs_and_dances() })
  • 68. Pre-Defined Behaviors These work today - built into NinjaScript • submits_as_ajax • submits_as_ajax_form • submits_as_ajax_link • becomes_ajax_link (for forms) • decays (fades away after 10 sec)
  • 69. Nifty Feature: ‘Busy’ spinner ( Demo )
  • 70. Planned Behaviors Coming Soon! • pops_tooltip • gets_round_corners • validates_local • gets_drop_shadow • validates_via_ajax • replaced_by_image • autocompletes • watermarked • has_ajax_observer • sortable • editable_via_ajax • sortable_via_ajax
  • 71. Future Plans • Complete replacement for rails.js • NinjaHelper Rails plugin/gem to make links and forms with non GET/POST methods degrade gracefully • Prototype / MooTools / YUI support (maybe)
  • 72. Come Help Us! NinjaScript is at version 0.6 fork: http://github.com/lrdesign/NinjaScript http://groups.google.com/group/lrd-ninjascript

Hinweis der Redaktion