Unobtrusive Ajax With Rails

15,366 views
15,193 views

Published on

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
15,366
On SlideShare
0
From Embeds
0
Number of Embeds
61
Actions
Shares
0
Downloads
1
Comments
0
Likes
32
Embeds 0
No embeds

No notes for slide

Unobtrusive Ajax With Rails

  1. 1. Unobtrusive Ajax With Rails Dan Webb (dan@danwebb. net)
  2. 2. Overview air A bit of history fir What is unobtrusive scripting? * The UJS Plugin air Casestudy * Ranti+= ig—Upcoming UJS Features
  3. 3. The dark days of DHTML
  4. 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. 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. 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. 7. Then web standards arrived
  8. 8. DEN HEBB. N£: T The C| ient—side Cake Style - CSS Content - (X)HTML
  9. 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. 10. JavaScript got a bad name
  11. 11. It deserved it
  12. 12. Web 2.0
  13. 13. llllll ll ‘ ‘:3 l: l l: ji i all In 35 $333.-sin‘
  14. 14. Massive text boxes
  15. 15. Social software
  16. 16. and Ajax. ..
  17. 17. JavaScript is trendy again!
  18. 18. Browser support is much better
  19. 19. We learnt our lessons from the DHTML days
  20. 20. What did we learn?
  21. 21. Unobtrusive DOM Scripting
  22. 22. It's an approach to browser Ul design
  23. 23. It's about separating content and style from behaviour
  24. 24. DEN HEBB. Nt: T Behaviour: A new layer for the client—side cake Behaviour - JavaScript Style - CSS Content - (X)HTML
  25. 25. It's enhancing a working application
  26. 26. so it degrades gracefully when things don't work
  27. 27. It's notju_st about putting JavaScript in a different file
  28. 28. It's not rocket science
  29. 29. It's not the ‘Rails Way‘
  30. 30. An example: 1ink_to_remote
  31. 31. DEN HEBB. NeT <%= 1ink_to_remote ‘View description‘, zcontroller = > 'product', :action = > 'desc', zid = > @product. id %>
  32. 32. DEN HEBB. NeT <a href= ”#" onc1ick= "new Ajax. Request('/ product/ desc/1', {asynchronous true, eva1Scripts: true}); return fa1se; ”>View description</ a>
  33. 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. 34. It's not possible to do that with | ink_to_remote
  35. 35. DEN HEBB. NeT <% @products. each do lproductl %> <%= link_to_remote ‘View description‘, zcontroller = > 'product‘, :action = > 'desc', zid = > @product. id %> <% end %>
  36. 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. 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. 38. Getting started
  39. 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. 40. Remote Links
  41. 41. DEN HEBB. NeT <u1 id= "outline"> <% @items. each do liteml %> <li><%= 1ink_to : action = > ‘more’, zid = > @item. id %></ li> <% end %> </ u1>
  42. 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. 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. 44. What about links with side-effects?
  45. 45. Links should never have side effects
  46. 46. DllN llEBB. Nt: T Use a button <%= button_to ‘Remove from basket‘, zmethod = > zdelete %>
  47. 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. 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. 49. Hijacking forms
  50. 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. 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. 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. 53. l]llN llEBB. Nt: T A Case Study Sneakr. com: A Web 2.0, Ajax Trainer Shop
  54. 54. DllN llEBB. Nt: T routes. rb map. resource zproducts map. resource zbasket, zcontroller = > ‘basket’, zcollection = > {zclear = > zpost}
  55. 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. 56. DllN llEBB. Nt: T index. rhtml <div id= "cata1ogue"> <%= render zpartial </ div> <div id= "basket"> <%= render zpartial </ div> = > = > ‘products’ %> ‘basket’ %>
  57. 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. 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. 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. 60. We're done!
  61. 61. now to add the Ajax
  62. 62. DEN HEBB. NeT <% apply_behaviours do on ’#catalogue li’, make_draggable(: revert = > true) end %>
  63. 63. DEN HEBB. NeT on ’#basket’, make_drop_receiving( zurl = > basket_url, zwith = > "’_method= put&id= ' + encodeURIComponent(element. id)"
  64. 64. So how do we deal With this on the server—side?
  65. 65. respond_to
  66. 66. DEN HEBB. NeT class BasketController < ApplicationController def update @product = Product. find params[ id] @basket << @product redirect_to products_url end end
  67. 67. DEN HEBB. NeT respond_to do ltypel type. html { redirect_to products_url } type. js end
  68. 68. DllN llEBB. Nt: T update. rjs page. replace_html ‘basket’, :partial = > ‘basket’
  69. 69. llllN llEBB. Nt: T Take a look for yourself. .. http: //www. danwebb. net/ rai| sconf2006/ujs_shopping. zip
  70. 70. We have no control overthe environment our JavaScript runs in
  71. 71. Code defensively
  72. 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. 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. 74. DllN llEBB. Nt: T Upcoming in UJS Improved testing (custom assertions) Improved debugging More behaviour helpers More tutorials on ujs4rai| s.com
  75. 75. DllN llEBB. Nt: T And finally. .. <%= apply_behaviour @products, make_draggable %>
  76. 76. DEN HEBB. NeT <% div_for @product, zbehavior = > make_draggable do %> <hZ><%= @product. name %></ h2> <p><%= @product. description %></ p> <% end %>
  77. 77. ' iltl llbfliiisltr l . l l . l ‘ ii i if I ll

×