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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<style type="text/css" scoped>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Standard Module Widget CSS */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule-hidden {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai display:none;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin:10px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule-content {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:3px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:1px solid #666;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule-content .yui3-widget-hd {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:2px solid #aa0000;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai background-color:#fff;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai overflow:auto;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule-content .yui3-widget-bd {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:2px solid #0000aa;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai background-color:#fff;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai overflow:auto;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule-content .yui3-widget-ft {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:2px solid #00aa00;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai background-color:#fff;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai overflow:auto;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Positionable Widget CSS */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-positionable {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai position:absolute;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-positionable-content {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai text-align:center;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:1px solid #000;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai background-color:#999966;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:10px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-positionable-hidden {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai visibility:hidden;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Alignable Widget CSS */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-alignable {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai position:absolute;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-alignable-content {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai text-align:center;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai border:1px solid #000000;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai background-color:#004C6D;
e1aced3d7f8ff426bc0a9474125b04d9a3137eedSatyen Desai padding:1px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-alignable-hidden {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai visibility:hidden;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Example Layout CSS */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.widget-build-example {
f3433d94fc91602084922f6106e13e91bebdf6f6Satyen Desai border:1px solid #ccc;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai padding:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.widget-build-example button, .widget-build-example label, .widget-build-example select, .widget-build-example input {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin-right:5px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.widget-build-example button.fail {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai color:#cc0000;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai margin-left:10px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.widget-build-example .filler {
f3433d94fc91602084922f6106e13e91bebdf6f6Satyen Desai#widget-build-examples dd {
f3433d94fc91602084922f6106e13e91bebdf6f6Satyen Desai margin-left:0;
f3433d94fc91602084922f6106e13e91bebdf6f6Satyen Desai#widget-build-examples dt {
f3433d94fc91602084922f6106e13e91bebdf6f6Satyen Desai margin-bottom:1em;
f3433d94fc91602084922f6106e13e91bebdf6f6Satyen Desai margin-top:1em;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai#widget2-example, #widget3-example {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai height:15em;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai#widget2-example select, #widget3-example select {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai#alignment p {
e1aced3d7f8ff426bc0a9474125b04d9a3137eedSatyen Desai padding:2px;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai color:#dddd00;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<div class="intro">
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <p>This example shows how you can mix and match the `WidgetPosition`, `WidgetPositionAlign`, `WidgetStack` and `WidgetStdMod` extensions to build custom versions of the `Widget` class, using `Base.create`.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<div class="example">
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai {{>widget-build-source}}
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Creating Custom Widget Classes</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The `Base` class provides a `create` method which can be used to create custom versions of classes which derive from `Base` by adding extension classes to them.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Widget currently ships with four such extensions: `WidgetPosition`, `WidgetStack`, `WidgetPositionAlign` and `WidgetStdMod`.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiThese extensions are used to create the basic `Overlay` widget, but can also be used individually, to create custom versions of the base `Widget` class.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Widget with WidgetStdMod support</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Adding the `WidgetStdMod` extension to Widget, creates a statically positioned Widget, with support for standard module format sections - header, body and footer, which maybe useful in portal type use cases, where the positioning/stacking capabilities which come bundled with Overlay are not required.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>To create a custom class, we use <a href="{{apiDocs}}/Base.html#method_Base.create">`Base.create`</a>, which is described in detail on the documention page for <a href="../base/index.html#extensions">Base</a>.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We pass in `Widget` as the main class we want to add extensions to, and `WidgetStdMod` as the extension we'd like added to the main class:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar StandardModule = Y.Base.create("standardModule", Y.Widget, [Y.WidgetStdMod]);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Render from Markup
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar stdmod = new StandardModule({
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai contentBox: "#widget1",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai width:"12em",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai height:"12em"
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li>Create a new class which extends `Widget`</li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li>Aggregate known `Base` and `Widget` fields, such as `ATTRS` and `HTML_PARSER` from `WidgetStdMod` on the new class</li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li>Augment prototype methods from `WidgetStdMod` onto the new class prototype</li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The first argument to create is the `NAME` of the new class we are creating, just like the `NAME` we define when extending the Widget class directly.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Note that the `Widget` class is unchanged, allowing you to still create `Widget` instances without any standard module support, along with `StandardModule` instances which have standard module support.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Testing It Out</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The example attempts to set content on an instance of the newly created `StandardModule` class, using the `setStdModContent` method which is added by the extension (which would otherwise not exist on the Widget instance).</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar contentInput = Y.one("#content");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar sectionInput = Y.one("#section");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// This should work, since the StandardModule widget has settable
2c40caf14e175744abe5a7365b2404da0d871328Satyen DesaiY.on("submit", function(e) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai var content = Y.Escape.html(contentInput.get("value"));
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai var section = sectionInput.get("value");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai stdmod.setStdModContent(section, content);
2c40caf14e175744abe5a7365b2404da0d871328Satyen Desai}, "#widget1-example");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>To verify that no unrequested features are added, we also attempt to move the instance using the `move` method, which is not part of the base Widget class, and would be added by the `WidgetPosition` extension. This verifies that the other example classes we'll create, which do create new classes which use `WidgetPosition`, have not modified the base Widget class.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// This shoud fail, since the StandardModule widget is not positionable
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiY.on("click", function(e) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai } catch (e) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai alert("move() is " + typeof stdmod.move + ", stdmod.hasImpl(Y.WidgetPosition) : "
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai}, "#tryMove");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Note that `Base.create` adds a `hasImpl` method to the built class, which allows you to query whether or not it has a particular extension applied.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>CSS Considerations</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We need to define the CSS which goes with this new `StandardModule` class we have created. The only rule really required out of the box is the rule which handles visibility (`yui-standardmodule-hidden`). The "standardmodule" used in the class name comes from the `NAME` property we set up for the new class, and is used to prefix all state related classes added to the widgets bounding box.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiSince the `StandardModule` class is not positionable, we use `display:none` to define the `hidden` state.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Visibility - How to handle visibility for this new widget */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-standardmodule-hidden {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai display:none;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The other "yui-standardmodule" rules are only used to create the required look/feel for this particular example, and do not impact the StandardModule widget's functionality.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Widget with WidgetPosition and WidgetStack support</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>As with `StandardModule`, we use `Base.create` to create the new `Positionable` widget class. This time we add `WidgetPosition` and `WidgetStack` support to the base `Widget` class to create a basic XY positionable widget, with shimming and z-index support.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar Positionable = Y.Base.create("positionable", Y.Widget,
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Render from markup
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar positionable = new Positionable({
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai contentBox: "#widget2",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai width:"10em",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai height:"10em",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaipositionable.render("#widget2-example");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar xy = Y.one("#widget2-example > p").getXY();
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We <strong>don't</strong> add `WidgetPositionAlign` or `WidgetStdMod` support, so the widget doesn't have extended positioning support (align, center) or standard module support. Hence we position it manually using the `move` method which the `WidgetPosition` extension provides.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Testing It Out</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We should now be able to invoke the `move` method on an instance of the newly created `Positionable` class:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// This should work, since Positionable has basic XY Positioning support
2c40caf14e175744abe5a7365b2404da0d871328Satyen DesaiY.on("submit", function(e) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai var x = parseInt(xInput.get("value"));
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai var y = parseInt(yInput.get("value"));
2c40caf14e175744abe5a7365b2404da0d871328Satyen Desai}, "#widget2-example");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>And, as with the `StandardModule` class, we should not be allowed to invoke any methods from an extension which we didn't request:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// This should fail, since Positionable does not have Standard Module sections
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiY.on("click", function(e) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai positionable.setStdModContent("header", "new content");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai } catch (e) {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai alert("setStdModContent() is " + typeof positionable.setStdModContent +
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai ", positionable.hasImpl(Y.WidgetStdMod) : " + positionable.hasImpl(Y.WidgetStdMod));
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai}, "#tryContent");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>CSS Considerations</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Since now we have a positionable widget, with z-index support, we set the widget to be absolutely positioned by default, and control it's hidden state using `visibility` as opposed to `display`</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Define absolute positioning as the default for positionable widgets */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-positionable {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai position:absolute;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai In order to be able to position the widget when hidden, we define hidden
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai to use visibility, as opposed to display
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-positionable-hidden {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai visibility:hidden;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Widget with WidgetPosition, WidgetStack and WidgetPositionAlign support</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Lastly, we'll attempt to create a new widget class, which, in addition to basic positioning and stacking support, also has extended positioning support, allowing us to align it with other elements on the page.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>Again, we use `Base.create` to create our new `Alignable` widget class, by combining `WidgetPosition`, `WidgetStack` and `WidgetPositionAlign` with the base widget class:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar Alignable = Y.Base.create("alignable", Y.Widget,
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai [Y.WidgetPosition, Y.WidgetPositionAlign, Y.WidgetStack]);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaivar alignable = new Alignable({
e1aced3d7f8ff426bc0a9474125b04d9a3137eedSatyen Desai width:"14em",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai node: "#widget3-example",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai points: ["cc", "cc"]
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.get("contentBox").set("innerHTML",
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai '<strong>Alignable Widget</strong><div id="alignment"><p>#widget3-example</p> \
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <p>[center, center]</p></div>');
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.render("#widget3-example");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>Testing It Out</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>We'll attempt to align an instance of the `Alignable` class, using some of the additional attributes which `WidgetPositionAlign` adds to the base `Widget` class: `align` and `centered`:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Align left-center egde of widget to
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// right-center edge of the node with id "widget3-example"
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.set("align", {node:"#widget3-example", points:["lc", "rc"]});
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Align top-right corner of widget to
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// bottom-right corner of the node with id "widget3-example"
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.set("align", {node:"#widget3-example", points:["tr", "br"]});
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Center the widget in the node with id "widget3-example"
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.set("centered", "widget3-example");
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Align the right-center edge of the widget to
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// the right center edge of the viewport (since a node is not provided to 'align')
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.set("align", {points:["rc", "rc"]});
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Center the widget in the viewport (wince a node is not provided to 'centered')
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.set("centered", true);
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// Return the node to it's original alignment
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// (centered in the node with id "widget3-example")
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai// NOTE: centered is a shortcut for align : { points:["cc", "cc"] }
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desaialignable.set("align", {node:"#widget3-example", points:["cc", "cc"]});
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h3>CSS Considerations</h3>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The `Alignable` widget class, has the same core CSS rules as the `Positionable` class, to define how it is positioned and how it is hidden:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai/* Define absolute positioning as the default for alignable widgets */
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-alignable {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai position:absolute;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai In order to be able to position the widget when hidden, we define hidden
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai to use visibility, as opposed to display
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai.yui3-alignable-hidden {
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai visibility:hidden;
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<h2>Complete Example Source</h2>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai{{>widget-build-source}}