Slide 1

Slide 1 text

Introduction to Prototype Christophe Porteneuve The Ajax Experience · San Francisco, July 25 2007

Slide 2

Slide 2 text

“Prototype,” uh?

Slide 3

Slide 3 text

“Prototype,” uh? • Open-source JS framework

Slide 4

Slide 4 text

“Prototype,” uh? • Open-source JS framework • Extracted from real apps, real needs

Slide 5

Slide 5 text

“Prototype,” uh? • Open-source JS framework • Extracted from real apps, real needs • Makes JS feel nicer (e.g. more expressive)

Slide 6

Slide 6 text

“Prototype,” uh? • Open-source JS framework • Extracted from real apps, real needs • Makes JS feel nicer (e.g. more expressive) • NOT widget-oriented. More of a core...

Slide 7

Slide 7 text

“Prototype,” uh? • Open-source JS framework • Extracted from real apps, real needs • Makes JS feel nicer (e.g. more expressive) • NOT widget-oriented. More of a core... • Actively maintained

Slide 8

Slide 8 text

“Prototype,” uh? • Open-source JS framework • Extracted from real apps, real needs • Makes JS feel nicer (e.g. more expressive) • NOT widget-oriented. More of a core... • Actively maintained • Excellent online documentation

Slide 9

Slide 9 text

“Porteneuve,” uh?

Slide 10

Slide 10 text

“Porteneuve,” uh? • 29, lives in Paris. Web work since 1995.

Slide 11

Slide 11 text

“Porteneuve,” uh? • 29, lives in Paris. Web work since 1995. • CTO @ Ciblo.net

Slide 12

Slide 12 text

“Porteneuve,” uh? • 29, lives in Paris. Web work since 1995. • CTO @ Ciblo.net • Prototype Core member

Slide 13

Slide 13 text

“Porteneuve,” uh? • 29, lives in Paris. Web work since 1995. • CTO @ Ciblo.net • Prototype Core member • Rails & script.aculo.us contributor

Slide 14

Slide 14 text

Prototype is people

Slide 15

Slide 15 text

Prototype is people

Slide 16

Slide 16 text

Prototype is people

Slide 17

Slide 17 text

So you said, “intro...”

Slide 18

Slide 18 text

So you said, “intro...” • We’ll take it easy: newbies, welcome!

Slide 19

Slide 19 text

So you said, “intro...” • We’ll take it easy: newbies, welcome! • There’s an advanced session anyway

Slide 20

Slide 20 text

So you said, “intro...” • We’ll take it easy: newbies, welcome! • There’s an advanced session anyway • What’s in this one?

Slide 21

Slide 21 text

So you said, “intro...” • We’ll take it easy: newbies, welcome! • There’s an advanced session anyway • What’s in this one? 1. These JS things you should know

Slide 22

Slide 22 text

So you said, “intro...” • We’ll take it easy: newbies, welcome! • There’s an advanced session anyway • What’s in this one? 1. These JS things you should know 2. How Prototype extends JavaScript...

Slide 23

Slide 23 text

So you said, “intro...” • We’ll take it easy: newbies, welcome! • There’s an advanced session anyway • What’s in this one? 1. These JS things you should know 2. How Prototype extends JavaScript... 3. How it puts the DOM on steroids...

Slide 24

Slide 24 text

So you said, “intro...” • We’ll take it easy: newbies, welcome! • There’s an advanced session anyway • What’s in this one? 1. These JS things you should know 2. How Prototype extends JavaScript... 3. How it puts the DOM on steroids... 4. And how it makes AJAX a snap!

Slide 25

Slide 25 text

JavaScript stuff you’d better know

Slide 26

Slide 26 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' };

Slide 27

Slide 27 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; person['name'] // 'Christophe'

Slide 28

Slide 28 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; person['name'] // 'Christophe' person['name'] = 'Mislav';

Slide 29

Slide 29 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; person['name'] // 'Christophe' person['name'] = 'Mislav'; person['name'] // 'Mislav'

Slide 30

Slide 30 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; person['name'] // 'Christophe' person['name'] = 'Mislav'; person['name'] // 'Mislav' person.name // 'Mislav'

Slide 31

Slide 31 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; person['name'] // 'Christophe' person['name'] = 'Mislav'; person['name'] // 'Mislav' person.name // 'Mislav' person.name = 'Tobie';

Slide 32

Slide 32 text

Everything is an object var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; person['name'] // 'Christophe' person['name'] = 'Mislav'; person['name'] // 'Mislav' person.name // 'Mislav' person.name = 'Tobie'; person.name // 'Tobie'

Slide 33

Slide 33 text

Arrays are not associative

Slide 34

Slide 34 text

Arrays are not associative var data = ['mark', 'john', 'susie'];

Slide 35

Slide 35 text

Arrays are not associative var data = ['mark', 'john', 'susie']; for (var name in data) alert(name);

Slide 36

Slide 36 text

Arrays are not associative • for...in iterates over all the properties! var data = ['mark', 'john', 'susie']; for (var name in data) alert(name); ✘

Slide 37

Slide 37 text

Arrays are not associative • for...in iterates over all the properties! ‣ Includes all of Prototype’s extensions! var data = ['mark', 'john', 'susie']; for (var name in data) alert(name); ✘

Slide 38

Slide 38 text

Arrays are not associative • for...in iterates over all the properties! ‣ Includes all of Prototype’s extensions! var data = ['mark', 'john', 'susie']; for (var name in data) alert(name); ✘ var data = ['mark', 'john', 'susie'];

Slide 39

Slide 39 text

Arrays are not associative • for...in iterates over all the properties! ‣ Includes all of Prototype’s extensions! var data = ['mark', 'john', 'susie']; for (var name in data) alert(name); ✘ var data = ['mark', 'john', 'susie']; for (var index = 0, l = data.length; index < l; ++index) alert(data[index]);

Slide 40

Slide 40 text

Arrays are not associative • for...in iterates over all the properties! ‣ Includes all of Prototype’s extensions! var data = ['mark', 'john', 'susie']; for (var name in data) alert(name); ✘ var data = ['mark', 'john', 'susie']; for (var index = 0, l = data.length; index < l; ++index) alert(data[index]); data.each(alert);

Slide 41

Slide 41 text

Functions are objects, too. var personToString = function(person) { return person.name + ', ' + person.age + ' (' + person.location + ')'; } They’re values like any other:

Slide 42

Slide 42 text

Functions are objects, too. var personToString = function(person) { return person.name + ', ' + person.age + ' (' + person.location + ')'; } var speaker = { name: 'Christophe', age: 29, location: 'Paris' }; speaker.toString = function() { return this.name + ', ' + this.age + ' (' + this.location + ')'; }; They’re values like any other: Same goes for methods:

Slide 43

Slide 43 text

Functions as constructors function Person(name, age, location) { this.name = name; this.age = age; this.location = location; this.toString = function() { /*...*/ } } Just initialize your fields using this:

Slide 44

Slide 44 text

Functions as constructors function Person(name, age, location) { this.name = name; this.age = age; this.location = location; this.toString = function() { /*...*/ } } var speaker = new Person('Christophe', 29, 'Paris'); speaker.name // 'Christophe' speaker.toString() // 'Christophe, 29 (Paris)' Just initialize your fields using this: And invoke using new:

Slide 45

Slide 45 text

The prototype property

Slide 46

Slide 46 text

The prototype property • this.method = ... quickly get tedious

Slide 47

Slide 47 text

The prototype property • this.method = ... quickly get tedious ‣ The constructors get overweight

Slide 48

Slide 48 text

The prototype property • this.method = ... quickly get tedious ‣ The constructors get overweight ‣ It’s all actually singleton methods!

Slide 49

Slide 49 text

The prototype property • this.method = ... quickly get tedious ‣ The constructors get overweight ‣ It’s all actually singleton methods! ‣ Save it for private/privileged methods

Slide 50

Slide 50 text

The prototype property • this.method = ... quickly get tedious ‣ The constructors get overweight ‣ It’s all actually singleton methods! ‣ Save it for private/privileged methods • prototype: all instances rely on it

Slide 51

Slide 51 text

The prototype property • this.method = ... quickly get tedious ‣ The constructors get overweight ‣ It’s all actually singleton methods! ‣ Save it for private/privileged methods • prototype: all instances rely on it ‣ Dynamic lookup: not just later instantiations!

Slide 52

Slide 52 text

The prototype property • this.method = ... quickly get tedious ‣ The constructors get overweight ‣ It’s all actually singleton methods! ‣ Save it for private/privileged methods • prototype: all instances rely on it ‣ Dynamic lookup: not just later instantiations! ‣ The class’ repository of public methods

Slide 53

Slide 53 text

The prototype property

Slide 54

Slide 54 text

The prototype property function Person(name, age, location) { ... }

Slide 55

Slide 55 text

The prototype property function Person(name, age, location) { ... } var sam = new Person('Sam', 23, 'Chicago');

Slide 56

Slide 56 text

The prototype property function Person(name, age, location) { ... } var sam = new Person('Sam', 23, 'Chicago'); Person.prototype.toString = function() { return this.name + ', ' + this.age + ' (' + this.location + ')'; }

Slide 57

Slide 57 text

The prototype property function Person(name, age, location) { ... } var sam = new Person('Sam', 23, 'Chicago'); Person.prototype.toString = function() { return this.name + ', ' + this.age + ' (' + this.location + ')'; } var tdd = new Person('Christophe', 29, 'Paris');

Slide 58

Slide 58 text

The prototype property function Person(name, age, location) { ... } var sam = new Person('Sam', 23, 'Chicago'); Person.prototype.toString = function() { return this.name + ', ' + this.age + ' (' + this.location + ')'; } var tdd = new Person('Christophe', 29, 'Paris'); tdd.toString() // 'Christophe, 29 (Paris)'

Slide 59

Slide 59 text

The prototype property function Person(name, age, location) { ... } var sam = new Person('Sam', 23, 'Chicago'); Person.prototype.toString = function() { return this.name + ', ' + this.age + ' (' + this.location + ')'; } var tdd = new Person('Christophe', 29, 'Paris'); tdd.toString() // 'Christophe, 29 (Paris)' sam.toString() // 'Sam, 23 (Chicago)'

Slide 60

Slide 60 text

Extending JavaScript

Slide 61

Slide 61 text

What could be improved?

Slide 62

Slide 62 text

What could be improved? • So much stuff (no offense, Brendan!)

Slide 63

Slide 63 text

What could be improved? • So much stuff (no offense, Brendan!) • Arrays, collections in general, iterators...

Slide 64

Slide 64 text

What could be improved? • So much stuff (no offense, Brendan!) • Arrays, collections in general, iterators... • Closures

Slide 65

Slide 65 text

What could be improved? • So much stuff (no offense, Brendan!) • Arrays, collections in general, iterators... • Closures • Comprehensions

Slide 66

Slide 66 text

What could be improved? • So much stuff (no offense, Brendan!) • Arrays, collections in general, iterators... • Closures • Comprehensions • Dynamic “inheritance,” method overriding

Slide 67

Slide 67 text

What could be improved? • So much stuff (no offense, Brendan!) • Arrays, collections in general, iterators... • Closures • Comprehensions • Dynamic “inheritance,” method overriding • ...and more!

Slide 68

Slide 68 text

What do we improve?

Slide 69

Slide 69 text

What do we improve? • We beef up the basics: Array, String, Number, Function...

Slide 70

Slide 70 text

What do we improve? • We beef up the basics: Array, String, Number, Function... • We unify event handling

Slide 71

Slide 71 text

What do we improve? • We beef up the basics: Array, String, Number, Function... • We unify event handling • Sure, JS 1.7-2.0 introduce a ton of cool

Slide 72

Slide 72 text

What do we improve? • We beef up the basics: Array, String, Number, Function... • We unify event handling • Sure, JS 1.7-2.0 introduce a ton of cool ‣ We try not to trump native stuff...

Slide 73

Slide 73 text

What do we improve? • We beef up the basics: Array, String, Number, Function... • We unify event handling • Sure, JS 1.7-2.0 introduce a ton of cool ‣ We try not to trump native stuff... ‣ ...but not everybody has Firefox 3!

Slide 74

Slide 74 text

What do we improve? • We beef up the basics: Array, String, Number, Function... • We unify event handling • Sure, JS 1.7-2.0 introduce a ton of cool ‣ We try not to trump native stuff... ‣ ...but not everybody has Firefox 3! ‣ ...and the syntax doesn’t always honor POLS ;)

Slide 75

Slide 75 text

Stretching your Strings

Slide 76

Slide 76 text

Stretching your Strings // 29 new methods. Here are just a few...

Slide 77

Slide 77 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true

Slide 78

Slide 78 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false

Slide 79

Slide 79 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true

Slide 80

Slide 80 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true 'Ho! '.times(3).strip() // 'Ho! Ho! Ho!'

Slide 81

Slide 81 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true 'Ho! '.times(3).strip() // 'Ho! Ho! Ho!' 'x > 0 && x < 100'.escapeHTML() // 'x > 0 && x < 100'

Slide 82

Slide 82 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true 'Ho! '.times(3).strip() // 'Ho! Ho! Ho!' 'x > 0 && x < 100'.escapeHTML() // 'x > 0 && x < 100' 'Extending JavaScript'.gsub(/([aeiouy])([^aeiouy]{2})/i, '#{2}#{1}')

Slide 83

Slide 83 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true 'Ho! '.times(3).strip() // 'Ho! Ho! Ho!' 'x > 0 && x < 100'.escapeHTML() // 'x > 0 && x < 100' 'Extending JavaScript'.gsub(/([aeiouy])([^aeiouy]{2})/i, '#{2}#{1}') // 'xtEndengi JavScarpti'

Slide 84

Slide 84 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true 'Ho! '.times(3).strip() // 'Ho! Ho! Ho!' 'x > 0 && x < 100'.escapeHTML() // 'x > 0 && x < 100' 'Extending JavaScript'.gsub(/([aeiouy])([^aeiouy]{2})/i, '#{2}#{1}') // 'xtEndengi JavScarpti' 'the ajax experience'.gsub(/\w+/, function(match) { return match[0].capitalize(); })

Slide 85

Slide 85 text

Stretching your Strings // 29 new methods. Here are just a few... 'Prototype'.include('to') // true 'Prototype'.startsWith('Active') // false 'Prototype'.endsWith('type') // true 'Ho! '.times(3).strip() // 'Ho! Ho! Ho!' 'x > 0 && x < 100'.escapeHTML() // 'x > 0 && x < 100' 'Extending JavaScript'.gsub(/([aeiouy])([^aeiouy]{2})/i, '#{2}#{1}') // 'xtEndengi JavScarpti' 'the ajax experience'.gsub(/\w+/, function(match) { return match[0].capitalize(); }) // 'The Ajax Experience'

Slide 86

Slide 86 text

Arrays as über-collections

Slide 87

Slide 87 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)...

Slide 88

Slide 88 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3

Slide 89

Slide 89 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6

Slide 90

Slide 90 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1

Slide 91

Slide 91 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5]

Slide 92

Slide 92 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5] [1, null, , 2, null, 3].compact() // [1, 2, 3]

Slide 93

Slide 93 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5] [1, null, , 2, null, 3].compact() // [1, 2, 3] [1, 2, 3, 2, 1].without(1) // [2, 3, 2]

Slide 94

Slide 94 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5] [1, null, , 2, null, 3].compact() // [1, 2, 3] [1, 2, 3, 2, 1].without(1) // [2, 3, 2] [1, 2, 3, 3, 4, 2, 5].uniq() // [1, 2, 3, 4, 5]

Slide 95

Slide 95 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5] [1, null, , 2, null, 3].compact() // [1, 2, 3] [1, 2, 3, 2, 1].without(1) // [2, 3, 2] [1, 2, 3, 3, 4, 2, 5].uniq() // [1, 2, 3, 4, 5] function greet() { return 'Hey ' + $A(arguments).first() + '!'; }

Slide 96

Slide 96 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5] [1, null, , 2, null, 3].compact() // [1, 2, 3] [1, 2, 3, 2, 1].without(1) // [2, 3, 2] [1, 2, 3, 3, 4, 2, 5].uniq() // [1, 2, 3, 4, 5] function greet() { return 'Hey ' + $A(arguments).first() + '!'; } greet('Sam', 'Thomas', 'John') // 'Hey Sam!'

Slide 97

Slide 97 text

Arrays as über-collections // 34 new methods, 19 of which from Enumerable (4 slides away)... [1, 2, 3].first() // 3 [4, 5, 6].last() // 6 [7, 8, 9].indexOf(8) // 1 [1, [2, 3], [4, [5], []]].flatten() // [1, 2, 3, 4, 5] [1, null, , 2, null, 3].compact() // [1, 2, 3] [1, 2, 3, 2, 1].without(1) // [2, 3, 2] [1, 2, 3, 3, 4, 2, 5].uniq() // [1, 2, 3, 4, 5] function greet() { return 'Hey ' + $A(arguments).first() + '!'; } greet('Sam', 'Thomas', 'John') // 'Hey Sam!' $w('eenie meenie minie moe') // ['eenie', 'meenie', 'minie', 'moe']

Slide 98

Slide 98 text

Numbers, the Ruby way

Slide 99

Slide 99 text

Numbers, the Ruby way (5).times(function() { // Processed 5 times })

Slide 100

Slide 100 text

Numbers, the Ruby way (5).times(function() { // Processed 5 times }) 'hello world!'.length.toPaddedString(3, 16) // '00c'

Slide 101

Slide 101 text

Numbers, the Ruby way (5).times(function() { // Processed 5 times }) 'hello world!'.length.toPaddedString(3, 16) // '00c' (221).toColorPart() // 'dd' (2-digit hex)

Slide 102

Slide 102 text

Numbers, the Ruby way (5).times(function() { // Processed 5 times }) 'hello world!'.length.toPaddedString(3, 16) // '00c' (221).toColorPart() // 'dd' (2-digit hex) Math.PI.ceil() // 4

Slide 103

Slide 103 text

Numbers, the Ruby way (5).times(function() { // Processed 5 times }) 'hello world!'.length.toPaddedString(3, 16) // '00c' (221).toColorPart() // 'dd' (2-digit hex) Math.PI.ceil() // 4 (3 - 2 * 4).abs() // 5

Slide 104

Slide 104 text

A few Function tricks

Slide 105

Slide 105 text

A few Function tricks function add(x, y) { return x + y; }

Slide 106

Slide 106 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; }

Slide 107

Slide 107 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4);

Slide 108

Slide 108 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5);

Slide 109

Slide 109 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5); add4(3) // 7

Slide 110

Slide 110 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5); add4(3) // 7 mul5(3) // 15

Slide 111

Slide 111 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5); add4(3) // 7 mul5(3) // 15 function greet(name) { alert('Hey ' + name + '!'); }

Slide 112

Slide 112 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5); add4(3) // 7 mul5(3) // 15 function greet(name) { alert('Hey ' + name + '!'); } greet.delay(1, 'Mark'); // will greet a second later

Slide 113

Slide 113 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5); add4(3) // 7 mul5(3) // 15 function greet(name) { alert('Hey ' + name + '!'); } greet.delay(1, 'Mark'); // will greet a second later updateDOMContents();

Slide 114

Slide 114 text

A few Function tricks function add(x, y) { return x + y; } function mul(x, y) { return x * y; } var add4 = add.curry(4); var mul5 = mul.curry(5); add4(3) // 7 mul5(3) // 15 function greet(name) { alert('Hey ' + name + '!'); } greet.delay(1, 'Mark'); // will greet a second later updateDOMContents(); rebindListeners.defer(); // give a tiny moment to breathe, then go!

Slide 115

Slide 115 text

New stuff you’ll love

Slide 116

Slide 116 text

Enumerable

Slide 117

Slide 117 text

Enumerable Mix it in your type and define _each:

Slide 118

Slide 118 text

Enumerable Object.extend(Array.prototype, Enumerable); Array.prototype._each = function(iterator) { for (var i = 0; i < this.length; i++) iterator(this[i]); }; Mix it in your type and define _each:

Slide 119

Slide 119 text

Enumerable Object.extend(Array.prototype, Enumerable); Array.prototype._each = function(iterator) { for (var i = 0; i < this.length; i++) iterator(this[i]); }; Mix it in your type and define _each: That’s it! Let’s start with iterations:

Slide 120

Slide 120 text

Enumerable Object.extend(Array.prototype, Enumerable); Array.prototype._each = function(iterator) { for (var i = 0; i < this.length; i++) iterator(this[i]); }; Mix it in your type and define _each: That’s it! Let’s start with iterations: var tae = $w('The Ajax Experience');

Slide 121

Slide 121 text

Enumerable Object.extend(Array.prototype, Enumerable); Array.prototype._each = function(iterator) { for (var i = 0; i < this.length; i++) iterator(this[i]); }; Mix it in your type and define _each: That’s it! Let’s start with iterations: var tae = $w('The Ajax Experience'); tae.each(alert);

Slide 122

Slide 122 text

Enumerable Object.extend(Array.prototype, Enumerable); Array.prototype._each = function(iterator) { for (var i = 0; i < this.length; i++) iterator(this[i]); }; Mix it in your type and define _each: That’s it! Let’s start with iterations: var tae = $w('The Ajax Experience'); tae.each(alert); tae.each(function(word, index) { alert(index + ': ' + word); })

Slide 123

Slide 123 text

Enumerable Object.extend(Array.prototype, Enumerable); Array.prototype._each = function(iterator) { for (var i = 0; i < this.length; i++) iterator(this[i]); }; Mix it in your type and define _each: That’s it! Let’s start with iterations: var tae = $w('The Ajax Experience'); tae.each(alert); tae.each(function(word, index) { alert(index + ': ' + word); }) tae.each(function(word, index) { if (index > 1) throw $break; alert(word); });

Slide 124

Slide 124 text

Enumerable (continued)

Slide 125

Slide 125 text

Enumerable (continued) var tae = $w('The Ajax Experience');

Slide 126

Slide 126 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E']

Slide 127

Slide 127 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10]

Slide 128

Slide 128 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10]

Slide 129

Slide 129 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E']

Slide 130

Slide 130 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E'] tae.invoke('gsub', /[aeiouy]+/i, '') // ['Th', 'jx', 'xprnc']

Slide 131

Slide 131 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E'] tae.invoke('gsub', /[aeiouy]+/i, '') // ['Th', 'jx', 'xprnc'] tae.max(function(w) { return w.length; }) // 10

Slide 132

Slide 132 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E'] tae.invoke('gsub', /[aeiouy]+/i, '') // ['Th', 'jx', 'xprnc'] tae.max(function(w) { return w.length; }) // 10 tae.zip(tae.pluck('length')).invoke('reverse')

Slide 133

Slide 133 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E'] tae.invoke('gsub', /[aeiouy]+/i, '') // ['Th', 'jx', 'xprnc'] tae.max(function(w) { return w.length; }) // 10 tae.zip(tae.pluck('length')).invoke('reverse') // [[3, 'The'], [4, 'Ajax'], [10, 'Experience']]

Slide 134

Slide 134 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E'] tae.invoke('gsub', /[aeiouy]+/i, '') // ['Th', 'jx', 'xprnc'] tae.max(function(w) { return w.length; }) // 10 tae.zip(tae.pluck('length')).invoke('reverse') // [[3, 'The'], [4, 'Ajax'], [10, 'Experience']] tae.inject('', function(acc, s) { return acc + s[0]; })

Slide 135

Slide 135 text

Enumerable (continued) var tae = $w('The Ajax Experience'); tae.map(function(word) { return word[0]; }) // ['T', 'A', 'E'] tae.map(function(word) { return word.length; }) // [3, 4, 10] tae.pluck('length') // [3, 4, 10] tae.pluck(0) // ['T', 'A', 'E'] tae.invoke('gsub', /[aeiouy]+/i, '') // ['Th', 'jx', 'xprnc'] tae.max(function(w) { return w.length; }) // 10 tae.zip(tae.pluck('length')).invoke('reverse') // [[3, 'The'], [4, 'Ajax'], [10, 'Experience']] tae.inject('', function(acc, s) { return acc + s[0]; }) // 'TAE'

Slide 136

Slide 136 text

Text interpolation

Slide 137

Slide 137 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}');

Slide 138

Slide 138 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' })

Slide 139

Slide 139 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' }) // 'Christophe is 29 and lives in Paris'

Slide 140

Slide 140 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' }) // 'Christophe is 29 and lives in Paris' var mislav = { name: 'Mislav', age: 23, location: 'Zagreb' };

Slide 141

Slide 141 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' }) // 'Christophe is 29 and lives in Paris' var mislav = { name: 'Mislav', age: 23, location: 'Zagreb' }; tpl.evaluate(mislav)

Slide 142

Slide 142 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' }) // 'Christophe is 29 and lives in Paris' var mislav = { name: 'Mislav', age: 23, location: 'Zagreb' }; tpl.evaluate(mislav) // 'Mislav is 23 and lives in Zagreb'

Slide 143

Slide 143 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' }) // 'Christophe is 29 and lives in Paris' var mislav = { name: 'Mislav', age: 23, location: 'Zagreb' }; tpl.evaluate(mislav) // 'Mislav is 23 and lives in Zagreb' // Pending commit to trunk: '#{name} is #{age} and lives in #{location}'.interpolate(mislav)

Slide 144

Slide 144 text

Text interpolation var tpl = new Template( '#{name} is #{age} and lives in #{location}'); tpl.evaluate({ name: 'Christophe', age: 29, location: 'Paris' }) // 'Christophe is 29 and lives in Paris' var mislav = { name: 'Mislav', age: 23, location: 'Zagreb' }; tpl.evaluate(mislav) // 'Mislav is 23 and lives in Zagreb' // Pending commit to trunk: '#{name} is #{age} and lives in #{location}'.interpolate(mislav) // 'Mislav is 23 and lives in Zagreb'

Slide 145

Slide 145 text

Ranges

Slide 146

Slide 146 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Slide 147

Slide 147 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Slide 148

Slide 148 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $R(1, 15).inject(0, function(acc, n) { return acc + n; })

Slide 149

Slide 149 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $R(1, 15).inject(0, function(acc, n) { return acc + n; }) // 120

Slide 150

Slide 150 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $R(1, 15).inject(0, function(acc, n) { return acc + n; }) // 120 $A($R('a', 'm'))

Slide 151

Slide 151 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $R(1, 15).inject(0, function(acc, n) { return acc + n; }) // 120 $A($R('a', 'm')) // ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm']

Slide 152

Slide 152 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $R(1, 15).inject(0, function(acc, n) { return acc + n; }) // 120 $A($R('a', 'm')) // ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'] $R(1, 5, true).map(function(n) { return '*'.times(n); })

Slide 153

Slide 153 text

Ranges new ObjectRange(1, 10).toArray() // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $A($R(1, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $R(1, 15).inject(0, function(acc, n) { return acc + n; }) // 120 $A($R('a', 'm')) // ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'] $R(1, 5, true).map(function(n) { return '*'.times(n); }) // ['*', '**', '***', '****']

Slide 154

Slide 154 text

The DOM is fun again!

Slide 155

Slide 155 text

What’s not fun about it?

Slide 156

Slide 156 text

What’s not fun about it? • Is that a trick question?

Slide 157

Slide 157 text

What’s not fun about it? • Is that a trick question? ‣ Selecting elements for processing

Slide 158

Slide 158 text

What’s not fun about it? • Is that a trick question? ‣ Selecting elements for processing ‣ Traversing it (don’t you hate indent nodes?)

Slide 159

Slide 159 text

What’s not fun about it? • Is that a trick question? ‣ Selecting elements for processing ‣ Traversing it (don’t you hate indent nodes?) ‣ Performing common manipulations (e.g. class tweaking, visibility toggling)

Slide 160

Slide 160 text

What’s not fun about it? • Is that a trick question? ‣ Selecting elements for processing ‣ Traversing it (don’t you hate indent nodes?) ‣ Performing common manipulations (e.g. class tweaking, visibility toggling) ‣ Cross-browser incompatibilities (e.g. attribute reading/writing, style tweaking)

Slide 161

Slide 161 text

What’s not fun about it? • Is that a trick question? ‣ Selecting elements for processing ‣ Traversing it (don’t you hate indent nodes?) ‣ Performing common manipulations (e.g. class tweaking, visibility toggling) ‣ Cross-browser incompatibilities (e.g. attribute reading/writing, style tweaking) ‣ Content changes (update, replace, etc.)

Slide 162

Slide 162 text

W3C DOM Level 2 HTML HTMLDocument HTMLElement HTMLHtmlElement HTMLHeadElement HTMLLinkElement HTMLTitleElement HTMLMetaElement HTMLBaseElement HTMLIsIndexElement HTMLStyleElement HTMLBodyElement HTMLFormElement HTMLSelectElement HTMLOptGroupElement HTMLOptionElement HTMLInputElement HTMLTextAreaElement HTMLButtonElement HTMLLabelElement HTMLFieldSetElement HTMLLegendElement HTMLUListElement HTMLOListElement HTMLDListElement HTMLDirectoryElement HTMLMenuElement HTMLLIElement HTMLDivElement HTMLParagraphElement HTMLHeadingElement HTMLQuoteElement HTMLPreElement HTMLBRElement HTMLBaseFontElement HTMLFontElement HTMLHRElement HTMLModElement HTMLAnchorElement HTMLImageElement HTMLObjectElement HTMLParamElement HTMLAppletElement HTMLMapElement HTMLAreaElement HTMLScriptElement HTMLTableElement HTMLTableCaptionElement HTMLTableColElement HTMLTableSectionElement HTMLTableRowElement HTMLTableCellElement HTMLFrameSetElement HTMLFrameElement HTMLIFrameElement

Slide 163

Slide 163 text

W3C DOM Level 2 HTML HTMLDocument HTMLElement HTMLHtmlElement HTMLHeadElement HTMLLinkElement HTMLTitleElement HTMLMetaElement HTMLBaseElement HTMLIsIndexElement HTMLStyleElement HTMLBodyElement HTMLFormElement HTMLSelectElement HTMLOptGroupElement HTMLOptionElement HTMLInputElement HTMLTextAreaElement HTMLButtonElement HTMLLabelElement HTMLFieldSetElement HTMLLegendElement HTMLUListElement HTMLOListElement HTMLDListElement HTMLDirectoryElement HTMLMenuElement HTMLLIElement HTMLDivElement HTMLParagraphElement HTMLHeadingElement HTMLQuoteElement HTMLPreElement HTMLBRElement HTMLBaseFontElement HTMLFontElement HTMLHRElement HTMLModElement HTMLAnchorElement HTMLImageElement HTMLObjectElement HTMLParamElement HTMLAppletElement HTMLMapElement HTMLAreaElement HTMLScriptElement HTMLTableElement HTMLTableCaptionElement HTMLTableColElement HTMLTableSectionElement HTMLTableRowElement HTMLTableCellElement HTMLFrameSetElement HTMLFrameElement HTMLIFrameElement ✘ Yeah, right.

Slide 164

Slide 164 text

DOM-related prototypes HTMLElement. prototype HTML*Element. prototype

Slide 165

Slide 165 text

DOM-related prototypes HTMLElement. prototype HTML*Element. prototype ✕ ✕

Slide 166

Slide 166 text

DOM-related prototypes HTMLElement. prototype HTML*Element. prototype ✕ ✕ ✓ ✕

Slide 167

Slide 167 text

DOM-related prototypes HTMLElement. prototype HTML*Element. prototype ✕ ✕ ✓ ✕ ✓ ✓

Slide 168

Slide 168 text

DOM-related prototypes HTMLElement. prototype HTML*Element. prototype ✕ ✕ ✓ ✕ ✓ ✓ ✓ ✕

Slide 169

Slide 169 text

DOM-related prototypes HTMLElement. prototype HTML*Element. prototype ✕ ✕ ✓ ✕ ✓ ✓ ✓ ✕ ✓ ✓

Slide 170

Slide 170 text

Element extension

Slide 171

Slide 171 text

Element extension • Element.extend(yourElement)

Slide 172

Slide 172 text

Element extension • Element.extend(yourElement) ‣ Adds all of Element.Methods (~60 methods)

Slide 173

Slide 173 text

Element extension • Element.extend(yourElement) ‣ Adds all of Element.Methods (~60 methods) ‣ Take advantage of prototypes when available

Slide 174

Slide 174 text

Element extension • Element.extend(yourElement) ‣ Adds all of Element.Methods (~60 methods) ‣ Take advantage of prototypes when available ‣ Adds tag-specific extensions (e.g. form elements)

Slide 175

Slide 175 text

Element extension • Element.extend(yourElement) ‣ Adds all of Element.Methods (~60 methods) ‣ Take advantage of prototypes when available ‣ Adds tag-specific extensions (e.g. form elements) • Most of Prototype extends implicitly ‣ $, $$, all extended methods’ results

Slide 176

Slide 176 text

The famous $ function

Slide 177

Slide 177 text

The famous $ function • Most common need: grab an element by ID

Slide 178

Slide 178 text

The famous $ function • Most common need: grab an element by ID • Runner-ups:

Slide 179

Slide 179 text

The famous $ function • Most common need: grab an element by ID • Runner-ups: ‣ Grab many elements by their ID’s

Slide 180

Slide 180 text

The famous $ function • Most common need: grab an element by ID • Runner-ups: ‣ Grab many elements by their ID’s ‣ Make sure an element is equipped with Prototype’s DOM extensions

Slide 181

Slide 181 text

The famous $ function • Most common need: grab an element by ID • Runner-ups: ‣ Grab many elements by their ID’s ‣ Make sure an element is equipped with Prototype’s DOM extensions • Enter $(...)

Slide 182

Slide 182 text

The famous $ function

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 183

Slide 183 text

The famous $ function $('article1')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 184

Slide 184 text

The famous $ function $('article1') //

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 185

Slide 185 text

The famous $ function $('article1') //
$(firstDiv)

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 186

Slide 186 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 187

Slide 187 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions $('article1', 'foobar', 'comment101')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 188

Slide 188 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions $('article1', 'foobar', 'comment101') // [firstDiv, null, firstCommentDiv]

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 189

Slide 189 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions $('article1', 'foobar', 'comment101') // [firstDiv, null, firstCommentDiv] $('article1', 'foobar', 'comment101').compact()

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 190

Slide 190 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions $('article1', 'foobar', 'comment101') // [firstDiv, null, firstCommentDiv] $('article1', 'foobar', 'comment101').compact() // [firstDiv, firstCommentDiv]

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 191

Slide 191 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions $('article1', 'foobar', 'comment101') // [firstDiv, null, firstCommentDiv] $('article1', 'foobar', 'comment101').compact() // [firstDiv, firstCommentDiv] $(firstDiv, 'article1', firstCommentDiv).uniq()

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 192

Slide 192 text

The famous $ function $('article1') //
$(firstDiv) // firstDiv, with guaranteed extensions $('article1', 'foobar', 'comment101') // [firstDiv, null, firstCommentDiv] $('article1', 'foobar', 'comment101').compact() // [firstDiv, firstCommentDiv] $(firstDiv, 'article1', firstCommentDiv).uniq() // [firstDiv, firstCommentDiv]

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 193

Slide 193 text

$$ (The Almighty One)

Slide 194

Slide 194 text

$$ (The Almighty One) • Relies on CSS3 selectors

Slide 195

Slide 195 text

$$ (The Almighty One) • Relies on CSS3 selectors • Independent of your browser’s CSS3!

Slide 196

Slide 196 text

$$ (The Almighty One) • Relies on CSS3 selectors • Independent of your browser’s CSS3! • Super-fast with DOM3 XPath

Slide 197

Slide 197 text

$$ (The Almighty One) • Relies on CSS3 selectors • Independent of your browser’s CSS3! • Super-fast with DOM3 XPath • Very powerful attributes, classes, ID’s, hierarchy, position, tags/types, and more...

Slide 198

Slide 198 text

$$ (The Almighty One)

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 199

Slide 199 text

$$ (The Almighty One) $$('div')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 200

Slide 200 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 201

Slide 201 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 202

Slide 202 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 203

Slide 203 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments $$('h2 + p')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 204

Slide 204 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments $$('h2 + p') //

Blah blah

,

Yada yada yada

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 205

Slide 205 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments $$('h2 + p') //

Blah blah

,

Yada yada yada

$$('div.comments > div[id$="01"] > h3')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 206

Slide 206 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments $$('h2 + p') //

Blah blah

,

Yada yada yada

$$('div.comments > div[id$="01"] > h3') // h3, h3

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 207

Slide 207 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments $$('h2 + p') //

Blah blah

,

Yada yada yada

$$('div.comments > div[id$="01"] > h3') // h3, h3 $$('div:nth-child(2)')

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 208

Slide 208 text

$$ (The Almighty One) $$('div') // #article1, .comments, #comment101, // #article2, .comments, #comment201, // #comment202 $$('div.comments') // .comments, .comments $$('h2 + p') //

Blah blah

,

Yada yada yada

$$('div.comments > div[id$="01"] > h3') // h3, h3 $$('div:nth-child(2)') // #comment202

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 209

Slide 209 text

Traversing and aggregating

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 210

Slide 210 text

Traversing and aggregating $('article1').down() //

Speaking!

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 211

Slide 211 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 212

Slide 212 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 213

Slide 213 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 214

Slide 214 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1)

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 215

Slide 215 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 216

Slide 216 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

$('comment201').ancestors()

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 217

Slide 217 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

$('comment201').ancestors() // div.comments, #article2, body

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 218

Slide 218 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

$('comment201').ancestors() // div.comments, #article2, body $('article2').down().nextSiblings()

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 219

Slide 219 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

$('comment201').ancestors() // div.comments, #article2, body $('article2').down().nextSiblings() // p, div.comments

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 220

Slide 220 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

$('comment201').ancestors() // div.comments, #article2, body $('article2').down().nextSiblings() // p, div.comments $('article2').down('p').siblings()

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 221

Slide 221 text

Traversing and aggregating $('article1').down() //

Speaking!

$('comment101').up() // div.comments $('comment202').previous() // #comment201 $('article1').next().down(1) // div.comments $('article2').down('h3', 1) //

John @ 09:37am

$('comment201').ancestors() // div.comments, #article2, body $('article2').down().nextSiblings() // p, div.comments $('article2').down('p').siblings() // h2, div.comments

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 222

Slide 222 text

Playing with visibility

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 223

Slide 223 text

Playing with visibility var hdr2 = $('article1').down('h2');

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 224

Slide 224 text

Playing with visibility var hdr2 = $('article1').down('h2'); hdr2.visible() // true

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 225

Slide 225 text

Playing with visibility var hdr2 = $('article1').down('h2'); hdr2.visible() // true hdr2.hide() //

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 226

Slide 226 text

Playing with visibility var hdr2 = $('article1').down('h2'); hdr2.visible() // true hdr2.hide() //

hdr2.visible() // false

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 227

Slide 227 text

Playing with visibility var hdr2 = $('article1').down('h2'); hdr2.visible() // true hdr2.hide() //

hdr2.visible() // false hdr2.toggle() //

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 228

Slide 228 text

Playing with attributes ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 229

Slide 229 text

Playing with attributes var box = $('chkTOS'); // ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 230

Slide 230 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 231

Slide 231 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 232

Slide 232 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null box.writeAttribute('checked', true); ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 233

Slide 233 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null box.writeAttribute('checked', true); // ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 234

Slide 234 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null box.writeAttribute('checked', true); // box.readAttribute('checked') ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 235

Slide 235 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null box.writeAttribute('checked', true); // box.readAttribute('checked') // 'checked' ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 236

Slide 236 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null box.writeAttribute('checked', true); // box.readAttribute('checked') // 'checked' box.writeAttribute('checked', false) ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 237

Slide 237 text

Playing with attributes var box = $('chkTOS'); // box.readAttribute('checked') // null box.writeAttribute('checked', true); // box.readAttribute('checked') // 'checked' box.writeAttribute('checked', false) // ...

I agree, wholeheartedly, to your wonderful terms of service. Love.

...

Slide 238

Slide 238 text

Playing with style h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 239

Slide 239 text

Playing with style var hdr = $('article1').down('h2'); h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 240

Slide 240 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 241

Slide 241 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 242

Slide 242 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' hdr.setStyle({ 'font-size': '1.5em' }) h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 243

Slide 243 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' hdr.setStyle({ 'font-size': '1.5em' }) //

h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 244

Slide 244 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' hdr.setStyle({ 'font-size': '1.5em' }) //

hdr.setStyle({ fontSize: '1.5em', true }) h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 245

Slide 245 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' hdr.setStyle({ 'font-size': '1.5em' }) //

hdr.setStyle({ fontSize: '1.5em', true }) // Same, but slightly faster... h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 246

Slide 246 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' hdr.setStyle({ 'font-size': '1.5em' }) //

hdr.setStyle({ fontSize: '1.5em', true }) // Same, but slightly faster... hdr.setStyle({ fontSize: null, color: 'red' }) h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 247

Slide 247 text

Playing with style var hdr = $('article1').down('h2'); hdr.getStyle('font-size'); // '1.2em' hdr.setStyle({ 'font-size': '1.5em' }) //

hdr.setStyle({ fontSize: '1.5em', true }) // Same, but slightly faster... hdr.setStyle({ fontSize: null, color: 'red' }) //

h2 { font-size: 1.2em; }

Speaking!

Blah blah

Slide 248

Slide 248 text

Dynamic contents! var hdr = $('article1').down('h2'); hdr.update('TAE!');

Speaking!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 249

Slide 249 text

Dynamic contents! var hdr = $('article1').down('h2'); hdr.update('TAE!');

TAE!

Blah blah

John @ 12:35pm

yikes!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 250

Slide 250 text

Dynamic contents! var c1 = $('comment101'); c1.insert('

Yuck indeed!

');

TAE!

Blah blah

John @ 12:35pm

yikes!

Yuck indeed!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

...

Slide 251

Slide 251 text

Dynamic contents! var c1 = $('comment101'); c1.insert('

Yuck indeed!

'); c1.insert({ top: '

er, well...

' });

TAE!

Blah blah

er, well...

John @ 12:35pm

yikes!

Yuck indeed!

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

...

Slide 252

Slide 252 text

Dynamic contents! var c1 = $('comment101'); c1.insert('

Yuck indeed!

'); c1.insert({ top: '

er, well...

' }); c1.insert({ before: 'BEFORE', after: 'AFTER' });

TAE!

Blah blah

BEFORE

er, well...

John @ 12:35pm

yikes!

Yuck indeed!

AFTER

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

...

Slide 253

Slide 253 text

Dynamic contents! var c1 = $('comment101'); c1.insert('

Yuck indeed!

'); c1.insert({ top: '

er, well...

' }); c1.insert({ before: 'BEFORE', after: 'AFTER' }); c1.replace('

--DELETED--

');

TAE!

Blah blah

BEFORE

--DELETED--

AFTER

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

Slide 254

Slide 254 text

Explicit element creation var warning = new Element('img', { id: 'warning', src: '/i/warn.png', title: 'Watch out!' }); $(document.body).insert({ top: warning });

TAE!

Blah blah

BEFORE

--DELETED--

AFTER

Guess what?

Yada yada yada

Mark @ 09:20am

cool!

John @ 09:37am

d'oh!

...

Slide 255

Slide 255 text

Event handling

Slide 256

Slide 256 text

The problems we face

Slide 257

Slide 257 text

The problems we face • People keep using events the DOM0 way

Slide 258

Slide 258 text

The problems we face • People keep using events the DOM0 way ‣ Inline handlers skip the event object in IE

Slide 259

Slide 259 text

The problems we face • People keep using events the DOM0 way ‣ Inline handlers skip the event object in IE • IE vs. The Rest Of The World

Slide 260

Slide 260 text

The problems we face • People keep using events the DOM0 way ‣ Inline handlers skip the event object in IE • IE vs. The Rest Of The World ‣ (De)registering event handlers

Slide 261

Slide 261 text

The problems we face • People keep using events the DOM0 way ‣ Inline handlers skip the event object in IE • IE vs. The Rest Of The World ‣ (De)registering event handlers ‣ Getting / manipulating the event object

Slide 262

Slide 262 text

The problems we face • People keep using events the DOM0 way ‣ Inline handlers skip the event object in IE • IE vs. The Rest Of The World ‣ (De)registering event handlers ‣ Getting / manipulating the event object ‣ Bubbling & capturing, key events, key codes...

Slide 263

Slide 263 text

The problems we face • People keep using events the DOM0 way ‣ Inline handlers skip the event object in IE • IE vs. The Rest Of The World ‣ (De)registering event handlers ‣ Getting / manipulating the event object ‣ Bubbling & capturing, key events, key codes... • Not just IE: Safari/Opera b0rk sometimes

Slide 264

Slide 264 text

Unifying the event code

Slide 265

Slide 265 text

Unifying the event code • (De)registering handlers ‣ Event.observe, Event.stopObserving

Slide 266

Slide 266 text

Unifying the event code • (De)registering handlers ‣ Event.observe, Event.stopObserving • Manipulating the event object ‣ Event.pointer(X|Y), Event.element, Event.stop, Event.KEY_xxx, etc.

Slide 267

Slide 267 text

Unifying the event code • (De)registering handlers ‣ Event.observe, Event.stopObserving • Manipulating the event object ‣ Event.pointer(X|Y), Event.element, Event.stop, Event.KEY_xxx, etc. • Working around the tweaks ‣ e.g. keypress/keydown in Safari, submit...

Slide 268

Slide 268 text

What it looks like function bindPopupLinks() { $$('a.popup').invoke('observe', 'click', handlePopupLinkClick); } function handlePopupLinkClick(e) { Event.stop(e); var lnk = Event.findElement(e, 'a'); var opts = 'width=500,height=400...'; window.open(lnk.href, 'wndPopupLink', opts); } // Prototype 1.6 should emulate DOMContentLoaded properly... Event.observe(window, 'DOMContentLoaded', bindPopupLinks);

Slide 269

Slide 269 text

What it looks like function bindPopupLinks() { $$('a.popup').invoke('observe', 'click', handlePopupLinkClick); } function handlePopupLinkClick(e) { Event.stop(e); var lnk = Event.findElement(e, 'a'); var opts = 'width=500,height=400...'; window.open(lnk.href, 'wndPopupLink', opts); } // Prototype 1.6 should emulate DOMContentLoaded properly... Event.observe(window, 'DOMContentLoaded', bindPopupLinks);

Slide 270

Slide 270 text

What it looks like function bindPopupLinks() { $$('a.popup').invoke('observe', 'click', handlePopupLinkClick); } function handlePopupLinkClick(e) { Event.stop(e); var lnk = Event.findElement(e, 'a'); var opts = 'width=500,height=400...'; window.open(lnk.href, 'wndPopupLink', opts); } // Prototype 1.6 should emulate DOMContentLoaded properly... Event.observe(window, 'DOMContentLoaded', bindPopupLinks);

Slide 271

Slide 271 text

What it looks like function bindPopupLinks() { $$('a.popup').invoke('observe', 'click', handlePopupLinkClick); } function handlePopupLinkClick(e) { Event.stop(e); var lnk = Event.findElement(e, 'a'); var opts = 'width=500,height=400...'; window.open(lnk.href, 'wndPopupLink', opts); } // Prototype 1.6 should emulate DOMContentLoaded properly... Event.observe(window, 'DOMContentLoaded', bindPopupLinks);

Slide 272

Slide 272 text

What it looks like function bindPopupLinks() { $$('a.popup').invoke('observe', 'click', handlePopupLinkClick); } function handlePopupLinkClick(e) { Event.stop(e); var lnk = Event.findElement(e, 'a'); var opts = 'width=500,height=400...'; window.open(lnk.href, 'wndPopupLink', opts); } // Prototype 1.6 should emulate DOMContentLoaded properly... Event.observe(window, 'DOMContentLoaded', bindPopupLinks);

Slide 273

Slide 273 text

Going AJAX

Slide 274

Slide 274 text

X = XML?

Slide 275

Slide 275 text

X = XML? • Yeah, but let’s just drop the XML garbage

Slide 276

Slide 276 text

X = XML? • Yeah, but let’s just drop the XML garbage ‣ What’s your cross to bear, SOAP with JS?

Slide 277

Slide 277 text

X = XML? • Yeah, but let’s just drop the XML garbage ‣ What’s your cross to bear, SOAP with JS? • X = XHTML

Slide 278

Slide 278 text

X = XML? • Yeah, but let’s just drop the XML garbage ‣ What’s your cross to bear, SOAP with JS? • X = XHTML ‣ I mean, we all send back XHTML anyway

Slide 279

Slide 279 text

X = XML? • Yeah, but let’s just drop the XML garbage ‣ What’s your cross to bear, SOAP with JS? • X = XHTML ‣ I mean, we all send back XHTML anyway ‣ Unless it’s JSON or plain JS to be eval’d

Slide 280

Slide 280 text

X = XML? • Yeah, but let’s just drop the XML garbage ‣ What’s your cross to bear, SOAP with JS? • X = XHTML ‣ I mean, we all send back XHTML anyway ‣ Unless it’s JSON or plain JS to be eval’d ‣ We’re all doing AHAH, knowing it or not!

Slide 281

Slide 281 text

Making an AJAX request

Slide 282

Slide 282 text

Making an AJAX request new Ajax.Request('/articles/1', { method: 'get', onComplete: function(xhr) { /* process xhr.responseText */ } });

Slide 283

Slide 283 text

Making an AJAX request new Ajax.Request('/articles/1', { method: 'get', onComplete: function(xhr) { /* process xhr.responseText */ } }); • Plenty of options!

Slide 284

Slide 284 text

Making an AJAX request new Ajax.Request('/articles/1', { method: 'get', onComplete: function(xhr) { /* process xhr.responseText */ } }); • Plenty of options! ‣ Method, callbacks, parameters, headers, encoding...

Slide 285

Slide 285 text

Making an AJAX request new Ajax.Request('/articles/1', { method: 'get', onComplete: function(xhr) { /* process xhr.responseText */ } }); • Plenty of options! ‣ Method, callbacks, parameters, headers, encoding... new Ajax.Request('/signin', { parameters: { login: 'john', password: 'foobar' }, requestHeaders: { 'X-Auth-Mode': 'XHR' }, onFailure: function(xhr) { alert(xhr.responseText); }, onComplete: function(xhr) { $('loginForm').update(xhr.responseText); } });

Slide 286

Slide 286 text

Returning pure JavaScript? Leave this to me. new Ajax.Request('/persist', { parameters: $('form').serialize() });

Slide 287

Slide 287 text

Returning pure JavaScript? Leave this to me. new Ajax.Request('/persist', { parameters: $('form').serialize() }); $('indicator').hide(); $('items').insert('
  • ...'); $('item5').highlight.defer(); ...
  • Slide 288

    Slide 288 text

    Returning pure JavaScript? Leave this to me. new Ajax.Request('/persist', { parameters: $('form').serialize() }); $('indicator').hide(); $('items').insert('
  • ...'); $('item5').highlight.defer(); ... eval(...)
  • Slide 289

    Slide 289 text

    Submitting forms

    Slide 290

    Slide 290 text

    Submitting forms • At the core of AJAXifying a page...

    Slide 291

    Slide 291 text

    Submitting forms • At the core of AJAXifying a page... ‣ Using the form’s method and action attributes

    Slide 292

    Slide 292 text

    Submitting forms • At the core of AJAXifying a page... ‣ Using the form’s method and action attributes ‣ Serializing it according to HTML spec

    Slide 293

    Slide 293 text

    Submitting forms • At the core of AJAXifying a page... ‣ Using the form’s method and action attributes ‣ Serializing it according to HTML spec ‣ Returning JS? You’re done! Otherwise use onComplete.

    Slide 294

    Slide 294 text

    Submitting forms • At the core of AJAXifying a page... ‣ Using the form’s method and action attributes ‣ Serializing it according to HTML spec ‣ Returning JS? You’re done! Otherwise use onComplete. • In phase with accessibility / unobstrusive JS

    Slide 295

    Slide 295 text

    Submitting forms

    Slide 296

    Slide 296 text

    Submitting forms • The HTML:

    Slide 297

    Slide 297 text

    Submitting forms • The HTML:

    Slide 298

    Slide 298 text

    Submitting forms • The HTML:

    • The JS:

    Slide 299

    Slide 299 text

    Submitting forms • The HTML:

    • The JS: var form = $('signinForm'); form.observe('submit', function(e) { Event.stop(e); form.request(); });

    Slide 300

    Slide 300 text

    AJAX returning markup

    Slide 301

    Slide 301 text

    AJAX returning markup • It’s everywhere!

    Slide 302

    Slide 302 text

    AJAX returning markup • It’s everywhere! ‣ Using the form’s method and action attributes

    Slide 303

    Slide 303 text

    AJAX returning markup • It’s everywhere! ‣ Using the form’s method and action attributes • In essence: container.update(xhr.responseText)

    Slide 304

    Slide 304 text

    AJAX returning markup • It’s everywhere! ‣ Using the form’s method and action attributes • In essence: container.update(xhr.responseText) • Automagically done!

    Slide 305

    Slide 305 text

    AJAX returning markup • It’s everywhere! ‣ Using the form’s method and action attributes • In essence: container.update(xhr.responseText) • Automagically done! ‣ Quite a few cool options (success/failure branching, inserting instead of updating, evaluation)

    Slide 306

    Slide 306 text

    AJAX returning markup • It’s everywhere! ‣ Using the form’s method and action attributes • In essence: container.update(xhr.responseText) • Automagically done! ‣ Quite a few cool options (success/failure branching, inserting instead of updating, evaluation) ‣ Can even be periodical (and slow down if no changes)

    Slide 307

    Slide 307 text

    AJAX returning markup

    Slide 308

    Slide 308 text

    AJAX returning markup new Ajax.Updater('container', '/url');

    Slide 309

    Slide 309 text

    AJAX returning markup new Ajax.Updater('container', '/url'); new Ajax.Updater('todo1', '/todos/1/items', { insertion: 'bottom', parameters: $('itemForm').serialize() });

    Slide 310

    Slide 310 text

    AJAX returning markup new Ajax.Updater('container', '/url'); new Ajax.Updater('todo1', '/todos/1/items', { insertion: 'bottom', parameters: $('itemForm').serialize() }); new Ajax.Updater('todo1', '/todos/1', { method: 'get', evalScripts: true, parameters: $('todoForm').serialize() });

    Slide 311

    Slide 311 text

    AJAX returning markup new Ajax.Updater('container', '/url'); new Ajax.Updater('todo1', '/todos/1/items', { insertion: 'bottom', parameters: $('itemForm').serialize() }); new Ajax.Updater('todo1', '/todos/1', { method: 'get', evalScripts: true, parameters: $('todoForm').serialize() }); new Ajax.Updater({ success: 'todo1', failure: 'errors' }, '/todos/1', { parameters: $('todoForm').serialize() });

    Slide 312

    Slide 312 text

    AJAX returning markup new Ajax.Updater('container', '/url'); new Ajax.Updater('todo1', '/todos/1/items', { insertion: 'bottom', parameters: $('itemForm').serialize() }); new Ajax.Updater('todo1', '/todos/1', { method: 'get', evalScripts: true, parameters: $('todoForm').serialize() }); new Ajax.Updater({ success: 'todo1', failure: 'errors' }, '/todos/1', { parameters: $('todoForm').serialize() }); new Ajax.Updater({ success: 'todo1' }, '/todos/1', { parameters: $('todoForm').serialize() });

    Slide 313

    Slide 313 text

    Progressive enhancement: “Hijax”

    Slide 314

    Slide 314 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be

    Slide 315

    Slide 315 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be ‣ semantical

    Slide 316

    Slide 316 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be ‣ semantical ‣ self-sufficient (works w/o JS)

    Slide 317

    Slide 317 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be ‣ semantical ‣ self-sufficient (works w/o JS) • The recipe is simple:

    Slide 318

    Slide 318 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be ‣ semantical ‣ self-sufficient (works w/o JS) • The recipe is simple: ‣ Plan for AJAX early (controllers/views, etc.)

    Slide 319

    Slide 319 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be ‣ semantical ‣ self-sufficient (works w/o JS) • The recipe is simple: ‣ Plan for AJAX early (controllers/views, etc.) ‣ Implement it when the page works already

    Slide 320

    Slide 320 text

    Progressive enhancement: “Hijax” • I’ll remind you that your markup should be ‣ semantical ‣ self-sufficient (works w/o JS) • The recipe is simple: ‣ Plan for AJAX early (controllers/views, etc.) ‣ Implement it when the page works already ‣ Use unobstrusive JavaScript

    Slide 321

    Slide 321 text

    But wait! There’s more!

    Slide 322

    Slide 322 text

    But wait! There’s more! • Next up: Advanced Prototype

    Slide 323

    Slide 323 text

    But wait! There’s more! • Next up: Advanced Prototype ‣ More Function-fu

    Slide 324

    Slide 324 text

    But wait! There’s more! • Next up: Advanced Prototype ‣ More Function-fu ‣ Best coding practices (e.g. on Enumerable)

    Slide 325

    Slide 325 text

    But wait! There’s more! • Next up: Advanced Prototype ‣ More Function-fu ‣ Best coding practices (e.g. on Enumerable) ‣ JSON love

    Slide 326

    Slide 326 text

    But wait! There’s more! • Next up: Advanced Prototype ‣ More Function-fu ‣ Best coding practices (e.g. on Enumerable) ‣ JSON love ‣ Whipping up your own DOM extensions

    Slide 327

    Slide 327 text

    But wait! There’s more! • Next up: Advanced Prototype ‣ More Function-fu ‣ Best coding practices (e.g. on Enumerable) ‣ JSON love ‣ Whipping up your own DOM extensions ‣ Creating your own classes

    Slide 328

    Slide 328 text

    But wait! There’s more! • Next up: Advanced Prototype ‣ More Function-fu ‣ Best coding practices (e.g. on Enumerable) ‣ JSON love ‣ Whipping up your own DOM extensions ‣ Creating your own classes ‣ Sneak peek at Prototype 1.6, and more!

    Slide 329

    Slide 329 text

    Online resources

    Slide 330

    Slide 330 text

    Online resources • The excellent documentation site ‣ http://prototypejs.org ‣ API reference, tutorials, downloads, blog... ‣ Soon: 3rd-party libs roster

    Slide 331

    Slide 331 text

    Online resources • The excellent documentation site ‣ http://prototypejs.org ‣ API reference, tutorials, downloads, blog... ‣ Soon: 3rd-party libs roster • The official list (does script.aculo.us too) ‣ http://groups.google.com/rubyonrails-spinoffs

    Slide 332

    Slide 332 text

    Online resources • The excellent documentation site ‣ http://prototypejs.org ‣ API reference, tutorials, downloads, blog... ‣ Soon: 3rd-party libs roster • The official list (does script.aculo.us too) ‣ http://groups.google.com/rubyonrails-spinoffs • IRC ‣ #prototype on Freenode

    Slide 333

    Slide 333 text

    Shameless plug

    Slide 334

    Slide 334 text

    Shameless plug

    Slide 335

    Slide 335 text

    Shameless plug • “The Bungee Book”

    Slide 336

    Slide 336 text

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

    Slide 337

    Slide 337 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 338

    Slide 338 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 339

    Slide 339 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 340

    Slide 340 text

    Q&A

    Slide 341

    Slide 341 text

    Q&A What Say You?