~smagoun/whoopsie/whoopsie-lp1017637

« back to all changes in this revision

Viewing changes to backend/stats/static/js/yui/docs/attribute/attribute-event.html

  • Committer: Evan Dandrea
  • Date: 2012-05-09 05:53:45 UTC
  • Revision ID: evan.dandrea@canonical.com-20120509055345-z2j41tmcbf4as5uf
The backend now lives in lp:daisy and the website (errors.ubuntu.com) now lives in lp:errors.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!DOCTYPE html>
2
 
<html lang="en">
3
 
<head>
4
 
    <meta charset="utf-8">
5
 
    <title>Example: Attribute Change Events</title>
6
 
    <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Maven+Pro:400,700">
7
 
    <link rel="stylesheet" href="../../build/cssgrids/grids-min.css">
8
 
    <link rel="stylesheet" href="../assets/css/main.css">
9
 
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
10
 
    <script src="../../build/yui/yui-min.js"></script>
11
 
</head>
12
 
<body>
13
 
 
14
 
<div id="doc">
15
 
    <h1>Example: Attribute Change Events</h1>
16
 
 
17
 
    
18
 
 
19
 
    <div class="yui3-g">
20
 
        <div class="yui3-u-3-4">
21
 
            <div id="main">
22
 
                <div class="content"><style type="text/css" scoped>
23
 
    #example-out .event {
24
 
        padding:2px 2px 2px 5px;
25
 
    }
26
 
    
27
 
    #example-out .event-props {
28
 
        font-family:courier;
29
 
        margin-top:2px;
30
 
    }
31
 
 
32
 
    #example-out .event-title {
33
 
        font-weight:bold;
34
 
        font-family:arial;
35
 
        color:#8dd5e7;
36
 
        margin-top:5px;
37
 
        margin-bottom:3px;
38
 
    }
39
 
 
40
 
    #example-out {
41
 
        margin:5px;
42
 
        border:1px solid #000;
43
 
        color:#ffffff;
44
 
        background-color:#004c6d;
45
 
        overflow:auto;
46
 
        height:20em;
47
 
    }
48
 
 
49
 
    .attrs {
50
 
        border:1px solid #000;
51
 
        background-color:#cdcdcd;
52
 
        margin:5px;
53
 
    }
54
 
 
55
 
    .attrs .header {
56
 
        font-weight:bold;
57
 
        background-color:#aaa;
58
 
        padding:5px;
59
 
    }
60
 
 
61
 
    .attrs .body {
62
 
        padding:10px;
63
 
    }
64
 
 
65
 
    .attrs .footer {
66
 
        padding:5px;
67
 
    }
68
 
 
69
 
    .attrs label {
70
 
        display:block;
71
 
        float:left;
72
 
        clear:left;
73
 
        font-weight:bold;
74
 
        width:8em;
75
 
    }
76
 
 
77
 
    .attrs #preventFoobar.hidden {
78
 
        display:none;
79
 
    }
80
 
 
81
 
    .attrs #preventFoobar {
82
 
        margin-left:5px;
83
 
        display:inline;
84
 
        float:none;
85
 
        clear:none;
86
 
    }
87
 
</style>
88
 
 
89
 
<div class="intro">
90
 
    <p>Attribute change events are one of the key benefits of using attributes to maintain state for your objects, instead of regular object properties. This example shows how you can listen for attribute change events and work with the event payload they receive.</p> 
91
 
</div>
92
 
 
93
 
<div class="example">
94
 
    <form id="changeValue" class="attrs" action="#">
95
 
    <div class="header">Enter a new value and click the "Change Value" button:</div>
96
 
    <div class="body">
97
 
        <p>
98
 
            <label for="attrSel">Attribute</label>: 
99
 
            <select id="attrSel">
100
 
                <option value="foo">foo</option>
101
 
                <option value="bar">bar</option>
102
 
                <option value="foobar">foobar</option>
103
 
            </select>
104
 
            <label id="preventFoobar" class="hidden"><input type="checkbox" checked="true"> Prevent change</label>
105
 
        </p>
106
 
        <p><label for="currentVal">Current Value</label>: <span id="currentVal"></span></p>
107
 
        <p><label for="newVal">New Value</label>: <input type="text" id="newVal" /></p>
108
 
    </div>
109
 
    <div class="footer">
110
 
        <button type="submit">Change Value</button>
111
 
    </div>
112
 
</form>
113
 
 
114
 
<div id="example-out"></div>
115
 
 
116
 
<script type="text/javascript">
117
 
// Get a new YUI instance 
118
 
YUI().use("node", "attribute", "escape", function(Y) {
119
 
 
120
 
    // Setup a custom class with attribute support
121
 
    function MyClass(cfg) {
122
 
 
123
 
        // Setup attribute configuration
124
 
        var attrs = {
125
 
            "foo" : {
126
 
                value:5
127
 
            },
128
 
     
129
 
            "bar" : {
130
 
                value:"Hello World!"
131
 
            },
132
 
    
133
 
            "foobar" : {
134
 
                value:true
135
 
            }
136
 
        };
137
 
 
138
 
        this.addAttrs(attrs, cfg);
139
 
    }
140
 
 
141
 
    Y.augment(MyClass, Y.Attribute);
142
 
 
143
 
    var o1 = new MyClass();
144
 
 
145
 
    function displayEvent(e, title) {
146
 
        var str = '<div class="event"><div class="event-title">' + title + '</div>';
147
 
 
148
 
        if (e) {
149
 
            str += 
150
 
            '<ul class="event-props"><li>e.attrName: ' 
151
 
            + e.attrName 
152
 
            + '</li><li>e.prevVal: '
153
 
            + Y.Escape.html(e.prevVal + "")
154
 
            + '</li><li>e.newVal: '
155
 
            + Y.Escape.html(e.newVal + "")
156
 
            + '</li></ul></div>';
157
 
        }
158
 
 
159
 
        str += '</div>';
160
 
 
161
 
        Y.one("#example-out").prepend(str);
162
 
    }
163
 
 
164
 
    // Start Example Form Handling
165
 
    var attrSel = Y.one("#attrSel");
166
 
    var newValTxt = Y.one("#newVal");
167
 
    var currentValSpan = Y.one("#currentVal");
168
 
    var preventFoobarChk = Y.one("#preventFoobar input[type=checkbox]");
169
 
    var preventFoobarLbl = Y.one("#preventFoobar");
170
 
 
171
 
    var attrOpts = attrSel.get("options");
172
 
 
173
 
    function updateVal(e) {
174
 
        e.preventDefault();
175
 
        
176
 
        var selIndex = attrSel.get("selectedIndex");
177
 
        var attr = attrOpts.item(selIndex).get("value");
178
 
        o1.set(attr, newValTxt.get("value"));
179
 
    }
180
 
 
181
 
    Y.on("submit", updateVal, "#changeValue");
182
 
 
183
 
    function populateCurrentValue() {
184
 
        var selIndex = attrSel.get("selectedIndex");
185
 
        var attr = attrOpts.item(selIndex).get("value");
186
 
 
187
 
        currentValSpan.set("innerHTML", Y.Escape.html(o1.get(attr) + ""));
188
 
        newValTxt.set("value", "");
189
 
 
190
 
        if (attr === "foobar") {
191
 
            preventFoobarLbl.removeClass("hidden");
192
 
        } else {
193
 
            preventFoobarLbl.addClass("hidden");
194
 
        }
195
 
    }
196
 
 
197
 
    populateCurrentValue();
198
 
 
199
 
    Y.on("change", populateCurrentValue, attrSel);
200
 
    // End Example Form Handling
201
 
 
202
 
    // Attribute Change Event Listners
203
 
 
204
 
    o1.after("fooChange", function(e) {
205
 
        displayEvent(e, "After fooChange");
206
 
        currentValSpan.set("innerHTML", Y.Escape.html(e.newVal+""));
207
 
    });
208
 
 
209
 
    o1.after("barChange", function(e) {
210
 
        displayEvent(e, "After barChange");
211
 
        currentValSpan.set("innerHTML", Y.Escape.html(e.newVal+""));
212
 
    });
213
 
 
214
 
    o1.on("foobarChange", function(e) {
215
 
 
216
 
        if (preventFoobarChk.get("checked")) {
217
 
 
218
 
            // Calling preventDefault, in an "on" listener
219
 
            // will prevent the attribute change from occuring
220
 
            // and the after listener being called.
221
 
 
222
 
            e.preventDefault();
223
 
            displayEvent(null, "On foobarChange (prevented)");
224
 
        }
225
 
 
226
 
    });
227
 
 
228
 
    o1.after("foobarChange", function(e) {
229
 
 
230
 
        // This foobar after listener will not get called, 
231
 
        // if we end up preventing default in the "on" 
232
 
        // listener above.
233
 
 
234
 
        displayEvent(e, "After foobarChange");
235
 
        currentValSpan.set("innerHTML", Y.Escape.html(e.newVal+""));
236
 
    });
237
 
 
238
 
});
239
 
</script>
240
 
 
241
 
</div>
242
 
 
243
 
<h2>Listening For Attribute Change Events</h2>
244
 
 
245
 
<p>In this example, we'll look at how you can setup listeners for attribute change events, and work with the event payload which the listeners receive.</p>
246
 
 
247
 
<h3>Setting Up A Custom Class With Attribute</h3>
248
 
 
249
 
<p>We start by setting up the same custom class we created for the <a href="attribute-basic.html">basic example</a> with 3 attributes <code>foo</code>, <code>bar</code> and <code>foobar</code>, using the code below:</p>
250
 
 
251
 
<pre class="code prettyprint">YUI().use(&quot;attribute&quot;, &quot;node&quot;, function(Y) {
252
 
 
253
 
    &#x2F;&#x2F; Setup a custom class with attribute support
254
 
    function MyClass(cfg) {
255
 
 
256
 
        &#x2F;&#x2F; Setup attribute configuration
257
 
        var attrs = {
258
 
            &quot;foo&quot; : {
259
 
                value:5
260
 
            },
261
 
     
262
 
            &quot;bar&quot; : {
263
 
                value:&quot;Hello World!&quot;
264
 
            },
265
 
    
266
 
            &quot;foobar&quot; : {
267
 
                value:true
268
 
            }
269
 
        };
270
 
 
271
 
        this.addAttrs(attrs, cfg);
272
 
    }
273
 
 
274
 
    Y.augment(MyClass, Y.Attribute);
275
 
 
276
 
});</pre>
277
 
 
278
 
 
279
 
<h3>Registering Event Listeners</h3>
280
 
 
281
 
<p>Once we have an instance of the custom class, we can use the <code>on</code> and <code>after</code> methods provided by Attribute, to listen for changes in the value of each of the attributes:</p>
282
 
 
283
 
<pre class="code prettyprint">var o1 = new MyClass();
284
 
 
285
 
...
286
 
 
287
 
&#x2F;&#x2F; Event Listners
288
 
o1.after(&quot;fooChange&quot;, function(e) {
289
 
    displayEvent(e, &quot;After fooChange&quot;);
290
 
    currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(e.newVal+&quot;&quot;));
291
 
});
292
 
 
293
 
o1.after(&quot;barChange&quot;, function(e) {
294
 
    displayEvent(e, &quot;After barChange&quot;);
295
 
    currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(e.newVal+&quot;&quot;));
296
 
});
297
 
 
298
 
o1.on(&quot;foobarChange&quot;, function(e) {
299
 
 
300
 
    if (preventFoobarChk.get(&quot;checked&quot;)) {
301
 
 
302
 
        &#x2F;&#x2F; Calling preventDefault, in an &quot;on&quot; listener
303
 
        &#x2F;&#x2F; will prevent the attribute change from occuring
304
 
        &#x2F;&#x2F; and the after listener being called.
305
 
 
306
 
        e.preventDefault();
307
 
        displayEvent(null, &quot;On foobarChange (prevented)&quot;);
308
 
    }
309
 
 
310
 
});
311
 
 
312
 
o1.after(&quot;foobarChange&quot;, function(e) {
313
 
 
314
 
    &#x2F;&#x2F; This foobar after listener will not get called, 
315
 
    &#x2F;&#x2F; if we end up preventing default in the &quot;on&quot; 
316
 
    &#x2F;&#x2F; listener above.
317
 
 
318
 
    displayEvent(e, &quot;After foobarChange&quot;);
319
 
    currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(e.newVal+&quot;&quot;));
320
 
});</pre>
321
 
 
322
 
 
323
 
<p>As seen in the above code, the event type for attribute change events is created by concatenating the attribute name with <code>&quot;Change&quot;</code> (e.g. <code>&quot;fooChange&quot;</code>), and this event type is used for both the <code>on</code> and <code>after</code> subscription methods. Whenever an attribute value is changed through Attribute's <code>set</code> method, both "on" and "after" subscribers are notified.</p>
324
 
 
325
 
<h3>On vs. After</h3>
326
 
 
327
 
<p><strong>on :</strong> Subscribers to the "on" moment, will be notified <em>before</em> any actual state change has occurred. This provides the opportunity to prevent the state change from occurring, using the <code>preventDefault</code> method of the event facade object passed to the subscriber. If you use <code>get</code> to retrieve the value of the attribute in an "on" subscriber, you will receive the current, unchanged value. However the event facade provides access to the value which the attribute is being set to, through it's <code>newVal</code> property.</p>
328
 
 
329
 
<p><strong>after :</strong> Subscribers to the "after" moment, will be notified <em>after</em> the attribute's state has been updated. This provides the opportunity to update state in other parts of your application, in response to a change in the attribute's state.</p>
330
 
 
331
 
<p>Based on the definition above, <code>after</code> listeners are not invoked if state change is prevented, for example, due to one of the <code>on</code> listeners calling <code>preventDefault</code> on the event object, as is done in the <code>on</code> listener for the <code>foobar</code> attribute:</p>
332
 
 
333
 
<pre class="code prettyprint">o1.on(&quot;foobarChange&quot;, function(event) {
334
 
 
335
 
    &#x2F;&#x2F; Calling preventDefault, in an &quot;on&quot; listener
336
 
    &#x2F;&#x2F; will prevent the attribute change from occurring
337
 
    &#x2F;&#x2F; and prevent the after listeners from being called
338
 
    displayEvent(event, &quot;on foobarChange (change prevented)&quot;);
339
 
 
340
 
    event.preventDefault();
341
 
});</pre>
342
 
 
343
 
 
344
 
<p>For primitive values (non-Object values), the <code>after</code> listeners will also not be invoked if there is no change in the actual value of the attribute. That is, if the new value of the attribute is the same as the current value (based on the identity operator, <code>===</code>), the <code>after</code> listeners will not be notified because there is no change in state. You can see this, by setting an attribute to the same value twice in a row.</p>
345
 
 
346
 
<h3>Event Facade</h3>
347
 
 
348
 
<p>The event object (an instance of <a href="http://yuilibrary.com/yui/docs/api/EventFacade.html">EventFacade</a>) passed to attribute change event subscribers, has the following interesting properties and methods related to attribute management:</p>
349
 
 
350
 
<dl>
351
 
    <dt>newVal</dt>
352
 
    <dd>The value which the attribute will be set to (in the case of "on" subscribers), or has been set to (in the case of "after" subscribers</dd>
353
 
    <dt>prevVal</dt>
354
 
    <dd>The value which the attribute is currently set to (in the case of "on" subscribers), or was previously set to (in the case of "after" subscribers</dd>
355
 
    <dt>attrName</dt>
356
 
    <dd>The name of the attribute which is being set</dd>
357
 
    <dt>subAttrName</dt>
358
 
    <dd>Attribute also allows you to set nested properties of attributes which have values which are objects through the 
359
 
    <code>set</code> method (e.g. <code>o1.set(&quot;x.y.z&quot;)</code>). This property will contain the path to the property which was changed.</dd>
360
 
    <dt>preventDefault()<dt>
361
 
    <dd>This method can be called in an "on" subscriber to prevent the attribute's value from being updated (the default behavior). Calling this method in an "after" listener has no impact, since the default behavior has already been invoked.</dd>
362
 
    <dt>stopImmediatePropagation()</dt>
363
 
    <dd>This method can be called in "on" or "after" subscribers, and will prevent the rest of the subscriber stack from
364
 
    being invoked, but will not prevent the attribute's value from being updated.</dd>
365
 
</dl>
366
 
 
367
 
<p>The <a href="attribute-event-speeddate.html">"Attribute Event Based Speed Dating" example</a> provides a look at how you can leverage attribute change events in your applications, to decouple logic both within your class, and when interacting with other objects.</p>
368
 
 
369
 
<h2>Complete Example Source</h2>
370
 
 
371
 
<pre class="code prettyprint">&lt;form id=&quot;changeValue&quot; class=&quot;attrs&quot; action=&quot;#&quot;&gt;
372
 
    &lt;div class=&quot;header&quot;&gt;Enter a new value and click the &quot;Change Value&quot; button:&lt;&#x2F;div&gt;
373
 
    &lt;div class=&quot;body&quot;&gt;
374
 
        &lt;p&gt;
375
 
            &lt;label for=&quot;attrSel&quot;&gt;Attribute&lt;&#x2F;label&gt;: 
376
 
            &lt;select id=&quot;attrSel&quot;&gt;
377
 
                &lt;option value=&quot;foo&quot;&gt;foo&lt;&#x2F;option&gt;
378
 
                &lt;option value=&quot;bar&quot;&gt;bar&lt;&#x2F;option&gt;
379
 
                &lt;option value=&quot;foobar&quot;&gt;foobar&lt;&#x2F;option&gt;
380
 
            &lt;&#x2F;select&gt;
381
 
            &lt;label id=&quot;preventFoobar&quot; class=&quot;hidden&quot;&gt;&lt;input type=&quot;checkbox&quot; checked=&quot;true&quot;&gt; Prevent change&lt;&#x2F;label&gt;
382
 
        &lt;&#x2F;p&gt;
383
 
        &lt;p&gt;&lt;label for=&quot;currentVal&quot;&gt;Current Value&lt;&#x2F;label&gt;: &lt;span id=&quot;currentVal&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
384
 
        &lt;p&gt;&lt;label for=&quot;newVal&quot;&gt;New Value&lt;&#x2F;label&gt;: &lt;input type=&quot;text&quot; id=&quot;newVal&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
385
 
    &lt;&#x2F;div&gt;
386
 
    &lt;div class=&quot;footer&quot;&gt;
387
 
        &lt;button type=&quot;submit&quot;&gt;Change Value&lt;&#x2F;button&gt;
388
 
    &lt;&#x2F;div&gt;
389
 
&lt;&#x2F;form&gt;
390
 
 
391
 
&lt;div id=&quot;example-out&quot;&gt;&lt;&#x2F;div&gt;
392
 
 
393
 
&lt;script type=&quot;text&#x2F;javascript&quot;&gt;
394
 
&#x2F;&#x2F; Get a new YUI instance 
395
 
YUI().use(&quot;node&quot;, &quot;attribute&quot;, &quot;escape&quot;, function(Y) {
396
 
 
397
 
    &#x2F;&#x2F; Setup a custom class with attribute support
398
 
    function MyClass(cfg) {
399
 
 
400
 
        &#x2F;&#x2F; Setup attribute configuration
401
 
        var attrs = {
402
 
            &quot;foo&quot; : {
403
 
                value:5
404
 
            },
405
 
     
406
 
            &quot;bar&quot; : {
407
 
                value:&quot;Hello World!&quot;
408
 
            },
409
 
    
410
 
            &quot;foobar&quot; : {
411
 
                value:true
412
 
            }
413
 
        };
414
 
 
415
 
        this.addAttrs(attrs, cfg);
416
 
    }
417
 
 
418
 
    Y.augment(MyClass, Y.Attribute);
419
 
 
420
 
    var o1 = new MyClass();
421
 
 
422
 
    function displayEvent(e, title) {
423
 
        var str = &#x27;&lt;div class=&quot;event&quot;&gt;&lt;div class=&quot;event-title&quot;&gt;&#x27; + title + &#x27;&lt;&#x2F;div&gt;&#x27;;
424
 
 
425
 
        if (e) {
426
 
            str += 
427
 
            &#x27;&lt;ul class=&quot;event-props&quot;&gt;&lt;li&gt;e.attrName: &#x27; 
428
 
            + e.attrName 
429
 
            + &#x27;&lt;&#x2F;li&gt;&lt;li&gt;e.prevVal: &#x27;
430
 
            + Y.Escape.html(e.prevVal + &quot;&quot;)
431
 
            + &#x27;&lt;&#x2F;li&gt;&lt;li&gt;e.newVal: &#x27;
432
 
            + Y.Escape.html(e.newVal + &quot;&quot;)
433
 
            + &#x27;&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;div&gt;&#x27;;
434
 
        }
435
 
 
436
 
        str += &#x27;&lt;&#x2F;div&gt;&#x27;;
437
 
 
438
 
        Y.one(&quot;#example-out&quot;).prepend(str);
439
 
    }
440
 
 
441
 
    &#x2F;&#x2F; Start Example Form Handling
442
 
    var attrSel = Y.one(&quot;#attrSel&quot;);
443
 
    var newValTxt = Y.one(&quot;#newVal&quot;);
444
 
    var currentValSpan = Y.one(&quot;#currentVal&quot;);
445
 
    var preventFoobarChk = Y.one(&quot;#preventFoobar input[type=checkbox]&quot;);
446
 
    var preventFoobarLbl = Y.one(&quot;#preventFoobar&quot;);
447
 
 
448
 
    var attrOpts = attrSel.get(&quot;options&quot;);
449
 
 
450
 
    function updateVal(e) {
451
 
        e.preventDefault();
452
 
        
453
 
        var selIndex = attrSel.get(&quot;selectedIndex&quot;);
454
 
        var attr = attrOpts.item(selIndex).get(&quot;value&quot;);
455
 
        o1.set(attr, newValTxt.get(&quot;value&quot;));
456
 
    }
457
 
 
458
 
    Y.on(&quot;submit&quot;, updateVal, &quot;#changeValue&quot;);
459
 
 
460
 
    function populateCurrentValue() {
461
 
        var selIndex = attrSel.get(&quot;selectedIndex&quot;);
462
 
        var attr = attrOpts.item(selIndex).get(&quot;value&quot;);
463
 
 
464
 
        currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(o1.get(attr) + &quot;&quot;));
465
 
        newValTxt.set(&quot;value&quot;, &quot;&quot;);
466
 
 
467
 
        if (attr === &quot;foobar&quot;) {
468
 
            preventFoobarLbl.removeClass(&quot;hidden&quot;);
469
 
        } else {
470
 
            preventFoobarLbl.addClass(&quot;hidden&quot;);
471
 
        }
472
 
    }
473
 
 
474
 
    populateCurrentValue();
475
 
 
476
 
    Y.on(&quot;change&quot;, populateCurrentValue, attrSel);
477
 
    &#x2F;&#x2F; End Example Form Handling
478
 
 
479
 
    &#x2F;&#x2F; Attribute Change Event Listners
480
 
 
481
 
    o1.after(&quot;fooChange&quot;, function(e) {
482
 
        displayEvent(e, &quot;After fooChange&quot;);
483
 
        currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(e.newVal+&quot;&quot;));
484
 
    });
485
 
 
486
 
    o1.after(&quot;barChange&quot;, function(e) {
487
 
        displayEvent(e, &quot;After barChange&quot;);
488
 
        currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(e.newVal+&quot;&quot;));
489
 
    });
490
 
 
491
 
    o1.on(&quot;foobarChange&quot;, function(e) {
492
 
 
493
 
        if (preventFoobarChk.get(&quot;checked&quot;)) {
494
 
 
495
 
            &#x2F;&#x2F; Calling preventDefault, in an &quot;on&quot; listener
496
 
            &#x2F;&#x2F; will prevent the attribute change from occuring
497
 
            &#x2F;&#x2F; and the after listener being called.
498
 
 
499
 
            e.preventDefault();
500
 
            displayEvent(null, &quot;On foobarChange (prevented)&quot;);
501
 
        }
502
 
 
503
 
    });
504
 
 
505
 
    o1.after(&quot;foobarChange&quot;, function(e) {
506
 
 
507
 
        &#x2F;&#x2F; This foobar after listener will not get called, 
508
 
        &#x2F;&#x2F; if we end up preventing default in the &quot;on&quot; 
509
 
        &#x2F;&#x2F; listener above.
510
 
 
511
 
        displayEvent(e, &quot;After foobarChange&quot;);
512
 
        currentValSpan.set(&quot;innerHTML&quot;, Y.Escape.html(e.newVal+&quot;&quot;));
513
 
    });
514
 
 
515
 
});
516
 
&lt;&#x2F;script&gt;</pre>
517
 
 
518
 
</div>
519
 
            </div>
520
 
        </div>
521
 
 
522
 
        <div class="yui3-u-1-4">
523
 
            <div class="sidebar">
524
 
                
525
 
 
526
 
                
527
 
                    <div class="sidebox">
528
 
                        <div class="hd">
529
 
                            <h2 class="no-toc">Examples</h2>
530
 
                        </div>
531
 
 
532
 
                        <div class="bd">
533
 
                            <ul class="examples">
534
 
                                
535
 
                                    
536
 
                                        <li data-description="Use the Attribute API to define, set and get attribute values.">
537
 
                                            <a href="attribute-basic.html">Basic Attribute Configuration</a>
538
 
                                        </li>
539
 
                                    
540
 
                                
541
 
                                    
542
 
                                        <li data-description="Configure attributes to be readOnly or writeOnce.">
543
 
                                            <a href="attribute-rw.html">Read-Only and Write-Once Attributes</a>
544
 
                                        </li>
545
 
                                    
546
 
                                
547
 
                                    
548
 
                                        <li data-description="How to listen for changes in attribute values.">
549
 
                                            <a href="attribute-event.html">Attribute Change Events</a>
550
 
                                        </li>
551
 
                                    
552
 
                                
553
 
                                    
554
 
                                        <li data-description="Create a basic SpeedDater class, with Attribute support.">
555
 
                                            <a href="attribute-basic-speeddate.html">Attribute Based Speed Dating</a>
556
 
                                        </li>
557
 
                                    
558
 
                                
559
 
                                    
560
 
                                        <li data-description="Refactors the basic Speed Dating example, to use attribute change events to update rendered elements, and have two instances react to another.">
561
 
                                            <a href="attribute-event-speeddate.html">Attribute Event Based Speed Dating</a>
562
 
                                        </li>
563
 
                                    
564
 
                                
565
 
                                    
566
 
                                        <li data-description="Add custom methods to get and set attribute values and provide validation support.">
567
 
                                            <a href="attribute-getset.html">Attribute Getters, Setters and Validators</a>
568
 
                                        </li>
569
 
                                    
570
 
                                
571
 
                            </ul>
572
 
                        </div>
573
 
                    </div>
574
 
                
575
 
 
576
 
                
577
 
            </div>
578
 
        </div>
579
 
    </div>
580
 
</div>
581
 
 
582
 
<script src="../assets/vendor/prettify/prettify-min.js"></script>
583
 
<script>prettyPrint();</script>
584
 
 
585
 
</body>
586
 
</html>