Cross Reference: /yui3/src/attribute/docs/attribute-basic.mustache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<style type="text/css" scoped>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai .example-out .myclass-attrs {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai font-family:courier;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin-top:2px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai }
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai .example-out .myclass-title {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai font-weight:bold;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai font-family:arial;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai color:#8dd5e7;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin-top:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin-bottom:3px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai }
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai .example-out {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai overflow:auto;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:1px solid #000;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai color:#ffffff;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai background-color:#004C6D;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai height:8em;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:2px 2px 2px 5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai }
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai</style>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<div class="intro">
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <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>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai 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">`Base`</a> class when you need managed attribute support,
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai instead of augmenting Attribute directly, especially if you expect your class to be extended. <a href="../base/index.html">`Base`</a> does the work described in this example for you, in addition to making it easier for users to extend you class.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai </p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai</div>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<div class="example">
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai {{>attribute-basic-source}}
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai</div>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Setting Up Your Own Class To Use Attribute</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<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>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Creating A YUI Instance</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<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>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<script type="text/javascript">
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // Create our local YUI instance, to avoid
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // modifying the global YUI object
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai YUI({...}).use("attribute", "node", function(Y) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // Example code is written inside this function,
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // which gets passed our own YUI instance, Y, loaded
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // with the modules we asked for - "attribute" and "node"
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai });
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai</script>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The call to `YUI()` 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>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>To load the modules, we invoke `use()` and pass it the list of modules we'd like populated on our new YUI instance - in this case, `attribute` and `node`.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiThe YUI instance will pull down the source files for modules if they don't already exist on the page, plus any or their dependencies.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiWhen the source files are done downloading, the callback function which we pass in as the 3rd argument to `use()`, is invoked. Our custom YUI instance, `Y`, is passed to the callback, populated with the classes which make up the requested modules.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<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>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The configuration object passed to `YUI()` 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="{{apiDocs}}/YUI.html">YUI object</a>, provides more information about the configuration options available.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Defining Your Custom Class</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<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 `MyClass`.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiWe then augment `MyClass` with `Y.Attribute`, so that it receives all of `Attribute's` methods:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaifunction MyClass(cfg) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai ...
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai}
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiY.augment(MyClass, Y.Attribute);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Adding Attributes</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We can now set up any attributes we need for `MyClass` using the `addAttrs` method. For the basic example we add 3 attributes - `foo`,`bar`, and `foobar`, and provide an initial `value` for each.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiThe 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 `readOnly` or `writeOnce`, and define `getter`, `setter` and `validator` methods for the attribute.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>In this example, the default set of attributes which `MyClass` will support gets passed to `addAttrs` to set up the attributes for each instance during construction.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiThe complete definition for `MyClass` is shown below:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Setup custom class which we want to add managed attribute support to
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaifunction MyClass(cfg) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // When constructed, setup the initial attributes for the
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // instance, by calling the addAttrs method.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai var attrs = {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // Add 3 attributes, foo, bar and foobar
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai "foo" : {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai value:5
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai },
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai "bar" : {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai value:"Hello World!"
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai },
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai "foobar" : {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai value:true
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai }
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai };
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai this.addAttrs(attrs, cfg);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai}
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Augment custom class with Attribute
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiY.augment(MyClass, Y.Attribute);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The `addAttrs` 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 `cfg` argument above.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiAs 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.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Using Attributes</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Now that we have `MyClass` defined with a set of attributes it supports, users can get and set attribute values on instances of `MyClass`:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We construct the first instance, `o1`, without setting any initial attribute values in the constructor, but use Attribute's `set()` method to set values after construction:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Create a new instance, but don't provide any initial attribute values.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar o1 = new MyClass();
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Display current values
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaidisplayValues(o1, "o1 with default values, set during construction",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai "#createo1 .example-out");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai...
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Update values, using the "set" method
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaio1.set("foo", 10);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaio1.set("bar", "Hello New World!");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaio1.set("foobar", false);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaidisplayValues(o1, "o1 values updated using set, after construction",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai "#updateo1 .example-out");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>For the second instance that, `o2` we set the initial values of the attributes, using the constructor configuration argument:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar o2 = new MyClass({
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai foo: 7,
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai bar: "Aloha World!",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai foobar: false
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai});
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The `displayValues()` method uses Attribute's `get()` method to retrieve the current values of the attributes, to display:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaifunction displayValues(o, title, node) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai var str =
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai '<div class="myclass"><div class="myclass-title">'
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + title +
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai ':</div><ul class="myclass-attrs"><li>foo:'
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + o.get("foo")
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + '</li><li>bar:'
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + o.get("bar")
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + '</li><li>foobar:'
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + o.get("foobar")
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai + '</li></ul></div>';
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // Use the Y.one() method to get the first element which
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai // matches the selector passed in, to output the string to...
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai Y.one(node).set("innerHTML", str);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai}
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Complete Example Source</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai{{>attribute-basic-source}}
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai```