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












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