Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

This is an intro, yet...

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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.

Slide 7

Slide 7 text

Who am I?

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

What are we going to see?

Slide 15

Slide 15 text

What are we going to see? • Visual effects

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Visual effects

Slide 22

Slide 22 text

Overview

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Triggering an effect

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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.

Slide 33

Slide 33 text

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 });

Slide 34

Slide 34 text

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 });

Slide 35

Slide 35 text

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 });

Slide 36

Slide 36 text

Core effects

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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)

Slide 40

Slide 40 text

Core effects

Slide 41

Slide 41 text

Core effects • Highlight ‣ Cross-fading background color

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Generic options

Slide 45

Slide 45 text

Generic options • When to start ‣ delay, queue

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Core Effects demos

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

Combined effects

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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...

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

Drag and drop

Slide 56

Slide 56 text

Overview

Slide 57

Slide 57 text

Overview • Custom use / manual setup

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

Making stuff draggable

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

Dragging, my way.

Slide 67

Slide 67 text

Dragging, my way. • Reverting

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

Here’s your drop zone

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

Not letting anybody in

Slide 81

Slide 81 text

Not letting anybody in • Restricting on CSS class names

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

Drop demo • A shopping cart with a trash can

Slide 84

Slide 84 text

Re-ordering lists... with your mouse

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

It doesn’t have to be lists...

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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!

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

Re-ordering demos

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

Autocompletion

Slide 99

Slide 99 text

Overview

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

The basics

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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...

Slide 110

Slide 110 text

Dealing with rich contents

Slide 111

Slide 111 text

Dealing with rich contents • Often suggesting texts alone is insufficient

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

Multiple-field completion

Slide 115

Slide 115 text

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...

Slide 116

Slide 116 text

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...

Slide 117

Slide 117 text

Autocompletion demo

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

In-place editing

Slide 120

Slide 120 text

Overview

Slide 121

Slide 121 text

Overview • Makes any document fragment editable

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

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)

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

A simple editable fragment

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

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

Slide 131

Slide 131 text

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

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

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

Slide 134

Slide 134 text

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

Slide 135

Slide 135 text

Nips & tucks

Slide 136

Slide 136 text

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

Slide 137

Slide 137 text

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

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

Working with an alternate textual form

Slide 140

Slide 140 text

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

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

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

Slide 145

Slide 145 text

Using a dropdown list

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

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

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

In-place editing demos

Slide 150

Slide 150 text

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

Slide 151

Slide 151 text

Sliders

Slide 152

Slide 152 text

Sliders in 30” (re-enacted by rabbits)

Slide 153

Slide 153 text

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

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

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

Slide 156

Slide 156 text

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

Slide 157

Slide 157 text

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

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

Slider demos

Slide 161

Slide 161 text

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

Slide 162

Slide 162 text

Concise DOM building

Slide 163

Slide 163 text

Building DOM fragments “by hand” is booooring

Slide 164

Slide 164 text

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

Slide 165

Slide 165 text

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

Slide 166

Slide 166 text

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?

Slide 167

Slide 167 text

Builder.node

Slide 168

Slide 168 text

Builder.node Builder.node('p')

Slide 169

Slide 169 text

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

Slide 170

Slide 170 text

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

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

Slide 171

Slide 171 text

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

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

Slide 172

Slide 172 text

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

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

Builder.node('p', 'Hello world!')

Slide 173

Slide 173 text

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

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

Builder.node('p', 'Hello world!') //

Hello world!

Slide 174

Slide 174 text

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')

Slide 175

Slide 175 text

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!

Slide 176

Slide 176 text

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'])

Slide 177

Slide 177 text

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']) //

Intro

Hey

Slide 178

Slide 178 text

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']) //

Intro

Hey
Builder.node('div', { id: 'demo' }, ['Hey', Builder.node('h2', { className: 'regular' }, 'Intro')])

Slide 179

Slide 179 text

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']) //

Intro

Hey
Builder.node('div', { id: 'demo' }, ['Hey', Builder.node('h2', { className: 'regular' }, 'Intro')]) //
Hey

Intro

Slide 180

Slide 180 text

Builder.dump: shortcuts!

Slide 181

Slide 181 text

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

Slide 182

Slide 182 text

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

Slide 183

Slide 183 text

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

Slide 184

Slide 184 text

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

P({ id: 'demo', className: 'notice' })

Slide 185

Slide 185 text

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

P({ id: 'demo', className: 'notice' }) //

Slide 186

Slide 186 text

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

P({ id: 'demo', className: 'notice' }) //

P('Hello world!')

Slide 187

Slide 187 text

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

P({ id: 'demo', className: 'notice' }) //

P('Hello world!') //

Hello world!

Slide 188

Slide 188 text

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

P({ id: 'demo', className: 'notice' }) //

P('Hello world!') //

Hello world!

P({ id: 'demo' }, 'Hello world')

Slide 189

Slide 189 text

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

P({ id: 'demo', className: 'notice' }) //

P('Hello world!') //

Hello world!

P({ id: 'demo' }, 'Hello world') //

Hello world!

Slide 190

Slide 190 text

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'])

Slide 191

Slide 191 text

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']) //

Intro

Hey

Slide 192

Slide 192 text

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']) //

Intro

Hey
DIV({ id: 'demo' }, ['Hey', H2({ className: 'regular' }, 'Intro')])

Slide 193

Slide 193 text

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']) //

Intro

Hey
DIV({ id: 'demo' }, ['Hey', H2({ className: 'regular' }, 'Intro')]) //
Hey

Intro

Slide 194

Slide 194 text

Builder demo • Interactive Builder code execution

Slide 195

Slide 195 text

Online resources

Slide 196

Slide 196 text

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)

Slide 197

Slide 197 text

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

Slide 198

Slide 198 text

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

Slide 199

Slide 199 text

Shameless plug

Slide 200

Slide 200 text

Shameless plug

Slide 201

Slide 201 text

Shameless plug • “The Bungee Book”

Slide 202

Slide 202 text

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

Slide 203

Slide 203 text

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

Slide 204

Slide 204 text

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

Slide 205

Slide 205 text

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!

Slide 206

Slide 206 text

Q&A

Slide 207

Slide 207 text

Q&A What Say You?