|
1 <!DOCTYPE html> |
|
2 <html lang="en"> |
|
3 <head> |
|
4 <meta charset="utf-8"> |
|
5 <title>Example: Basic Attribute Configuration</title> |
|
6 <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic"> |
|
7 <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css"> |
|
8 <link rel="stylesheet" href="../assets/css/main.css"> |
|
9 <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css"> |
|
10 <link rel="shortcut icon" type="image/png" href="../assets/favicon.png"> |
|
11 <script src="../../build/yui/yui-min.js"></script> |
|
12 |
|
13 </head> |
|
14 <body> |
|
15 <!-- |
|
16 <a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> |
|
17 --> |
|
18 <div id="doc"> |
|
19 <div id="hd"> |
|
20 <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1> |
|
21 </div> |
|
22 |
|
23 |
|
24 <h1>Example: Basic Attribute Configuration</h1> |
|
25 <div class="yui3-g"> |
|
26 <div class="yui3-u-3-4"> |
|
27 <div id="main"> |
|
28 <div class="content"><style type="text/css" scoped> |
|
29 .example-out .myclass-attrs { |
|
30 font-family:courier; |
|
31 margin-top:2px; |
|
32 } |
|
33 |
|
34 .example-out .myclass-title { |
|
35 font-weight:bold; |
|
36 font-family:arial; |
|
37 color:#8dd5e7; |
|
38 margin-top:5px; |
|
39 margin-bottom:3px; |
|
40 } |
|
41 |
|
42 .example-out { |
|
43 overflow:auto; |
|
44 border:1px solid #000; |
|
45 color:#ffffff; |
|
46 background-color:#004C6D; |
|
47 margin:5px; |
|
48 height:8em; |
|
49 padding:2px 2px 2px 5px; |
|
50 } |
|
51 </style> |
|
52 |
|
53 <div class="intro"> |
|
54 <p>This example provides an introduction to the Attribute utility, showing how you can use it to add attribute support to your own custom classes.</p> |
|
55 <p> |
|
56 It is geared towards users who want to create their own classes from scratch and add Attribute support. In most cases you should consider extending the <a href="../base/index.html"><code>Base</code></a> class when you need managed attribute support, |
|
57 instead of augmenting Attribute directly, especially if you expect your class to be extended. <a href="../base/index.html"><code>Base</code></a> does the work described in this example for you, in addition to making it easier for users to extend you class. |
|
58 </p> |
|
59 </div> |
|
60 |
|
61 <div class="example"> |
|
62 <div id="createo1"> |
|
63 <button type="button" class="do">Create First Instance</button> Construct o1, with default attribute values |
|
64 <div class="example-out"></div> |
|
65 </div> |
|
66 <div id="updateo1"> |
|
67 <button type="button" class="do">Update First Instance</button> Update the first instance, using set |
|
68 <div class="example-out"></div> |
|
69 </div> |
|
70 <div id="createo2"> |
|
71 <button type="button" class="do">Create Second Instance</button> Create the second instance, passing initial values to the constructor |
|
72 <div class="example-out"></div> |
|
73 </div> |
|
74 |
|
75 <script type="text/javascript"> |
|
76 |
|
77 // Get a new instance of YUI and |
|
78 // load it with the required set of modules |
|
79 |
|
80 YUI().use("node", "attribute", function(Y) { |
|
81 |
|
82 // Setup custom class which we want to |
|
83 // add managed attribute support to |
|
84 |
|
85 function MyClass(cfg) { |
|
86 |
|
87 // When constructed, setup the initial attributes for the instance, by calling the addAttrs method. |
|
88 var attrs = { |
|
89 // Add 3 attributes, foo, bar and foobar |
|
90 "foo" : { |
|
91 value:5 |
|
92 }, |
|
93 |
|
94 "bar" : { |
|
95 value:"Hello World!" |
|
96 }, |
|
97 |
|
98 "foobar" : { |
|
99 value:true |
|
100 } |
|
101 }; |
|
102 |
|
103 this.addAttrs(attrs, cfg); |
|
104 } |
|
105 |
|
106 // Augment custom class with Attribute |
|
107 Y.augment(MyClass, Y.Attribute); |
|
108 |
|
109 function displayValues(o, title, node) { |
|
110 var str = |
|
111 '<div class="myclass"><div class="myclass-title">' |
|
112 + title + |
|
113 '</div><ul class="myclass-attrs"><li>foo: ' |
|
114 + o.get("foo") |
|
115 + '</li><li>bar: ' |
|
116 + o.get("bar") |
|
117 + '</li><li>foobar: ' |
|
118 + o.get("foobar") |
|
119 + '</li></ul></div>'; |
|
120 |
|
121 Y.one(node).set("innerHTML", str); |
|
122 } |
|
123 |
|
124 Y.on("click", function() { |
|
125 |
|
126 // Create a new instance, but don't provide any initial attribute values. |
|
127 var o1 = new MyClass(); |
|
128 |
|
129 // Display current values |
|
130 displayValues(o1, "o1 with default values, set during construction", "#createo1 .example-out"); |
|
131 |
|
132 Y.on("click", function() { |
|
133 |
|
134 // Update values, using the "set" method |
|
135 o1.set("foo", 10); |
|
136 o1.set("bar", "Hello New World!"); |
|
137 o1.set("foobar", false); |
|
138 |
|
139 displayValues(o1, "o1 values updated using set, after construction", "#updateo1 .example-out"); |
|
140 |
|
141 }, "#updateo1 .do"); |
|
142 |
|
143 }, "#createo1 .do"); |
|
144 |
|
145 Y.on("click", function() { |
|
146 |
|
147 var o2 = new MyClass({ |
|
148 foo: 7, |
|
149 bar: "Aloha World!", |
|
150 foobar: false |
|
151 }); |
|
152 |
|
153 displayValues(o2, "o2 values set during construction", "#createo2 .example-out"); |
|
154 |
|
155 }, "#createo2 .do"); |
|
156 }); |
|
157 </script> |
|
158 |
|
159 </div> |
|
160 |
|
161 <h2>Setting Up Your Own Class To Use Attribute</h2> |
|
162 |
|
163 <p>In this example, we'll show how you can use the Attribute utility to add managed attributes to your own object classes. Later examples will show how you can configure more advanced attribute properties, and work with attribute change events.</p> |
|
164 |
|
165 <h3>Creating A YUI Instance</h3> |
|
166 |
|
167 <p>Before we get into attribute, a quick note on how we set up the instance of YUI we'll use for the examples. For all of the attribute examples, we'll setup our own instance of the YUI object and download the files we require on demand using the code pattern shown below:</p> |
|
168 |
|
169 <pre class="code prettyprint"><script type="text/javascript"> |
|
170 |
|
171 // Create our local YUI instance, to avoid |
|
172 // modifying the global YUI object |
|
173 |
|
174 YUI({...}).use("attribute", "node", function(Y) { |
|
175 |
|
176 // Example code is written inside this function, |
|
177 // which gets passed our own YUI instance, Y, loaded |
|
178 // with the modules we asked for - "attribute" and "node" |
|
179 |
|
180 }); |
|
181 </script></pre> |
|
182 |
|
183 |
|
184 <p>The call to <code>YUI()</code> will create and return a new instance of the global YUI object for us to use. However this instance does not yet have all the modules we need for the examples.</p> |
|
185 |
|
186 <p>To load the modules, we invoke <code>use()</code> and pass it the list of modules we'd like populated on our new YUI instance - in this case, <code>attribute</code> and <code>node</code>. |
|
187 |
|
188 The YUI instance will pull down the source files for modules if they don't already exist on the page, plus any or their dependencies. |
|
189 When the source files are done downloading, the callback function which we pass in as the 3rd argument to <code>use()</code>, is invoked. Our custom YUI instance, <code>Y</code>, is passed to the callback, populated with the classes which make up the requested modules.</p> |
|
190 |
|
191 <p>This callback function is where we'll write all our example code. By working inside the callback function, we don't pollute the global namespace and we're also able to download the files we need on demand, rather than have them be on the page up front.</p> |
|
192 |
|
193 <p>The configuration object passed to <code>YUI()</code> when creating the instance is used to specify how (<em>combined, separate, debug, min etc.</em>) we want the files downloaded, and from where. The API documentation for the <a href="http://yuilibrary.com/yui/docs/api/YUI.html">YUI object</a>, provides more information about the configuration options available.</p> |
|
194 |
|
195 <h3>Defining Your Custom Class</h3> |
|
196 |
|
197 <p>The first step in the example is to create the constructor function for our new class, to which we want to add attribute support. In our example, this class is called <code>MyClass</code>. |
|
198 |
|
199 We then augment <code>MyClass</code> with <code>Y.Attribute</code>, so that it receives all of <code>Attribute's</code> methods:</p> |
|
200 |
|
201 <pre class="code prettyprint">function MyClass(cfg) { |
|
202 ... |
|
203 } |
|
204 |
|
205 Y.augment(MyClass, Y.Attribute);</pre> |
|
206 |
|
207 |
|
208 <h3>Adding Attributes</h3> |
|
209 |
|
210 <p>We can now set up any attributes we need for <code>MyClass</code> using the <code>addAttrs</code> method. For the basic example we add 3 attributes - <code>foo</code>,<code>bar</code>, and <code>foobar</code>, and provide an initial <code>value</code> for each. |
|
211 |
|
212 The same object literal we use to provide the initial value for the attribute will also be used in the other examples to configure attribute properties such as <code>readOnly</code> or <code>writeOnce</code>, and define <code>getter</code>, <code>setter</code> and <code>validator</code> methods for the attribute.</p> |
|
213 |
|
214 <p>In this example, the default set of attributes which <code>MyClass</code> will support gets passed to <code>addAttrs</code> to set up the attributes for each instance during construction.</p> |
|
215 |
|
216 The complete definition for <code>MyClass</code> is shown below:</p> |
|
217 |
|
218 <pre class="code prettyprint">// Setup custom class which we want to add managed attribute support to |
|
219 function MyClass(cfg) { |
|
220 |
|
221 // When constructed, setup the initial attributes for the |
|
222 // instance, by calling the addAttrs method. |
|
223 var attrs = { |
|
224 // Add 3 attributes, foo, bar and foobar |
|
225 "foo" : { |
|
226 value:5 |
|
227 }, |
|
228 |
|
229 "bar" : { |
|
230 value:"Hello World!" |
|
231 }, |
|
232 |
|
233 "foobar" : { |
|
234 value:true |
|
235 } |
|
236 }; |
|
237 |
|
238 this.addAttrs(attrs, cfg); |
|
239 } |
|
240 |
|
241 // Augment custom class with Attribute |
|
242 Y.augment(MyClass, Y.Attribute);</pre> |
|
243 |
|
244 |
|
245 <p>The <code>addAttrs</code> method, in addition to the default attribute configuration, also accepts an object literal (associative array) of name/value pairs which can be used to over-ride the default initial values of the attributes. This is useful for classes which wish to allow the user to set the value of attributes as part of object construction, as shown by the use of the <code>cfg</code> argument above.</p> |
|
246 |
|
247 <p> |
|
248 As mentioned previously, if you expect your class to be extended, <a href="../base/index.html">Base</a> provides a more convenient way for you to define the same attribute configuration statically for your class, so that it can be easily modified by extended classes. Base will take care of isolating the static configuration, so that it isn't modified across instances. |
|
249 </p> |
|
250 |
|
251 <h3>Using Attributes</h3> |
|
252 |
|
253 <p>Now that we have <code>MyClass</code> defined with a set of attributes it supports, users can get and set attribute values on instances of <code>MyClass</code>:</p> |
|
254 |
|
255 <p>We construct the first instance, <code>o1</code>, without setting any initial attribute values in the constructor, but use Attribute's <code>set()</code> method to set values after construction:</p> |
|
256 |
|
257 <pre class="code prettyprint">// Create a new instance, but don't provide any initial attribute values. |
|
258 var o1 = new MyClass(); |
|
259 |
|
260 // Display current values |
|
261 displayValues(o1, "o1 with default values, set during construction", |
|
262 "#createo1 .example-out"); |
|
263 |
|
264 ... |
|
265 |
|
266 // Update values, using the "set" method |
|
267 o1.set("foo", 10); |
|
268 o1.set("bar", "Hello New World!"); |
|
269 o1.set("foobar", false); |
|
270 |
|
271 displayValues(o1, "o1 values updated using set, after construction", |
|
272 "#updateo1 .example-out");</pre> |
|
273 |
|
274 |
|
275 <p>For the second instance that, <code>o2</code> we set the initial values of the attributes, using the constructor configuration argument:</p> |
|
276 |
|
277 <pre class="code prettyprint">var o2 = new MyClass({ |
|
278 foo: 7, |
|
279 bar: "Aloha World!", |
|
280 foobar: false |
|
281 });</pre> |
|
282 |
|
283 |
|
284 <p>The <code>displayValues()</code> method uses Attribute's <code>get()</code> method to retrieve the current values of the attributes, to display:</p> |
|
285 |
|
286 <pre class="code prettyprint">function displayValues(o, title, node) { |
|
287 var str = |
|
288 '<div class="myclass"><div class="myclass-title">' |
|
289 + title + |
|
290 ':</div><ul class="myclass-attrs"><li>foo:' |
|
291 + o.get("foo") |
|
292 + '</li><li>bar:' |
|
293 + o.get("bar") |
|
294 + '</li><li>foobar:' |
|
295 + o.get("foobar") |
|
296 + '</li></ul></div>'; |
|
297 |
|
298 // Use the Y.one() method to get the first element which |
|
299 // matches the selector passed in, to output the string to... |
|
300 Y.one(node).set("innerHTML", str); |
|
301 }</pre> |
|
302 |
|
303 |
|
304 <h2>Complete Example Source</h2> |
|
305 |
|
306 <pre class="code prettyprint"><div id="createo1"> |
|
307 <button type="button" class="do">Create First Instance</button> Construct o1, with default attribute values |
|
308 <div class="example-out"></div> |
|
309 </div> |
|
310 <div id="updateo1"> |
|
311 <button type="button" class="do">Update First Instance</button> Update the first instance, using set |
|
312 <div class="example-out"></div> |
|
313 </div> |
|
314 <div id="createo2"> |
|
315 <button type="button" class="do">Create Second Instance</button> Create the second instance, passing initial values to the constructor |
|
316 <div class="example-out"></div> |
|
317 </div> |
|
318 |
|
319 <script type="text/javascript"> |
|
320 |
|
321 // Get a new instance of YUI and |
|
322 // load it with the required set of modules |
|
323 |
|
324 YUI().use("node", "attribute", function(Y) { |
|
325 |
|
326 // Setup custom class which we want to |
|
327 // add managed attribute support to |
|
328 |
|
329 function MyClass(cfg) { |
|
330 |
|
331 // When constructed, setup the initial attributes for the instance, by calling the addAttrs method. |
|
332 var attrs = { |
|
333 // Add 3 attributes, foo, bar and foobar |
|
334 "foo" : { |
|
335 value:5 |
|
336 }, |
|
337 |
|
338 "bar" : { |
|
339 value:"Hello World!" |
|
340 }, |
|
341 |
|
342 "foobar" : { |
|
343 value:true |
|
344 } |
|
345 }; |
|
346 |
|
347 this.addAttrs(attrs, cfg); |
|
348 } |
|
349 |
|
350 // Augment custom class with Attribute |
|
351 Y.augment(MyClass, Y.Attribute); |
|
352 |
|
353 function displayValues(o, title, node) { |
|
354 var str = |
|
355 '<div class="myclass"><div class="myclass-title">' |
|
356 + title + |
|
357 '</div><ul class="myclass-attrs"><li>foo: ' |
|
358 + o.get("foo") |
|
359 + '</li><li>bar: ' |
|
360 + o.get("bar") |
|
361 + '</li><li>foobar: ' |
|
362 + o.get("foobar") |
|
363 + '</li></ul></div>'; |
|
364 |
|
365 Y.one(node).set("innerHTML", str); |
|
366 } |
|
367 |
|
368 Y.on("click", function() { |
|
369 |
|
370 // Create a new instance, but don't provide any initial attribute values. |
|
371 var o1 = new MyClass(); |
|
372 |
|
373 // Display current values |
|
374 displayValues(o1, "o1 with default values, set during construction", "#createo1 .example-out"); |
|
375 |
|
376 Y.on("click", function() { |
|
377 |
|
378 // Update values, using the "set" method |
|
379 o1.set("foo", 10); |
|
380 o1.set("bar", "Hello New World!"); |
|
381 o1.set("foobar", false); |
|
382 |
|
383 displayValues(o1, "o1 values updated using set, after construction", "#updateo1 .example-out"); |
|
384 |
|
385 }, "#updateo1 .do"); |
|
386 |
|
387 }, "#createo1 .do"); |
|
388 |
|
389 Y.on("click", function() { |
|
390 |
|
391 var o2 = new MyClass({ |
|
392 foo: 7, |
|
393 bar: "Aloha World!", |
|
394 foobar: false |
|
395 }); |
|
396 |
|
397 displayValues(o2, "o2 values set during construction", "#createo2 .example-out"); |
|
398 |
|
399 }, "#createo2 .do"); |
|
400 }); |
|
401 </script></pre> |
|
402 |
|
403 </div> |
|
404 </div> |
|
405 </div> |
|
406 |
|
407 <div class="yui3-u-1-4"> |
|
408 <div class="sidebar"> |
|
409 |
|
410 |
|
411 |
|
412 <div class="sidebox"> |
|
413 <div class="hd"> |
|
414 <h2 class="no-toc">Examples</h2> |
|
415 </div> |
|
416 |
|
417 <div class="bd"> |
|
418 <ul class="examples"> |
|
419 |
|
420 |
|
421 <li data-description="Use the Attribute API to define, set and get attribute values."> |
|
422 <a href="attribute-basic.html">Basic Attribute Configuration</a> |
|
423 </li> |
|
424 |
|
425 |
|
426 |
|
427 <li data-description="Configure attributes to be readOnly or writeOnce."> |
|
428 <a href="attribute-rw.html">Read-Only and Write-Once Attributes</a> |
|
429 </li> |
|
430 |
|
431 |
|
432 |
|
433 <li data-description="How to listen for changes in attribute values."> |
|
434 <a href="attribute-event.html">Attribute Change Events</a> |
|
435 </li> |
|
436 |
|
437 |
|
438 |
|
439 <li data-description="Create a basic SpeedDater class, with Attribute support."> |
|
440 <a href="attribute-basic-speeddate.html">Attribute Based Speed Dating</a> |
|
441 </li> |
|
442 |
|
443 |
|
444 |
|
445 <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."> |
|
446 <a href="attribute-event-speeddate.html">Attribute Event Based Speed Dating</a> |
|
447 </li> |
|
448 |
|
449 |
|
450 |
|
451 <li data-description="Add custom methods to get and set attribute values and provide validation support."> |
|
452 <a href="attribute-getset.html">Attribute Getters, Setters and Validators</a> |
|
453 </li> |
|
454 |
|
455 |
|
456 </ul> |
|
457 </div> |
|
458 </div> |
|
459 |
|
460 |
|
461 |
|
462 </div> |
|
463 </div> |
|
464 </div> |
|
465 </div> |
|
466 |
|
467 <script src="../assets/vendor/prettify/prettify-min.js"></script> |
|
468 <script>prettyPrint();</script> |
|
469 |
|
470 <script> |
|
471 YUI.Env.Tests = { |
|
472 examples: [], |
|
473 project: '../assets', |
|
474 assets: '../assets/attribute', |
|
475 name: 'attribute-basic', |
|
476 title: 'Basic Attribute Configuration', |
|
477 newWindow: '', |
|
478 auto: false |
|
479 }; |
|
480 YUI.Env.Tests.examples.push('attribute-basic'); |
|
481 YUI.Env.Tests.examples.push('attribute-rw'); |
|
482 YUI.Env.Tests.examples.push('attribute-event'); |
|
483 YUI.Env.Tests.examples.push('attribute-basic-speeddate'); |
|
484 YUI.Env.Tests.examples.push('attribute-event-speeddate'); |
|
485 YUI.Env.Tests.examples.push('attribute-getset'); |
|
486 |
|
487 </script> |
|
488 <script src="../assets/yui/test-runner.js"></script> |
|
489 |
|
490 |
|
491 |
|
492 </body> |
|
493 </html> |