Upgrade to Pro — share decks privately, control downloads, hide ads and more …

script.aculo.us

 script.aculo.us

Christophe Porteneuve

July 25, 2007
Tweet

More Decks by Christophe Porteneuve

Other Decks in Technology

Transcript

  1. script.aculo.us
    Christophe Porteneuve
    The Ajax Experience · San Francisco, July 25 2007

    View Slide

  2. This is an intro, yet...

    View Slide

  3. This is an intro, yet...
    • It’s better if you do know some Prototype

    View Slide

  4. This is an intro, yet...
    • It’s better if you do know some Prototype
    ‣ script.aculo.us relies heavily on it

    View Slide

  5. This is an intro, yet...
    • It’s better if you do know some Prototype
    ‣ script.aculo.us relies heavily on it
    ‣ If you just attended one of the Prototype
    sessions this morning, you should be fine

    View Slide

  6. This is an intro, yet...
    • It’s better if you do know some Prototype
    ‣ script.aculo.us relies heavily on it
    ‣ If you just attended one of the Prototype
    sessions this morning, you should be fine
    • As for script.aculo.us, we’ll skim the surface
    and showcast the features.

    View Slide

  7. Who am I?

    View Slide

  8. Who am I?
    • 29, lives in Paris. Web work since 1995

    View Slide

  9. Who am I?
    • 29, lives in Paris. Web work since 1995
    • Prototype Core member

    View Slide

  10. Who am I?
    • 29, lives in Paris. Web work since 1995
    • Prototype Core member
    • Rails & script.aculo.us contributor

    View Slide

  11. Who am I?
    • 29, lives in Paris. Web work since 1995
    • Prototype Core member
    • Rails & script.aculo.us contributor
    • Prototype doc writer (prototypejs.org)

    View Slide

  12. Who am I?
    • 29, lives in Paris. Web work since 1995
    • Prototype Core member
    • Rails & script.aculo.us contributor
    • Prototype doc writer (prototypejs.org)
    • Prototype & script.aculo.us book author

    View Slide

  13. Who am I?
    • 29, lives in Paris. Web work since 1995
    • Prototype Core member
    • Rails & script.aculo.us contributor
    • Prototype doc writer (prototypejs.org)
    • Prototype & script.aculo.us book author
    • Top question batter on the Google Group

    View Slide

  14. What are we going to see?

    View Slide

  15. What are we going to see?
    • Visual effects

    View Slide

  16. What are we going to see?
    • Visual effects
    • Drag and drop, re-orderable elements

    View Slide

  17. What are we going to see?
    • Visual effects
    • Drag and drop, re-orderable elements
    • Autocompletion

    View Slide

  18. What are we going to see?
    • Visual effects
    • Drag and drop, re-orderable elements
    • Autocompletion
    • In-place editing

    View Slide

  19. What are we going to see?
    • Visual effects
    • Drag and drop, re-orderable elements
    • Autocompletion
    • In-place editing
    • Sliders

    View Slide

  20. What are we going to see?
    • Visual effects
    • Drag and drop, re-orderable elements
    • Autocompletion
    • In-place editing
    • Sliders
    • Concise DOM building

    View Slide

  21. Visual effects

    View Slide

  22. Overview

    View Slide

  23. Overview
    • No Flash, no SVG, just plain JS/CSS/DOM!

    View Slide

  24. Overview
    • No Flash, no SVG, just plain JS/CSS/DOM!
    • 6 Core Effects, 18 Combined Effects

    View Slide

  25. Overview
    • No Flash, no SVG, just plain JS/CSS/DOM!
    • 6 Core Effects, 18 Combined Effects
    • 9 “transitions” (control acceleration)

    View Slide

  26. Overview
    • No Flash, no SVG, just plain JS/CSS/DOM!
    • 6 Core Effects, 18 Combined Effects
    • 9 “transitions” (control acceleration)
    • Fine-tune: 8 generic options, 7 callbacks

    View Slide

  27. Overview
    • No Flash, no SVG, just plain JS/CSS/DOM!
    • 6 Core Effects, 18 Combined Effects
    • 9 “transitions” (control acceleration)
    • Fine-tune: 8 generic options, 7 callbacks
    • Queues to sync timelines

    View Slide

  28. Overview
    • No Flash, no SVG, just plain JS/CSS/DOM!
    • 6 Core Effects, 18 Combined Effects
    • 9 “transitions” (control acceleration)
    • Fine-tune: 8 generic options, 7 callbacks
    • Queues to sync timelines
    • Custom effects easy to implement

    View Slide

  29. Triggering an effect

    View Slide

  30. Triggering an effect
    • new Effect.Name(element[, arg][, options])

    View Slide

  31. Triggering an effect
    • new Effect.Name(element[, arg][, options])
    ‣ Mandatory argument sometimes (e.g. Scale)

    View Slide

  32. Triggering an effect
    • new Effect.Name(element[, arg][, options])
    ‣ Mandatory argument sometimes (e.g. Scale)
    ‣ As usual, a hash of options. Many effects
    feature specific options in addition of the 8
    generic ones.

    View Slide

  33. Triggering an effect
    • new Effect.Name(element[, arg][, options])
    ‣ Mandatory argument sometimes (e.g. Scale)
    ‣ As usual, a hash of options. Many effects
    feature specific options in addition of the 8
    generic ones.
    new Effect.Opacity('header', { to: 0.5 });

    View Slide

  34. Triggering an effect
    • new Effect.Name(element[, arg][, options])
    ‣ Mandatory argument sometimes (e.g. Scale)
    ‣ As usual, a hash of options. Many effects
    feature specific options in addition of the 8
    generic ones.
    new Effect.Opacity('header', { to: 0.5 });
    new Effect.Highlight('notice', { duration: 2 });

    View Slide

  35. Triggering an effect
    • new Effect.Name(element[, arg][, options])
    ‣ Mandatory argument sometimes (e.g. Scale)
    ‣ As usual, a hash of options. Many effects
    feature specific options in addition of the 8
    generic ones.
    new Effect.Opacity('header', { to: 0.5 });
    new Effect.Highlight('notice', { duration: 2 });
    new Effect.Scale('mugshot', 200, { scaleFromCenter: true });

    View Slide

  36. Core effects

    View Slide

  37. Core effects
    • Opacity
    ‣ Alters an element’s opacity. Relies on the
    generic from/to options to define opacity.

    View Slide

  38. Core effects
    • Opacity
    ‣ Alters an element’s opacity. Relies on the
    generic from/to options to define opacity.
    • Move
    ‣ Absolute or relative movement

    View Slide

  39. Core effects
    • Opacity
    ‣ Alters an element’s opacity. Relies on the
    generic from/to options to define opacity.
    • Move
    ‣ Absolute or relative movement
    • Scale
    ‣ Resizing (impacting textual contents or not)

    View Slide

  40. Core effects

    View Slide

  41. Core effects
    • Highlight
    ‣ Cross-fading background color

    View Slide

  42. Core effects
    • Highlight
    ‣ Cross-fading background color
    • Morph
    ‣ Smoothly migrating any set of measurable CSS
    properties (colors, sizes) in sync!

    View Slide

  43. Core effects
    • Highlight
    ‣ Cross-fading background color
    • Morph
    ‣ Smoothly migrating any set of measurable CSS
    properties (colors, sizes) in sync!
    • Parallel
    ‣ Synchronized execution of multiple effects

    View Slide

  44. Generic options

    View Slide

  45. Generic options
    • When to start
    ‣ delay, queue

    View Slide

  46. Generic options
    • When to start
    ‣ delay, queue
    • How fast to go
    ‣ fps, sync, transition

    View Slide

  47. Generic options
    • When to start
    ‣ delay, queue
    • How fast to go
    ‣ fps, sync, transition
    • Cutting corners: where to start and stop
    ‣ from, to

    View Slide

  48. Core Effects demos

    View Slide

  49. Core Effects demos
    • Effect.Morph
    • Using custom queues
    • “Flash Stompers”
    ‣ Effect.multiple + Element.tagifyText
    • Creating a custom effect: Effect.Wave

    View Slide

  50. Combined effects

    View Slide

  51. Combined effects
    • Just like core, except you don’t need new

    View Slide

  52. Combined effects
    • Just like core, except you don’t need new
    • Many symmetrical ones:
    ‣ Appear/Fade, BlindDown/Up, SlideDown/Up
    ‣ Grow/Shrink

    View Slide

  53. Combined effects
    • Just like core, except you don’t need new
    • Many symmetrical ones:
    ‣ Appear/Fade, BlindDown/Up, SlideDown/Up
    ‣ Grow/Shrink
    • And funky ones to boot:
    ‣ DropOut, Puff, SwitchOff, Squish, Fold,
    Pulsate, Shake, Transform...

    View Slide

  54. Combined Effects demo
    • Let’s look at live examples of just about
    every combined effect...

    View Slide

  55. Drag and drop

    View Slide

  56. Overview

    View Slide

  57. Overview
    • Custom use / manual setup

    View Slide

  58. Overview
    • Custom use / manual setup
    ‣ Making an element draggable

    View Slide

  59. Overview
    • Custom use / manual setup
    ‣ Making an element draggable
    ‣ Setting up an element as a drop zone

    View Slide

  60. Overview
    • Custom use / manual setup
    ‣ Making an element draggable
    ‣ Setting up an element as a drop zone
    ‣ Controlling drag, restricting drops

    View Slide

  61. Overview
    • Custom use / manual setup
    ‣ Making an element draggable
    ‣ Setting up an element as a drop zone
    ‣ Controlling drag, restricting drops
    • Foremost use-case: re-orderable elements

    View Slide

  62. Making stuff draggable

    View Slide

  63. Making stuff draggable
    • new Draggable(element[, options])

    View Slide

  64. Making stuff draggable
    • new Draggable(element[, options])
    • How easier can it get?!

    View Slide

  65. Making stuff draggable
    • new Draggable(element[, options])
    • How easier can it get?!
    • Can be disabled by calling destroy() on
    the Draggable instance.

    View Slide

  66. Dragging, my way.

    View Slide

  67. Dragging, my way.
    • Reverting

    View Slide

  68. Dragging, my way.
    • Reverting
    • Movement restrictions (handle)

    View Slide

  69. Dragging, my way.
    • Reverting
    • Movement restrictions (handle)
    • Using specific handles to drag

    View Slide

  70. Dragging, my way.
    • Reverting
    • Movement restrictions (handle)
    • Using specific handles to drag
    • Staying within a scrolling container

    View Slide

  71. Dragging, my way.
    • Reverting
    • Movement restrictions (handle)
    • Using specific handles to drag
    • Staying within a scrolling container
    • Delayed triggering, dragging layer, ghosting...

    View Slide

  72. Dragging, my way.
    • Reverting
    • Movement restrictions (handle)
    • Using specific handles to drag
    • Staying within a scrolling container
    • Delayed triggering, dragging layer, ghosting...
    • Callbacks on start, drag step, drag release

    View Slide

  73. Dragging demo
    • A plump Tux wandering on a mini Chess
    board (now that’s an odd sight)

    View Slide

  74. Here’s your drop zone

    View Slide

  75. Here’s your drop zone
    • Droppables.add(element[, options])

    View Slide

  76. Here’s your drop zone
    • Droppables.add(element[, options])
    • Droppables.remove(element)

    View Slide

  77. Here’s your drop zone
    • Droppables.add(element[, options])
    • Droppables.remove(element)
    • Callbacks (dropped element & drop zone)

    View Slide

  78. Here’s your drop zone
    • Droppables.add(element[, options])
    • Droppables.remove(element)
    • Callbacks (dropped element & drop zone)

    View Slide

  79. Here’s your drop zone
    • Droppables.add(element[, options])
    • Droppables.remove(element)
    • Callbacks (dropped element & drop zone)
    • ...do we actually charge clients for this?!

    View Slide

  80. Not letting anybody in

    View Slide

  81. Not letting anybody in
    • Restricting on CSS class names

    View Slide

  82. Not letting anybody in
    • Restricting on CSS class names
    • Restricting on container of origin

    View Slide

  83. Drop demo
    • A shopping cart with a trash can

    View Slide

  84. Re-ordering lists...
    with your mouse

    View Slide

  85. Re-ordering lists...
    with your mouse
    • Sortable.create(container[, options])

    View Slide

  86. Re-ordering lists...
    with your mouse
    • Sortable.create(container[, options])
    • Sortable.destroy(container)

    View Slide

  87. Re-ordering lists...
    with your mouse
    • Sortable.create(container[, options])
    • Sortable.destroy(container)

    View Slide

  88. Re-ordering lists...
    with your mouse
    • Sortable.create(container[, options])
    • Sortable.destroy(container)

    View Slide

  89. Re-ordering lists...
    with your mouse
    • Sortable.create(container[, options])
    • Sortable.destroy(container)
    • Refund that client now, scoundrel!

    View Slide

  90. It doesn’t have to be lists...

    View Slide

  91. It doesn’t have to be lists...
    • It can be any container element, and any
    child elements

    View Slide

  92. It doesn’t have to be lists...
    • It can be any container element, and any
    child elements
    ‣ It doesn’t even have to be all the children

    View Slide

  93. It doesn’t have to be lists...
    • It can be any container element, and any
    child elements
    ‣ It doesn’t even have to be all the children
    ‣ It doesn’t have to be vertical

    View Slide

  94. It doesn’t have to be lists...
    • It can be any container element, and any
    child elements
    ‣ It doesn’t even have to be all the children
    ‣ It doesn’t have to be vertical
    ‣ You can even swap elements between
    containers!

    View Slide

  95. It doesn’t have to be lists...
    • It can be any container element, and any
    child elements
    ‣ It doesn’t even have to be all the children
    ‣ It doesn’t have to be vertical
    ‣ You can even swap elements between
    containers!
    • Two callbacks keep you posted on changes

    View Slide

  96. Re-ordering demos

    View Slide

  97. Re-ordering demos
    • A regular sorted list with callbacks and
    serialization of the updated order
    • An horizontal list (you gotta love CSS)
    • Re-ordering part of the ’s in a
    • Playing with multiple lists

    View Slide

  98. Autocompletion

    View Slide

  99. Overview

    View Slide

  100. Overview
    • Assisted typing (e.g. Google Suggest)
    ‣ Terrific to reduce misspellings, duplicates...
    ‣ Helps accelerate the input process

    View Slide

  101. Overview
    • Assisted typing (e.g. Google Suggest)
    ‣ Terrific to reduce misspellings, duplicates...
    ‣ Helps accelerate the input process
    • Processes a ul/li list
    ‣ CSS can make it look like anything we want

    View Slide

  102. Overview
    • Assisted typing (e.g. Google Suggest)
    ‣ Terrific to reduce misspellings, duplicates...
    ‣ Helps accelerate the input process
    • Processes a ul/li list
    ‣ CSS can make it look like anything we want
    • Full keyboard+mouse operation

    View Slide

  103. Overview
    • Assisted typing (e.g. Google Suggest)
    ‣ Terrific to reduce misspellings, duplicates...
    ‣ Helps accelerate the input process
    • Processes a ul/li list
    ‣ CSS can make it look like anything we want
    • Full keyboard+mouse operation
    • Suggested items can be content-rich

    View Slide

  104. The basics

    View Slide

  105. The basics
    • new Ajax.Autocompleter(element,
    container, url[, options])

    View Slide

  106. The basics
    • new Ajax.Autocompleter(element,
    container, url[, options])
    • A few CSS rules won’t hurt, too.

    View Slide

  107. The basics
    • new Ajax.Autocompleter(element,
    container, url[, options])
    • A few CSS rules won’t hurt, too.
    • Plenty of cool options

    View Slide

  108. The basics
    • new Ajax.Autocompleter(element,
    container, url[, options])
    • A few CSS rules won’t hurt, too.
    • Plenty of cool options
    ‣ autoSelect, minChars, frequency...

    View Slide

  109. The basics
    • new Ajax.Autocompleter(element,
    container, url[, options])
    • A few CSS rules won’t hurt, too.
    • Plenty of cool options
    ‣ autoSelect, minChars, frequency...
    ‣ AJAX is 98% of use cases; can also be local...

    View Slide

  110. Dealing with rich contents

    View Slide

  111. Dealing with rich contents
    • Often suggesting texts alone is insufficient

    View Slide

  112. Dealing with rich contents
    • Often suggesting texts alone is insufficient
    • Example: company’s internal directory
    ‣ Just how many “John Smith” are at GE/BofA?

    View Slide

  113. Dealing with rich contents
    • Often suggesting texts alone is insufficient
    • Example: company’s internal directory
    ‣ Just how many “John Smith” are at GE/BofA?
    • Bringing up more info helps the user
    ‣ Dept. name, photo, dates, file sizes, whatever
    ‣ But completion should still extract our text

    View Slide

  114. Multiple-field completion

    View Slide

  115. Multiple-field completion
    • “John Smith, Corporate Accts” looks nice,
    but the server will hate it
    ‣ Why don’t you send it a nice person_id?
    ‣ You don’t want your server’s hatred...

    View Slide

  116. Multiple-field completion
    • “John Smith, Corporate Accts” looks nice,
    but the server will hate it
    ‣ Why don’t you send it a nice person_id?
    ‣ You don’t want your server’s hatred...
    • So we should hook up on the completion
    and grab more info from the selected entry
    ‣ Complete multiple fields, visible or hidden...

    View Slide

  117. Autocompletion demo

    View Slide

  118. Autocompletion demo
    • Consolidated demo
    ‣ AJAX completion based on installed Ruby
    libraries
    ‣ Rich contents
    ‣ Can complete multiple entries in the same
    field

    View Slide

  119. In-place editing

    View Slide

  120. Overview

    View Slide

  121. Overview
    • Makes any document fragment editable

    View Slide

  122. Overview
    • Makes any document fragment editable
    ‣ Right there, right then: in place

    View Slide

  123. Overview
    • Makes any document fragment editable
    ‣ Right there, right then: in place
    • Numerous options address most needs

    View Slide

  124. Overview
    • Makes any document fragment editable
    ‣ Right there, right then: in place
    • Numerous options address most needs
    ‣ Working on an alternate text (i.e. not HTML)

    View Slide

  125. Overview
    • Makes any document fragment editable
    ‣ Right there, right then: in place
    • Numerous options address most needs
    ‣ Working on an alternate text (i.e. not HTML)
    ‣ Customize editor controls

    View Slide

  126. Overview
    • Makes any document fragment editable
    ‣ Right there, right then: in place
    • Numerous options address most needs
    ‣ Working on an alternate text (i.e. not HTML)
    ‣ Customize editor controls
    ‣ Offer a dropdown list instead of free typing

    View Slide

  127. Overview
    • Makes any document fragment editable
    ‣ Right there, right then: in place
    • Numerous options address most needs
    ‣ Working on an alternate text (i.e. not HTML)
    ‣ Customize editor controls
    ‣ Offer a dropdown list instead of free typing
    • Recently 100% rewritten: clean-slate code

    View Slide

  128. A simple editable fragment

    View Slide

  129. A simple editable fragment
    • new Ajax.InPlaceEditor(element,
    url[, options])

    View Slide

  130. A simple editable fragment
    • new Ajax.InPlaceEditor(element,
    url[, options])
    ‣ Uses an OK button and a Cancel link

    View Slide

  131. A simple editable fragment
    • new Ajax.InPlaceEditor(element,
    url[, options])
    ‣ Uses an OK button and a Cancel link
    ‣ Binds to Return and Esc

    View Slide

  132. A simple editable fragment
    • new Ajax.InPlaceEditor(element,
    url[, options])
    ‣ Uses an OK button and a Cancel link
    ‣ Binds to Return and Esc
    ‣ Uses a POST request

    View Slide

  133. A simple editable fragment
    • new Ajax.InPlaceEditor(element,
    url[, options])
    ‣ Uses an OK button and a Cancel link
    ‣ Binds to Return and Esc
    ‣ Uses a POST request
    ‣ Works over the native markup

    View Slide

  134. A simple editable fragment
    • new Ajax.InPlaceEditor(element,
    url[, options])
    ‣ Uses an OK button and a Cancel link
    ‣ Binds to Return and Esc
    ‣ Uses a POST request
    ‣ Works over the native markup
    ‣ Uses multiple-line editor only if needed

    View Slide

  135. Nips & tucks

    View Slide

  136. Nips & tucks
    • Tweak AJAX persistence
    ‣ paramName, callback, ajaxOptions,
    htmlResponse

    View Slide

  137. Nips & tucks
    • Tweak AJAX persistence
    ‣ paramName, callback, ajaxOptions,
    htmlResponse
    • Customize appearance
    ‣ TONS of options: controls, texts, CSS classes...

    View Slide

  138. Nips & tucks
    • Tweak AJAX persistence
    ‣ paramName, callback, ajaxOptions,
    htmlResponse
    • Customize appearance
    ‣ TONS of options: controls, texts, CSS classes...
    • Plenty of callbacks

    View Slide

  139. Working with an alternate
    textual form

    View Slide

  140. Working with an alternate
    textual form
    • Perhaps you’re storing these dynamic markups
    as something other than HTML

    View Slide

  141. Working with an alternate
    textual form
    • Perhaps you’re storing these dynamic markups
    as something other than HTML
    ‣ Textile? Markdown? Wiki? Something... darker?

    View Slide

  142. Working with an alternate
    textual form
    • Perhaps you’re storing these dynamic markups
    as something other than HTML
    ‣ Textile? Markdown? Wiki? Something... darker?
    • You’d want your user to edit in that format

    View Slide

  143. Working with an alternate
    textual form
    • Perhaps you’re storing these dynamic markups
    as something other than HTML
    ‣ Textile? Markdown? Wiki? Something... darker?
    • You’d want your user to edit in that format
    ‣ Load an alternate text when entering editing

    View Slide

  144. Working with an alternate
    textual form
    • Perhaps you’re storing these dynamic markups
    as something other than HTML
    ‣ Textile? Markdown? Wiki? Something... darker?
    • You’d want your user to edit in that format
    ‣ Load an alternate text when entering editing
    ‣ Respond to persistence with the matching
    markup, as usual

    View Slide

  145. Using a dropdown list

    View Slide

  146. Using a dropdown list
    • So your users can’t be trusted?

    View Slide

  147. Using a dropdown list
    • So your users can’t be trusted?
    • You’d like them to pick from a dropdown list
    (“combo”) instead...

    View Slide

  148. Using a dropdown list
    • So your users can’t be trusted?
    • You’d like them to pick from a dropdown list
    (“combo”) instead...
    • Just use Ajax.InPlaceCollectionEditor
    ‣ Collection can be local or AJAX-based

    View Slide

  149. In-place editing demos

    View Slide

  150. In-place editing demos
    • Simple editing with a few style options
    • Editing an alternate text representation
    • Using a collection-based editor

    View Slide

  151. Sliders

    View Slide

  152. Sliders in 30”
    (re-enacted by rabbits)

    View Slide

  153. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)

    View Slide

  154. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)
    • One or more handles sliding on a track

    View Slide

  155. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)
    • One or more handles sliding on a track
    • Easy customization through CSS + options

    View Slide

  156. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)
    • One or more handles sliding on a track
    • Easy customization through CSS + options
    ‣ Orientation: vertical or horizontal

    View Slide

  157. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)
    • One or more handles sliding on a track
    • Easy customization through CSS + options
    ‣ Orientation: vertical or horizontal
    ‣ Restrict valid positions

    View Slide

  158. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)
    • One or more handles sliding on a track
    • Easy customization through CSS + options
    ‣ Orientation: vertical or horizontal
    ‣ Restrict valid positions
    ‣ Prevent handles from crossing each other

    View Slide

  159. Sliders in 30”
    (re-enacted by rabbits)
    • Replaces numerical input (free/dropdown)
    • One or more handles sliding on a track
    • Easy customization through CSS + options
    ‣ Orientation: vertical or horizontal
    ‣ Restrict valid positions
    ‣ Prevent handles from crossing each other
    ‣ Using handle pairs to define value ranges

    View Slide

  160. Slider demos

    View Slide

  161. Slider demos
    • Simple sliders
    ‣ Vertical & horizontal
    ‣ Callbacks
    • Multiple-handle slider
    • 3 handles defining 2 ranges, no cross-over

    View Slide

  162. Concise DOM building

    View Slide

  163. Building DOM fragments
    “by hand” is booooring

    View Slide

  164. Building DOM fragments
    “by hand” is booooring
    • Yet sometimes update/insert won’t cut it
    ‣ Browser innerHTML (or equiv.) weirdness

    View Slide

  165. Building DOM fragments
    “by hand” is booooring
    • Yet sometimes update/insert won’t cut it
    ‣ Browser innerHTML (or equiv.) weirdness
    • Prototype has a nice new Element thing
    ‣ But one element at a time, no textual content

    View Slide

  166. Building DOM fragments
    “by hand” is booooring
    • Yet sometimes update/insert won’t cut it
    ‣ Browser innerHTML (or equiv.) weirdness
    • Prototype has a nice new Element thing
    ‣ But one element at a time, no textual content
    • So how do we manually build DOM
    fragments in a concise, expressive way?

    View Slide

  167. Builder.node

    View Slide

  168. Builder.node
    Builder.node('p')

    View Slide

  169. Builder.node
    Builder.node('p')
    //

    View Slide

  170. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })

    View Slide

  171. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //

    View Slide

  172. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')

    View Slide

  173. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!

    View Slide

  174. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!
    Builder.node('p', { id: 'demo' }, 'Hello world')

    View Slide

  175. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!
    Builder.node('p', { id: 'demo' }, 'Hello world')
    // Hello world!

    View Slide

  176. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!
    Builder.node('p', { id: 'demo' }, 'Hello world')
    // Hello world!
    Builder.node('div', [Builder.node('h2', 'Intro'), 'Hey'])

    View Slide

  177. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!
    Builder.node('p', { id: 'demo' }, 'Hello world')
    // Hello world!
    Builder.node('div', [Builder.node('h2', 'Intro'), 'Hey'])
    // IntroHey

    View Slide

  178. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!
    Builder.node('p', { id: 'demo' }, 'Hello world')
    // Hello world!
    Builder.node('div', [Builder.node('h2', 'Intro'), 'Hey'])
    // IntroHey
    Builder.node('div', { id: 'demo' }, ['Hey',
    Builder.node('h2', { className: 'regular' }, 'Intro')])

    View Slide

  179. Builder.node
    Builder.node('p')
    //
    Builder.node('p', { id: 'demo', className: 'notice' })
    //
    Builder.node('p', 'Hello world!')
    // Hello world!
    Builder.node('p', { id: 'demo' }, 'Hello world')
    // Hello world!
    Builder.node('div', [Builder.node('h2', 'Intro'), 'Hey'])
    // IntroHey
    Builder.node('div', { id: 'demo' }, ['Hey',
    Builder.node('h2', { className: 'regular' }, 'Intro')])
    // HeyIntro

    View Slide

  180. Builder.dump: shortcuts!

    View Slide

  181. Builder.dump: shortcuts!
    Builder.dump();

    View Slide

  182. Builder.dump: shortcuts!
    Builder.dump();
    P()

    View Slide

  183. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //

    View Slide

  184. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })

    View Slide

  185. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //

    View Slide

  186. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')

    View Slide

  187. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!

    View Slide

  188. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!
    P({ id: 'demo' }, 'Hello world')

    View Slide

  189. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!
    P({ id: 'demo' }, 'Hello world')
    // Hello world!

    View Slide

  190. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!
    P({ id: 'demo' }, 'Hello world')
    // Hello world!
    DIV('div', [H2('Intro'), 'Hey'])

    View Slide

  191. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!
    P({ id: 'demo' }, 'Hello world')
    // Hello world!
    DIV('div', [H2('Intro'), 'Hey'])
    // IntroHey

    View Slide

  192. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!
    P({ id: 'demo' }, 'Hello world')
    // Hello world!
    DIV('div', [H2('Intro'), 'Hey'])
    // IntroHey
    DIV({ id: 'demo' }, ['Hey', H2({ className: 'regular' }, 'Intro')])

    View Slide

  193. Builder.dump: shortcuts!
    Builder.dump();
    P()
    //
    P({ id: 'demo', className: 'notice' })
    //
    P('Hello world!')
    // Hello world!
    P({ id: 'demo' }, 'Hello world')
    // Hello world!
    DIV('div', [H2('Intro'), 'Hey'])
    // IntroHey
    DIV({ id: 'demo' }, ['Hey', H2({ className: 'regular' }, 'Intro')])
    // HeyIntro

    View Slide

  194. Builder demo
    • Interactive Builder code execution

    View Slide

  195. Online resources

    View Slide

  196. Online resources
    • The documentation sites
    ‣ http://prototypejs.org to understand the code
    ‣ http://script.aculo.us to download and read
    the Wiki (massive overhaul initiated)

    View Slide

  197. Online resources
    • The documentation sites
    ‣ http://prototypejs.org to understand the code
    ‣ http://script.aculo.us to download and read
    the Wiki (massive overhaul initiated)
    • The official list
    ‣ http://groups.google.com/rubyonrails-spinoffs

    View Slide

  198. Online resources
    • The documentation sites
    ‣ http://prototypejs.org to understand the code
    ‣ http://script.aculo.us to download and read
    the Wiki (massive overhaul initiated)
    • The official list
    ‣ http://groups.google.com/rubyonrails-spinoffs
    • IRC
    ‣ #scriptaculous on Freenode

    View Slide

  199. Shameless plug

    View Slide

  200. Shameless plug

    View Slide

  201. Shameless plug
    • “The Bungee Book”

    View Slide

  202. Shameless plug
    • “The Bungee Book”
    • Available already (as beta) from
    the Pragmatic Bookshelf
    ‣ http://books.pragprog.com/titles/cppsu/

    View Slide

  203. Shameless plug
    • “The Bungee Book”
    • Available already (as beta) from
    the Pragmatic Bookshelf
    ‣ http://books.pragprog.com/titles/cppsu/
    • 95% content-complete already

    View Slide

  204. Shameless plug
    • “The Bungee Book”
    • Available already (as beta) from
    the Pragmatic Bookshelf
    ‣ http://books.pragprog.com/titles/cppsu/
    • 95% content-complete already
    • Up-to-date on the latest stuff

    View Slide

  205. Shameless plug
    • “The Bungee Book”
    • Available already (as beta) from
    the Pragmatic Bookshelf
    ‣ http://books.pragprog.com/titles/cppsu/
    • 95% content-complete already
    • Up-to-date on the latest stuff
    • Pre-order the paper book too!

    View Slide

  206. Q&A

    View Slide

  207. Q&A
    What Say You?

    View Slide