Your SlideShare is downloading. ×
0
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Unobtrusive Ajax With Rails
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Unobtrusive Ajax With Rails

14,850

Published on

Dan Webb (dan@danwebb.net) From: www.danwebb.net/railsconf2006/ujs_railsconf.pdf

Dan Webb (dan@danwebb.net) From: www.danwebb.net/railsconf2006/ujs_railsconf.pdf

Published in: Business, Technology
0 Comments
32 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
14,850
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
32
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Unobtrusive Ajax With Rails Dan Webb (dan@danwebb. net)
  • 2. Overview air A bit of history fir What is unobtrusive scripting? * The UJS Plugin air Casestudy * Ranti+= ig—Upcoming UJS Features
  • 3. The dark days of DHTML
  • 4. an H ‘/ ’i: ’~l‘7' This is best viewed in 800 x 600 resolution. We strongly suggest that you have "Internet Explorer 5.0”. Can be viewed with lntemet Explorer 3.0 and Netscape Navigator 3.0. If your computer is not 800 x 600 res. You would not be able to view this site property. 1 / /
  • 5. '3“ Microsoft Internet Explorer la 4. l3‘lllit M: This site is best viewed with 4.0 and up versions of Netscape Navigator/ Communicator or Microsoft Intemet Explorer. Some downloadable documents can only be viewed with Adobe® Acrobat® Reader. Click on any of the Icon's to download the latest software.
  • 6. on-line CIV This site has been optimised for lE4+ and Netscape 4+ with 800x600 resolution. Flash site 2-2. HTl/ ll_ site
  • 7. Then web standards arrived
  • 8. DEN HEBB. N£: T The C| ient—side Cake Style - CSS Content - (X)HTML
  • 9. What web standards did for us * More maintainable at More accessible fir Leaner pages * Platform independent (print, mobile. ..) * ‘Future-proof‘ as well as backwards compatible
  • 10. JavaScript got a bad name
  • 11. It deserved it
  • 12. Web 2.0
  • 13. llllll ll ‘ ‘:3 l: l l: ji i all In 35 $333.-sin‘
  • 14. Massive text boxes
  • 15. Social software
  • 16. and Ajax. ..
  • 17. JavaScript is trendy again!
  • 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 Ul design
  • 23. It's about separating content and style from behaviour
  • 24. DEN HEBB. Nt: T Behaviour: A new layer for the client—side cake Behaviour - JavaScript Style - CSS Content - (X)HTML
  • 25. It's enhancing a working application
  • 26. so it degrades gracefully when things don't work
  • 27. It's notju_st about putting JavaScript in a different file
  • 28. It's not rocket science
  • 29. It's not the ‘Rails Way‘
  • 30. An example: 1ink_to_remote
  • 31. DEN HEBB. NeT <%= 1ink_to_remote ‘View description‘, zcontroller = > 'product', :action = > 'desc', zid = > @product. id %>
  • 32. DEN HEBB. NeT <a href= ”#" onc1ick= "new Ajax. Request('/ product/ desc/1', {asynchronous true, eva1Scripts: true}); return fa1se; ”>View description</ a>
  • 33. DEN HEBB. NeT <a href= ”/product/ desc/1” onc1ick= ”new Ajax. Request(this. href, {asynchronous true, eva1Scripts: true}); return fa1se; ”>View description</ a>
  • 34. It's not possible to do that with | ink_to_remote
  • 35. DEN HEBB. NeT <% @products. each do lproductl %> <%= link_to_remote ‘View description‘, zcontroller = > 'product‘, :action = > 'desc', zid = > @product. id %> <% end %>
  • 36. DEN HEBB. NeT vrcduct <a href= onc1ick= “"on A1ax. Roq _ return la se; ”>View description</ a> '4' {as ch"o"cus: truo. ova Scr17ts: trao} <a href= ”W' onclick= vrcduct roturn la so; ”>View description</ a> rn A1ax. {oq {usy"th"o"cus: . ' Str1vts: truo}); <a href= ”t' onc1ick= in Aiax. <oqJcst(‘ vrcduct roturn la sr ”>View description</ a> {usy"th"o"cus: truo. ova Scr1vts: truo}); <a href= ”¢' onc1ick= “~ou Aiax. “ "vrcdutt dost ‘. {asyethro —: trao. ova Str1its: truo}); return la ”>View description</ a> <a href= ”"' onc1ick= “ren A]ax. ’eaJest{' ~rcduct ; h"o"cus: true. eva Scr17ts: true}): return la ' ”>View description</ a> <a href= ”v' onc1ick= “"on Aiax. “ vrcduct 'h"o"cus: truo. ova Scr1vts: trao}); "Oturn fa so; ”>View description</ a> <a href= ”v' onc1ick= “"on A1ax.1oqJos vrcduct JCBC '. {asvrch"o"cus: truo. ova Scr1vts: trao}); return la se; ”>View description</ a> vrcduct <a href= ”t' onc1ick= “ jn Aiax. <oqJcst( return fa se; ”>View description</ a> {usy"th"o"cus: truo. ova Scr1vts: truo}); Lt‘ vrcduct <a href= ”t' onc1ick= “ on A}ax. {oq roturn la sr ”>View description</ a> {usy"th"o"cus: . ' Scr1vts: truo}); <a href= ‘¢ onc1ick= “~on A1ax. ?oqJost(">rcdutt dost ‘. {asy"chro"cJ2:trao. ova Str1its: truo}); roturn la so; ”>View description</ a> <a href= ”¢' onc1ick= “ren A]ax. ’eaJest{' ~rcduct descr ; h"o"cus: true. eva Scr17ts: true}): roturn la so; ”>View description</ a> <a href= ”¢' onc1ick= “ren A]ax. ’eaJest{' ~rcduct descr ‘. {asv"ch"o"cus: true. eva Scr17ts: true}): roturn la so; ”>View description</ a> <a href= ”v' onc1ick= “"on Aiax. “ vrcduct {asvrch"o"cus: truo. ova Scr1vts: trao}); "Oturn fa so; ”>View description</ a> <a href= onc1ick= “"on A1ax.1oqJost(' vrcduct JCBC '. {asvrch"o"cus: truo. ova Scr1vts: trao}); return la >View description</ a>
  • 37. (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a (a href-“I” href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" href-"I" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-" oncltck-' oncltck-" nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu nu ‘nu nu Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax. Ajax Ajax RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( ' / product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , RegJest( '/ product/ desc/1' , .RegJest( ' / product/ desc/1' , .RegJest( '/ product/ desc/1' , (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: (asynchronous: true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: eval Scrlpts: (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): (Welt): f| 'U¢)): (Welt): (Welt): return return return return return return return return return return return return return return return return return return return return return return return return return return return return return return return return false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " false; " >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vien >Vi en descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a> descr1ption</ as descr1ption</ a>
  • 38. Getting started
  • 39. DllN llEBB. Nt: T 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 wvvw. ujs4rai| s.com - check it out!
  • 40. Remote Links
  • 41. DEN HEBB. NeT <u1 id= "outline"> <% @items. each do liteml %> <li><%= 1ink_to : action = > ‘more’, zid = > @item. id %></ li> <% end %> </ u1>
  • 42. DEN HEBB. NeT <u1 id= "out1ine"> <% @items. each do liteml %> <1i><%= 1ink_to : action = > ‘more’, zid = > @item. id %></ li> <% end %> </ u1> <% app1y_behaviour '#outline a click‘, ‘new Ajax. Request(this. href); return false; ' %>
  • 43. DEN HEBB. NeT <u1 id= "out1ine"> <% @items. each do liteml %> <li><%= link_to : action = > ‘more’, :id = > @item. id %></ li> <% end %> </ ul> <% app1y_behaviour ‘#out1ine a‘, make_remote_1ink %>
  • 44. What about links with side-effects?
  • 45. Links should never have side effects
  • 46. DllN llEBB. Nt: T Use a button <%= button_to ‘Remove from basket‘, zmethod = > zdelete %>
  • 47. [_lnN HEBB. NeT <for'm c1ass= "button-to" action= "/basket/2" method= "post"> <input type= "hidden" name= “_method" va1ue= "de1ete" / > <input type= “submit" value= "Remove from basket" / > </ form>
  • 48. DllN llEBB. Nt: T Then attach the behaviour <%= button_to ‘Remove from basket‘, zmethod = > zdelete %> <% apply_behaviour 'form. button—to', make_remote_form %>
  • 49. Hijacking forms
  • 50. DEN HEBB. NeT <%= form_tag zurl = > entries_ur1, zid = > ‘comment’ %> <%= text_field : name %> <%= text_field zemail %> <%= text_area : comment %> <%= submit_tag ‘Post comment‘ %> <%= end_Form_tag %>
  • 51. DEN HEBB. NeT <%= form_tag : ur1 = > entries_ur1, zid = > ‘comment’ %> <%= text_field : name %> <%= text_fie1d : 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. DEN HEBB. NeT <%= form_tag : ur1 = > entries_ur1, zid = > ‘comment’ %> <%= text_fie1d : name %> <%= text_field : email %> <%= text_area : comment %> <%= submit_tag ‘Post comment‘ %> <%= end_form_tag %> <% app1y_behaviour ‘#comment‘, make_remote_form %>
  • 53. l]llN llEBB. Nt: T A Case Study Sneakr. com: A Web 2.0, Ajax Trainer Shop
  • 54. DllN llEBB. Nt: T routes. rb map. resource zproducts map. resource zbasket, zcontroller = > ‘basket’, zcollection = > {zclear = > zpost}
  • 55. The Product Controller class ProductContro11er < App1icationContro11er def index # show all products @products = Product. find : a11 end def show # show the details of a product @product = Product. find params[: id] end end
  • 56. DllN llEBB. Nt: T index. rhtml <div id= "cata1ogue"> <%= render zpartial </ div> <div id= "basket"> <%= render zpartial </ div> = > = > ‘products’ %> ‘basket’ %>
  • 57. DllN llEBB. Nt: T _products. rhtm| <ul> <% @products. each do lproductl %> <1i id= "<%= product. id %>_prod"> <%= 1ink_to product. name, product_url(product) %> <%= product. description %> </1i> <% end %> </ u1>
  • 58. DllN llEBB. Nt: T show. rhtm| <h1><%= @product. name %></ h1> <p><%= image_tag @product. photo. pub1ic_fi1ename %></ p> <p><%= @product. description %></ p> <p><%= button_to ‘Add To Basket’, basket_ur1 (@product), zmethod = > zput %></ p>
  • 59. DllN llEBB. Nt: T The Basket Controller class BasketController < ApplicationController def update @product = Product. find params[: id] @basket << @product redirect_to products_url end end
  • 60. We're done!
  • 61. now to add the Ajax
  • 62. DEN HEBB. NeT <% apply_behaviours do on ’#catalogue li’, make_draggable(: revert = > true) end %>
  • 63. DEN HEBB. NeT on ’#basket’, make_drop_receiving( zurl = > basket_url, zwith = > "’_method= put&id= ' + encodeURIComponent(element. id)"
  • 64. So how do we deal With this on the server—side?
  • 65. respond_to
  • 66. DEN HEBB. NeT class BasketController < ApplicationController def update @product = Product. find params[ id] @basket << @product redirect_to products_url end end
  • 67. DEN HEBB. NeT respond_to do ltypel type. html { redirect_to products_url } type. js end
  • 68. DllN llEBB. Nt: T update. rjs page. replace_html ‘basket’, :partial = > ‘basket’
  • 69. llllN llEBB. Nt: T Take a look for yourself. .. http: //www. danwebb. net/ rai| sconf2006/ujs_shopping. zip
  • 70. We have no control overthe environment our JavaScript runs in
  • 71. Code defensively
  • 72. DllN llEBB. Nt: T 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. DllN llEBB. Nt: T Further Reading The JavaScript articles on A List Apart (alistapart. com) Unobtrusive Scripting by Christian Heilmann (on| inetools. org) Jeremy Keith's presentations, book and articles (domscripting. com) Google it!
  • 74. DllN llEBB. Nt: T Upcoming in UJS Improved testing (custom assertions) Improved debugging More behaviour helpers More tutorials on ujs4rai| s.com
  • 75. DllN llEBB. Nt: T And finally. .. <%= apply_behaviour @products, make_draggable %>
  • 76. DEN HEBB. NeT <% div_for @product, zbehavior = > make_draggable do %> <hZ><%= @product. name %></ h2> <p><%= @product. description %></ p> <% end %>
  • 77. ' iltl llbfliiisltr l . l l . l ‘ ii i if I ll

×