Tuesday, October 24th, 2006
Unobtrusive Ajax for Rails by Dan Webb
>Notes from Dan Webb's presentation on unobtrusive javascript with Rails. Dan is one half of the team behind UJS4Rails and Low Pro.
- web developer from London, UK
- DHTML hacker for 7 years
- working with RoR for nearly two years
- member of the prototype core team
Web Standards are Good
- more maintabile
- more accessible
- lighter pages
- future proofed better
Javascript and Web Standards
- javascript got a bad name back in teh day
- lots of crappy js around
- web 2.0 has helped maked js more trendy
- plus browser support is much better
What is unobtrusive js
- new behavior layer on top of the client-side cake
- further decoupling from style (css) and content (xhtml)
- its not just putting your js in a different file
- its not the “rails way”
link_to_remote
- ex: link_to_remote which
-
HTML:
-
<a href="#" onclick="new Ajax.Request('/product/desc/1', {opts}); return false;">inline js link</a>
-
- a little better:
HTML:
-
<a href="/product/desc/1" onclick="new Ajax.Request('/product/desc/1', {opts}); return false;">a little better</a>
-
- the better option isnt possible with link_to_remote
Path to Enlightment
- write good app in semantic HTML, CSS, first
- then write javascript to hijack elements and enhance the UI
- dont be scared of JS
UJS Plugin
- plugin to make unobtrusive scripting easier w/ Rails
- define behaviors with CSS selectors
- keep script in external files
- www.ujs4rails.com
- links should never have side effect
- use button_to to insert a form button
- apply_behavior a CSS selector, some behavior (js), and hash of options
At this point Dan gave a demo with a lot of code samples, which you can find by going to his site.
Dynamic Caching
- hashes js file and sets ETag header
- everytime script is requested the ETag is stored by browser
- server can then check the ETag on future requests
- if browser and server match send back 304 Not Modified header
File Caching
- writes files to disk using Rails caching
- faster then dynamic caching
- manual expiration of scripts required
- use observers, cron jobs, etc…same methods use for all of Rails caching
Sensible Defaults
- be angle on your client-side shoulder
- UJS does things the way it wants to, unless you tell it otherwise
- can override most things
- make it easy to do things the right way
Prototype Rocks
- easy API
- large user base
- integration with Rails
- lots of supporting libraries
- good functional utilties
Prototype Sucks
- poor event utilties
- almost exclusively innerHTML based
- performance in some sports
- weird OO extensions
- slowed development in recent months, but promising recently
Enter Low Pro
- set of extensions to Prototype for unobtrusive scripting
- compilation of others wrok
- thx to many other JS authors…
- better event handling, behaviors, DOMBuilder, and more…
Sample Code
- $(‘element’).remove();
- $(‘another’).nextElement();
- (‘my_el’).replaceElement(newEl);
Events
- Event.observe replaced w/ Dean Edwards addEvent()
- return false; to stop default behavior – works in Safari!
- “this” points to the triggering element, like it should
- DOMContentLoaded supported
Behaviors
- inspired by event:Selectors by Justin Palmer
- Event.addBehavior() to do behavior declaratively
- behavior classes for OO style
- nicely encapsulate behaviors in spot for many different elements
Low Pro Plans
- developed alongside UJS for Rails
- lowpro.ujs4rails.com – coming soon
- XPath support
- add on behavior classes for common tasks (dnd, sorting, etc)
- behavior debugging
Plans for UJS
- improved testing
- more behavior helpers
- more tutorials
- ways around the session problem
- integration with Simply Helpful
Wrapping Up
- unobtrusive js should be default way to approach problems
- rails is not up to it out of the box
- UJS is one attempt
Related Content:











bullet points two deep does not an article make. The slides by themselves aren’t very coherent, is the presentation available online anywhere?
The presentations should be available online eventually – all audio is being recorded, and some talks are also being videotaped. I don’t know what will be available free and what won’t…
Did you have specific questions on any of the points? Most talks are moving pretty fast so in-depth outlines aren’t really possible.
@spoggle – in fairness, Ajaxian are doing a very good job at being the CNN of JavaScript. They occasionally delete our comments, they BLOCKQUOTE everything, the spelling and proof-reading are not of the highest quality — but what other web-sites keep you up to date so good? :-)
thank a lot.
Just a quick note re: link_to_remote. You *can* get the second option out of it. Example:
{:controller => 'product', :action => 'desc', :id => 1}}, {:href => url_for({:controller => 'product', :action => 'desc', :id => 1}) %>
or, a little cleaner:
'product', :action => 'desc', :id => 1 %>
url}, {:href => url} %>
Wow! The live preview didn’t accurately reflect what would be posted at all. Here’s what the code should’ve looked like:
<%= link_to_remote 'a little better', {:url => {:controller => 'product', :action => 'desc', :id => 1}}, {:href => url_for({:controller => 'product', :action => 'desc', :id => 1})} %>
and
<% url = url_for :controller => 'product', :action => 'desc', :id => 1 %>
<%= link_to_remote 'a little better', {:url => url}, {:href => url} %>
Thanks for the note, Ben. So it _is_ possible, it just requires a whole lot of extra work when it should do it be default. :)
A mini rant on Dan Webb’s comment
Few days ago I was reading a post ( Unobtrusive Ajax for Rails by Dan Webb ) and kinda got upset. Although I agree with Dan Webb on many points and I am all for UJS a specific bullet point annoyed me. See if you can spot it.
What is unobtrusive js