~ubuntu-branches/ubuntu/raring/maas/raring-updates

« back to all changes in this revision

Viewing changes to src/maasserver/static/jslibs/yui/3.4.1/docs/widget/index.html

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2012-07-03 17:42:37 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20120703174237-p8l0keuuznfg721k
Tags: 0.1+bzr709+dfsg-0ubuntu1
* New Upstream release
* debian/control:
  - Depends on python-celery, python-tempita, libjs-yui3-{full,min},
    libjs-raphael
* debian/maas.install:
  - Install apiclient, celeryconfig.py, maas-import-pxe-files, preseeds_v2.
  - Update to install various files from chroot, rather tha manually copy
    them from the source.
* debian/maas.links: symlink celeryconfig.py
* debian/maas.maas-celery.upstart: Add job.
* debian/rules:
  - Install celery upstart job.
  - Do not install jslibs as packages are now used.
  - Drop copying of maas_local_settings_sample.py as source now ships
    a maas_local_settings.py
* debian/patches:
  - 04-maas-http-fix.patch: Drop. Merged upstream.
  - 01-fix-database-settings.patch: Refreshed.
  - 99_enums_js.patch: Added until creation of enum.js / build process
    is fixed.
* debian/maas.postinst: Update bzr version to correctly handle upgrades.

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>Widget</title>
6
 
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
7
 
    <link rel="stylesheet" href="../assets/css/main.css">
8
 
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
9
 
    <script src="../../build/yui/yui-min.js"></script>
10
 
</head>
11
 
<body>
12
 
 
13
 
<div id="doc">
14
 
    <h1>Widget</h1>
15
 
 
16
 
    
17
 
        <a href="#toc" class="jump">Jump to Table of Contents</a>
18
 
    
19
 
 
20
 
    <div class="yui3-g">
21
 
        <div id="main" class="yui3-u">
22
 
            <div class="content"><div class="intro">
23
 
    <p><code>Widget</code> is the foundation class from which all YUI 3 widgets are derived. It provides the following pieces of core functionality on top of what <a href="../base/index.html">Base</a> already provides:</p>
24
 
    <ul>
25
 
        <li>Adds the <code>render</code> lifecycle moment, to <a href="../base/index.html">Base's</a> <code>init</code> and <code>destroy</code> moments</li>
26
 
        <li>Abstract rendering methods to promote a consistent MVC pattern across widgets</li>
27
 
        <li>A common set of widget attributes</li>
28
 
        <li>Consistent markup generation support</li>
29
 
        <li>Consistent class-name generation support</li>
30
 
        <li>Built-in progressive enhancement support</li>
31
 
    </ul>
32
 
</div>
33
 
 
34
 
<h2 id="responsibilities">What Widget Provides</h2>
35
 
 
36
 
<h3 id="structure">Class Structure And Responsibilities</h3>
37
 
 
38
 
<img src="../assets/widget/widget-class-diagram.png" alt="The widget class diagram" width="436" height="357">
39
 
 
40
 
<p><code>Widget</code> provides the foundation class on which all YUI 3 widgets will be built. 
41
 
Although instantiable and usable by itself, it is designed to be extended to create widgets which address
42
 
specific user interaction patterns.</p>
43
 
 
44
 
<p>The <code>Widget</code> class extends <a href="http://yuilibrary.com/yui/docs/api/Base.html"><code>Base</code></a>. Therefore it provides 
45
 
the same <code>Attribute</code>, <code>Event.Provider</code> and <code>Plugin.Host</code> support as <code>&lt;a href=&quot;..&#x2F;base&#x2F;index.html#extendbase&quot;&gt;Base&lt;&#x2F;a&gt;</code> does.
46
 
 
47
 
<p>It adds the following core functionality:</p>
48
 
 
49
 
<dl>
50
 
    <dt><strong>Basic Attributes</strong></dt> 
51
 
    <dd>It introduces a common set of attributes that will be available on any widget. 
52
 
    For example, <code>boundingBox</code>, <code>contentBox</code>, <code>width</code>, <code>height</code>, <code>visible</code>, <code>focused</code> and <code>disabled</code>.</dd>
53
 
 
54
 
    <dt><strong>Render Lifecycle Phase</strong></dt>
55
 
    <dd>It adds the <code>render</code> lifecycle method (and event) to the <code>init</code> and <code>destroy</code> 
56
 
    lifecycle methods provided by <code>Base</code>.</dd>
57
 
 
58
 
    <dt><strong>Abstract Rendering Methods</strong></dt> 
59
 
    <dd>It establishes abstract methods <code>renderUI</code>, <code>bindUI</code> and <code>syncUI</code> to 
60
 
    provide consistent entry points for rendering across all widgets.</dd>
61
 
 
62
 
    <dt><strong>Consistent Progressive Enhancement</strong></dt>
63
 
    
64
 
    <dd>It provides a common entry point for <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive Enhancement</a> during widget initialization and also provides
65
 
    the infrastructure to hide progressively enhanced markup to avoid flashes of unstyled content.</dd>
66
 
 
67
 
    <dt><strong>String Localization</strong></dt>
68
 
    <dd>The <code>strings</code> attribute provides client-side string localization support, which when used with the <a href="../intl/index.html">Internationalization</a> utility
69
 
    allows localized strings for your widget to be shipped separately from the core code.</dd>
70
 
</ul>
71
 
 
72
 
<h3 id="attributes">Basic Attributes</h3>
73
 
 
74
 
<p>Widget establishes a common set of attributes which will be available in all YUI 3 widgets. The core attributes are discussed below:</p>
75
 
 
76
 
<table>
77
 
    <tr><th>Attribute</th><th>Description</th></tr>
78
 
    <tr><td><code>boundingBox</code></td><td>The widget's outermost node, used for sizing and positioning; this element can also serve as a containing node for any decorator elements used for skinning.</td></tr>
79
 
    <tr><td><code>contentBox</code></td><td>A node that is a direct descendant of a widget's bounding box and houses its content. This will generally be the node that establishes the look and feel for the widget.</td></tr>
80
 
    <tr><td><code>srcNode</code></td><td>An existing node in the document provided by application developers when progressively enhancing existing markup to create the widget. By default, this resolves to the <code>contentBox</code>.</td></tr>
81
 
    <tr><td><code>tabIndex</code></td><td>The tabIndex, applied to the bounding box.</td></tr>
82
 
    <tr><td><code>focused</code></td><td>Flag, indicating if the widget currently has focus. <code>Widget</code> marks the bounding box with a "focused" class, but other than that the focus implementation is left to the specific widget class.</td></tr>
83
 
    <tr><td><code>disabled</code></td><td>Flag, indicating if the widget is disabled. <code>Widget</code> marks the bounding box with a "disabled" class, but other than that the disabled implementation is left to the specific widget class.</td></tr>
84
 
    <tr><td><code>visible</code></td><td>Flag, indicating whether or not the widget is visible. <code>Widget</code> marks the bounding box with a "hidden" class. The hidden implementation is left to the CSS delivered by the specific widget class (viz. whether or not the widget uses visibility, display or off screen positioning to actually hide the widget).</td></tr>
85
 
    <tr><td><code>height</code></td><td>String with units, or a number, representing the height of the widget. If a number is provided, the default unit, defined by <code>Widget</code>'s <code>DEF_UNIT</code>, property is used. The height is applied to the bounding box.</td></tr>
86
 
    <tr><td><code>width</code></td><td>String with units, or a number, representing the width of the widget. If a number is provided, the default unit, defined by <code>Widget</code>'s <code>DEF_UNIT</code>, property is used. The width is applied to the bounding box.</td></tr>
87
 
    <tr><td><code>strings</code></td><td>The collection of strings used to label elements of the widget's UI.</td></tr>
88
 
</table>
89
 
 
90
 
<h3 id="rendering">Rendering Methods</h3>
91
 
 
92
 
<p><code>Widget</code> adds the <code>render</code> method/lifecycle phase to the 
93
 
<code>init</code> and <code>destroy</code> phases established by Base.</p>
94
 
 
95
 
<p>
96
 
The <code>render</code> method establishes the point at which the widget lays down its UI by adding elements to (or modifying existing elements in) the DOM and 
97
 
setting up listeners to activate that UI. Having a distinct rendering phase promotes widget classes that separate state and corresponding logic 
98
 
from the way the widget UI is displayed. This separation tends to allow the widget's state to be safely modified and queried before it is displayed or rendered to the DOM.
99
 
</p>
100
 
 
101
 
<p>Additionally, this separation of concerns leads to code being split into methods that manipulate the widget's state or handle core "app" logic versus methods which work with the DOM.  
102
 
Following this practice makes it easier to customize and test one area or the other.</p>
103
 
 
104
 
<h4 id="the-lifecycle-methods-init-destroy-render">The Lifecycle Methods: <code>init, destroy, render</code></h4>
105
 
 
106
 
<p>As with <code>init</code> and <code>destroy</code>, the <code>render</code> method on <code>Widget</code> is final and delegates to the 
107
 
widget implementation's <code>renderer</code> method to perform the actual rendering work:</p>
108
 
 
109
 
<dl>
110
 
    <dt><a href="http://yuilibrary.com/yui/docs/api/Base.html#method_init"><code>init</code></a> <em>(inherited from <code>Base</code>)</em>:</dt>
111
 
    <dd>
112
 
        <p>
113
 
        The <code>init</code> method loops through the class hierarchy, top down (Base first, subclass last) and:
114
 
        </p>
115
 
        <ul>
116
 
            <li>Configures attributes for each class, based on the class' <code>ATTRS</code> static property.</li>
117
 
            <li>Then, invokes the <code>initializer</code> method for the class.</li>
118
 
        </ul>
119
 
        <p>The <code>init</code> method fires an <code>init</code> event, which can be prevented to stop initialization from proceeding.</p>
120
 
    </dd>
121
 
</dl>
122
 
<dl>
123
 
    <dt><a href="http://yuilibrary.com/yui/docs/api/Base.html#method_destroy"><code>destroy</code></a> <em>(inherited from <code>Base</code>)</em>:</dt>
124
 
    <dd>
125
 
        <p>Invokes the <code>destructor</code> method for all classes in the widget hierarchy, bottom up (subclass first, Base last).</p>
126
 
        <p>The <code>destroy</code> method fires a <code>destroy</code> event, which can be prevented to stop destruction from proceeding.</p>
127
 
    </dd>
128
 
</dl>
129
 
<dl>
130
 
    <dt><a href="http://yuilibrary.com/yui/docs/api/Widget.html#method_render"><code>render</code></a>:</dt>
131
 
    <dd>
132
 
        <p>Invokes the <code>renderer</code> method for the Widget instance. Unlike the <code>initializer</code> and <code>destructor</code>, this method 
133
 
        is not chained automatically for the widget's class hierarchy.</p>
134
 
        
135
 
        <p>
136
 
        The <code>render</code> method accepts a <code>parentNode</code> argument, which can be used to specify an existing node in the document, where the widget should be appended, when rendered.
137
 
        If the widget's contentBox or boundingBox don't already exist in the document, and the <code>parentNode</code> argument is not provided, the widget is inserted as the first child of the document's body element (we <em>insert</em> as the default behavior, to avoid IE6 "Operation Aborted" errors).
138
 
        </p>
139
 
 
140
 
        <p>The <code>render</code> method fires a <code>render</code> event, which can be prevented to stop rendering from proceeding.</p>
141
 
    </dd>
142
 
</dl>
143
 
 
144
 
<h4 id="widgets-renderer-method">Widget's <code>renderer</code> Method</h4>
145
 
 
146
 
<p>Widget provides a <a href="http://yuilibrary.com/yui/docs/api/Widget.html#method_renderer"><code>renderer</code></a> method implementation, which for most simple widgets will not need to be over-ridden.
147
 
This <code>renderer</code> method is shown below:</p>
148
 
 
149
 
<pre class="code prettyprint">renderer: function() {
150
 
    this.renderUI();
151
 
    this.bindUI();
152
 
    this.syncUI();
153
 
}</pre>
154
 
 
155
 
 
156
 
<p>
157
 
The <code>renderUI</code>, <code>bindUI</code> and <code>syncUI</code> are abstract (empty) methods in the <code>Widget</code> class which attempt to establish a common pattern for widget development.
158
 
The intended role of each of these methods is described below, and most widgets will simply implement these methods based on their expected roles:
159
 
</p>
160
 
 
161
 
<dl>
162
 
    <dt><a href="http://yuilibrary.com/yui/docs/api/Widget.html#method_renderUI"><code>renderUI</code></a></dt>
163
 
    <dd>This method is responsible for creating and adding the nodes which the widget needs into the document (or modifying existing nodes, in the case of progressive enhancement).
164
 
    It is usually the point at which the DOM is first modified by the widget.</dd>
165
 
</dl>
166
 
<dl>
167
 
    <dt><a href="http://yuilibrary.com/yui/docs/api/Widget.html#method_bindUI"><code>bindUI</code></a></dt>
168
 
    <dd>This method is responsible for attaching event listeners which bind the UI to the widget state. 
169
 
    These listeners are generally attribute change listeners &mdash; used to update the state of the UI in response to changes in the attribute's value.
170
 
    It also attaches DOM event listeners to the UI to map user interactions to the widget's API.</dd>
171
 
</dl>
172
 
<dl>
173
 
    <dt><a href="http://yuilibrary.com/yui/docs/api/Widget.html#method_syncUI"><code>syncUI</code></a></dt>
174
 
    <dd>This method is responsible for setting the initial state of the UI based on the current state of the widget at the time of rendering.</dd>
175
 
</dl>
176
 
 
177
 
<h3 id="progressive">Progressive Enhancement</h3>
178
 
 
179
 
<p>The <code>Widget</code> class establishes a standard entry point for widgets that need to provide support for <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive Enhancement</a>; this entry point is provided in the form of an <code>HTML_PARSER</code> property on each class.</p>
180
 
 
181
 
<p><a href="http://yuilibrary.com/yui/docs/api/Widget.html#property_Widget.HTML_PARSER"><code>HTML_PARSER</code></a> is a static property, used to define a hash of selectors or functions that are responsible for (a) parsing content for the widget from existing DOM elements and (b) extracting attribute configuration values for use during initialization.</p>
182
 
 
183
 
<pre class="code prettyprint">MyWidget.HTML_PARSER = {
184
 
 
185
 
     &#x2F;&#x2F; Set attributes which are Node references 
186
 
     &#x2F;&#x2F; using selector syntax (uses node.one())
187
 
     titleNode: &quot;span.yui3-title&quot;,
188
 
 
189
 
     &#x2F;&#x2F; Set attributes which are multiple Node references 
190
 
     &#x2F;&#x2F; using selector syntax (uses node.all()) 
191
 
     itemNodes: [&quot;li.yui3-listitem&quot;],
192
 
 
193
 
     &#x2F;&#x2F; Set attributes using a parse function. Execution context 
194
 
     &#x2F;&#x2F; is set to the widget instance
195
 
     label: function(srcNode) {    
196
 
        return srcNode.one(&quot;input.yui3-title&quot;).get(&quot;innerHTML&quot;);
197
 
     },
198
 
 
199
 
     xValue: function(srcNode) {
200
 
         return srcNode.one(&quot;input.yui3-slider-xvalue&quot;).get(&quot;value&quot;);
201
 
     },
202
 
 
203
 
     yValue: function(srcNode) {
204
 
         return srcNode.one(&quot;input.yui3-slider-yvalue&quot;).get(&quot;value&quot;);
205
 
     }
206
 
};</pre>
207
 
 
208
 
 
209
 
<p>The <code>HTML_PARSER</code> property is evaluated when the Widget class' <code>initializer</code> method is invoked (so Widget sub-classes receive the configuration
210
 
object passed into the constructor). The object is iterated, to create a filled out configuration object for the widget, based on the content the user points to using the <code>srcNode</code> attribute. 
211
 
For example, the parser definition above may lead to the following object literal when evaluated:</p>
212
 
 
213
 
<pre class="code prettyprint">{
214
 
    titleNode: NodeRef,
215
 
    itemNodes: NodeListRef (multiple nodes),
216
 
    label: &quot;My Widget&quot;,
217
 
    xValue: &quot;10&quot;,
218
 
    yValue: &quot;20&quot;
219
 
}</pre>
220
 
 
221
 
 
222
 
<p>This object is merged with the user configuration object passed into the constructor (markup can be thought of as alternate source/format for configuration data), with the configuration object passed to the widget constructor taking precedence if a value for an attribute is found in both places.</p>
223
 
 
224
 
<h4 id="hidingmarkup">Hiding Progressively Enhanced Markup</h4>
225
 
 
226
 
<p>In addition to providing a common entry point for progressively enhanced solutions through the <code>HTML_PARSER</code>, Widget also provides the CSS hooks you need to initially hide content which will be progressively enhanced.</p>
227
 
 
228
 
<ol>
229
 
    <li> If JavaScript <em>is not</em> enabled the content provided by the markup for the widget, should be visible and accessible.</li>
230
 
    <li> If JavaScript <em>is enabled</em>, the widget source markup should be hidden as early as possible, to avoid the user seeing the flash of 
231
 
    unstyled content while the widget's JavaScript and CSS components are delivered to the page and the widget is rendered.</li>
232
 
    <li> Once the widget is fully rendered it should then be displayed.</li>
233
 
</ol>
234
 
 
235
 
<p>In order to make this happen:</p>
236
 
 
237
 
<ul>
238
 
    <li> <p>The <a href="../yui/index.html">YUI</a> seed file will stamp the documentElement (the &lt;HTML&gt; element) with a class of <code>&#x27;yui3-js-enabled&#x27;</code>.</p></li>
239
 
    <li> <p>Application developers can then add a class name representing the &quot;loading&quot; state, to the widget's content (e.g. <code>&#x27;yui3-widget-loading&#x27;</code>).</p><p>This class can be used in combination with the &quot;yui3-js-enabled&quot; class name to 
240
 
         create style rules to hide the widget content while its JavaScript is being loaded.</p>
241
 
 
242
 
         <p>                    
243
 
<pre class="code prettyprint">.yui3-js-enabled .yui3-widget-loading {
244
 
   display: none;
245
 
}
246
 
        
247
 
.yui3-js-enabled .yui3-overlay-loading {
248
 
   &#x2F;* Hide overlay markup offscreen *&#x2F;
249
 
   position:absolute;
250
 
   top:-1000em;
251
 
   left:-1000em;
252
 
}</pre>
253
 
 
254
 
         </p>
255
 
 
256
 
         <p>As shown in the example above, there is support for use of both a generic widget and type-specific widget class name by default (&quot;yui3-widget-loading&quot; and &quot;yui3-tabview-loading&quot;).</p>
257
 
    </li>
258
 
    <li> <p>Widget's renderer will remove the &quot;loading&quot; class names from both the bounding box and content box once the widget is rendered, allowing the fully functional widget to be revealed.</p></li>
259
 
</ul>
260
 
 
261
 
<h3 id="markup">Rendered Markup</h3>
262
 
 
263
 
<p>The <code>Widget</code> class establishes a common markup format for all widgets, through its <a href="http://yuilibrary.com/yui/docs/api/Widget.html#config_boundingBox"><code>boundingBox</code></a> and 
264
 
<a href="http://yuilibrary.com/yui/docs/api/Widget.html#config_contentBox"><code>contentBox</code></a> attributes.</p>
265
 
 
266
 
<p>
267
 
    Most widgets will have a bounding box wrapping a content box. They are both <code>DIV</code>s by default but can be customized by overriding the <code>BOUNDING_TEMPLATE</code> and <code>CONTENT_TEMPLATE</code> prototype properties.
268
 
    However, the widget developer can also specify the <code>CONTENT_TEMPLATE</code> to be null, if their widget implementation does not require a two-box structure. In this case, both the boundingBox and contentBox attributes will point to the same node.
269
 
</p>
270
 
 
271
 
<p>
272
 
    The widget will create either of the nodes if they are not provided in the constructor, and add them to the document when the widget's <code>render</code> method is called. 
273
 
    As mentioned previously, if the <code>render</code> method is passed a node reference, the widget's bounding box is appended to that node.
274
 
</p>
275
 
 
276
 
<h4 id="the-bounding-box">The Bounding Box</h4>
277
 
 
278
 
<p>The bounding box is the outermost element owned by the widget and is used for functional, rather than visual, purposes.</p>
279
 
 
280
 
<ul class="topiclist">
281
 
    <li><p class="topic">A class name identifying the widget is added to the bounding box.</p>
282
 
        <p>The default format for the class name is "yui3-[widgetname]". For example, for Slider, the "yui3-slider" class name is added to the bounding box.</p>
283
 
    </li>
284
 
    <li><p class="topic">Additionally, class names for all widget classes in the class hierarchy are also used to tag the bounding box.</p>
285
 
        <p>For example, for a MultiThumbSlider, which may extend Slider, the bounding box is marked with the classes "yui3-widget", "yui3-slider" and "yui3-multithumbslider" (this is the only place where we mark an element with class names for all widget classes in the hierarchy).</p>
286
 
    </li>
287
 
    <li>
288
 
        <p class="topic">Class names used for state management by the widget instance are also applied to the bounding box.</p>
289
 
        <p>The general format is "yui3-[widgetname]-[state]". For example "yui3-slider-hidden", "yui3-slider-disabled".</p>
290
 
    </li>
291
 
    <li>
292
 
        <p class="topic">The widget's width and height values are applied to the bounding box if set, as are top/left (xy) positioning values, for positioned widgets.</p>
293
 
    </li>
294
 
    <li>
295
 
        <p class="topic">The bounding box is not expected to have any visual properties (e.g. borders, padding, etc.) applied to it.</p>
296
 
        <p>However it will have CSS defining how the widget impacts the document flow. For example, the bounding box type ("display:inline", "display:inline-block", "display:block") and the positioning scheme ("position:absolute", "position:relative").</p>
297
 
    </li>
298
 
</ul>
299
 
 
300
 
<h4 id="the-content-box">The Content Box</h4>
301
 
 
302
 
<p>The content box is a child of the bounding box. The widget will add the elements which make up its core UI inside the content box.</p>
303
 
 
304
 
<ul class="topiclist">
305
 
    <li>
306
 
        <p class="topic">The content box also has an identifying class name applied to it.</p>
307
 
        <p>The default format is "yui3-[widgetname]-content". For example "yui3-slider-content".</p>
308
 
    </li>
309
 
    <li><p class="topic">Visual treatment for the widget is applied to the content box (e.g. borders, padding, background-color, etc.).</p></li>
310
 
    <li>
311
 
        <p class="topic">For progressively enhanced solutions, generally the application developer will only provide what will be the content box on the page and pass it into the constructor as the <code>srcNode</code> (rather than the bounding box).</p> 
312
 
        <p>The bounding box will be added dynamically when the widget is instantiated. This maintains semantic value (the content box ends up containing existing content), and avoids unnecessary markup on the page up front.</p>
313
 
    </li>
314
 
</ul>
315
 
 
316
 
<h4 id="widget-markup-diagram">Widget Markup Diagram</h4>
317
 
            
318
 
<p>The following illustration demonstrates how the markup and class names for a widget's bounding box and content box come together.</p>
319
 
 
320
 
<img src="../assets/widget/widget-dom.png" height="357" width="524" alt="Illustration of the two-box DOM layout for a widget.">
321
 
 
322
 
<h4 id="why-two-nested-boxes">Why Two Nested Boxes?</h4>
323
 
 
324
 
<p>Providing nested boxes for all widgets provides benefits for CSS application, decorative element support and bounding box dimension handling. These are detailed below:</p>
325
 
 
326
 
<ul>
327
 
    <li>The nested structure allows the bounding box to act as a container for any additional decorator elements which need to be added for the widget, for example, elements which support rounded-corners, shadows, or shimming. These can live as siblings of the content box, and can be positioned and sized more efficiently since they have a common parent container.</li>
328
 
    <li>Additionally, due to the consistent structure across all widgets, generic plugins can be written to provide the above decorator support, which are re-usable across all widgets.</li>
329
 
    <li>Having a box without border and padding applied (the bounding box) allows for consistent width and height application across browser box model differences.</li>
330
 
</ul>
331
 
 
332
 
<h3 id="CSS">Class Names and CSS</h3>
333
 
 
334
 
<p>In order to provide consistent class names for use across all widgets, the <code>Widget</code> class provides two methods which are simple wrappers for the <code>ClassNameManager</code> utility, and leverage the <code>NAME</code> property defined for widget classes.</p>
335
 
 
336
 
<dl>
337
 
    <dt>Instance Method: <code>getClassName(arg1, arg2, arg3 ...)</code></dt>
338
 
    <dd>
339
 
        <p>This method can be used to create class names which begin with the configured prefix for the application ("yui3-" by default) and the name of the widget (the <code>NAME</code> property, lowercase). For example:</p>
340
 
 
341
 
<pre class="code prettyprint">&#x2F;&#x2F; A method on a Spinner widget instance, 
342
 
&#x2F;&#x2F; with Spinner.NAME = &quot;spinner&quot;;
343
 
renderSpinnerButton: function() {
344
 
    &#x2F;&#x2F; generates the class name &quot;yui3-spinner-increment-major&quot;
345
 
    var btnClassName = this.getClassName(&quot;increment&quot;, &quot;major&quot;);
346
 
}</pre>
347
 
 
348
 
 
349
 
        <p><strong>Note:</strong> The <code>ClassNameManager.getClassName(arg1, arg2, arg3 ...)</code> method can be used as a replacement for the above method, when class names need to be generated in a static context, by passing in the widget implementation's <code>NAME</code> property as the first argument. For example:</p>
350
 
        
351
 
<pre class="code prettyprint">&#x2F;&#x2F; Generates the class name &quot;yui3-spinner-button&quot;
352
 
Spinner.BUTTON_TEMPLATE = Y.ClassNameManager.getClassName(
353
 
                                        Spinner.NAME, &quot;button&quot;);</pre>
354
 
 
355
 
 
356
 
    </dd>
357
 
 
358
 
    <dt>Static Method: <code>Widget.getClassName(arg1, arg2, arg3 ....)</code></dt>
359
 
 
360
 
    <dd>
361
 
        <p>
362
 
        This static version of the method (invoked directly on the <code>Widget</code> class, as opposed to "<code>this</code>") can be used to create class names which begin with a "yui3-widget" prefix. This maybe useful for plugins, which need to ship with CSS which targets a fixed class name, regardless of the widget instance to which they are applied.
363
 
        For example:
364
 
        </p>
365
 
 
366
 
<pre class="code prettyprint">&#x2F;&#x2F; generates the class name &quot;yui3-widget-shim&quot;
367
 
Widget.getClassName(&quot;shim&quot;);</pre>
368
 
 
369
 
 
370
 
    </dd>
371
 
</dl>
372
 
 
373
 
<p>If, as a custom widget developer, you want to override the default prefix (<code>yui3-[widgetname]</code>), you can define a static <code>CSS_PREFIX</code> property on your
374
 
widget's constructor function and CSS classnames will be prefixed with the value you set <code>CSS_PREFIX</code> to.</p>
375
 
 
376
 
<pre class="code prettyprint">&#x2F;&#x2F; Define a custom css prefix
377
 
MyWidget.CSS_PREFIX = &quot;myapp-common&quot;;
378
 
 
379
 
&#x2F;&#x2F; Inside your widget code:
380
 
_renderUI : function() {
381
 
    &#x2F;&#x2F; Generates the class name &quot;myapp-common-selected&quot;, 
382
 
    &#x2F;&#x2F; instead of &quot;yui3-mywidget-selected&quot;
383
 
    var selectedClassName = this.getClassName(&quot;selected&quot;);
384
 
}</pre>
385
 
 
386
 
 
387
 
<h4 id="css-implications">CSS Implications</h4>
388
 
 
389
 
<p>As a best practice, Widget avoids using the <code>style</code> attribute to control state such as "visible", "disabled" or "focused". Instead it marks the bounding box with class names which reflect the state:</p>
390
 
 
391
 
<table>
392
 
    <tr>
393
 
        <th>Attribute/State</th>
394
 
        <th>CSS Class Applied</th>
395
 
    </tr>
396
 
    <tr>
397
 
        <td>visible</td>
398
 
        <td>yui3-[widgetname]-hidden</td>
399
 
    </tr>
400
 
    <tr>
401
 
        <td>disabled</td>
402
 
        <td>yui3-[widgetname]-disabled</td>
403
 
    </tr>
404
 
    <tr>
405
 
        <td>focused</td>
406
 
        <td>yui3-[widgetname]-focused</td>
407
 
    </tr>
408
 
</table>
409
 
 
410
 
<p>In the above definitions, "[widgetname]" is the name of the widget (e.g. "menu", "overlay", "slider"). 
411
 
 
412
 
The widget name is combined with the state identifier so that different widgets can customize the way they handle visibility differently, and still work with IE6, 
413
 
where multiple class name rules, like <code>.yui3-menu.yui3-hidden</code> are not well supported. For example:
414
 
</p>
415
 
 
416
 
<pre class="code prettyprint">&#x2F;* Hide by positioning off-screen *&#x2F;
417
 
.yui3-menu-hidden {
418
 
    top:-10000em;
419
 
    left:-10000em;
420
 
}
421
 
 
422
 
&#x2F;* Hide by flipping visibility *&#x2F;
423
 
.yui3-overlay-hidden {
424
 
    visibility:hidden;
425
 
}
426
 
 
427
 
&#x2F;* Hide by flipping display *&#x2F;
428
 
.yui3-slider-hidden {
429
 
    display:none;
430
 
}</pre>
431
 
 
432
 
 
433
 
<p>
434
 
However, providing an IE6-compatible format requires each widget to ship with the CSS rules defined for each of its states.
435
 
Of the state-based rules above, all widgets will definitely end up providing a "yui3-[widgetname]-hidden" implementation to control visibility.
436
 
Whether or not CSS rules for the the other two states are provided is usually a function of whether or not the widget needs special UI handled for the "disabled" and "focused" states.
437
 
</p>
438
 
 
439
 
<h3 id="uievents">Default UI Events</h3>
440
 
 
441
 
<p>
442
 
Widget publishes and fires custom events for any DOM events (<code>&quot;click&quot;</code>, <code>&quot;mousever&quot;</code> etc.) which get fired inside its bounding box. 
443
 
Like all other Widget custom events, these events are prefixed with the widget's name (e.g. 'menuitem:click') and 
444
 
the default context of the event listener will be the widget that fired the event (as opposed to the Node firing the DOM event). 
445
 
These events provide application developers the ability to listen for UI events as part of the logical widget API, without having to be concerned with the DOM elements which make up the widget's UI.
446
 
</p>
447
 
 
448
 
<p>Since these are events that many Widget instances are going to want to publish and fire, Widget does this by default to ensure that these events are fired in a performant, consistent way across Widget implementations.</p>
449
 
 
450
 
<ul>
451
 
    <li>
452
 
        <p>
453
 
        Widget developers don't have to explicitly publish a given UI event in 
454
 
        order for Widget consumers to listen for them.
455
 
        </p>
456
 
        <p>
457
 
        For performance, these events are only created when someone is listening, and the actual firing of these events is facilitated by a 
458
 
        single, delegated DOM event listener.
459
 
        </p>
460
 
    </li>
461
 
    <li>
462
 
        <p>Widget developers can still choose to publish any given UI event in order to 
463
 
        explicitly control some aspect of the event.</p> 
464
 
        
465
 
        <p>
466
 
        The most likely use case is the desire to provide the default implementation/handler for a given 
467
 
        event. For example: a developer might want to publish a <code>&quot;click&quot;</code> event 
468
 
        for a Menu widget with the goal of providing the default click 
469
 
        behavior/function.
470
 
        </p>
471
 
    </li>
472
 
    <li>
473
 
        <p>
474
 
        The set of DOM events published by widget is defined by the 
475
 
        UI_EVENTS prototype property.</p>
476
 
        
477
 
        <p>
478
 
        This property defaults to <a href="http://yuilibrary.com/yui/docs/api/Node.html#property_DOM_EVENTS"><code>Node.DOM_EVENTS</code></a>.
479
 
        Widget developers can use this property to pare down or extend the number of events that are published and fired automatically.
480
 
        </p>
481
 
    </li>
482
 
</ul>
483
 
 
484
 
<h2 id="creatingwidgets">Developing Your Own Widgets</h2>
485
 
 
486
 
<p>To create your own widget, you'll create a class which extends <code>Widget</code> and implements the properties and methods shown in the diagram below:</p>
487
 
 
488
 
<p><img src="../assets/widget/widget-template-diagram.png" alt="Illustration of the code template for a custom widget, showing the ATTRS property and initializer, destructor, renderUI, bindUI and syncUI methods" width="446" height="412"></p>
489
 
 
490
 
<p>The best place to start is by defining the attributes which make up your widget (the <code>ATTRS</code> static property). These will help define the state and API which your widget exposes to the application developer. 
491
 
You can then implement the <code>initializer</code>, <code>destructor</code>, <code>renderUI</code>, <code>bindUI</code> and <code>syncUI</code> methods, based on the responsibilities defined for them above, 
492
 
along with the methods which support the attribute state handling and API.</p>
493
 
 
494
 
<p>
495
 
The <a href="widget-extend.html">"Extending The Widget Class"</a> example walks you through the step-by-step process involved in implementing a Spinner widget using this template structure. The example along with the template file should provide a good jumping off point for developing your own widgets.
496
 
</p>
497
 
 
498
 
<p>Additionally, the template structure shown above is captured in this <a href="../assets/widget/mywidget.js.txt">"MyWidget" template file</a>, which you can use as a starting point to develop your own widgets.</p>
499
 
 
500
 
<h2 id="pluginsandextensions">Plugins And Extensions</h2>
501
 
 
502
 
<p>
503
 
In addition to being able to subclass any given Widget class to provide custom widget implementations, YUI 3 also provides two additional code reuse mechanisms which can be used to 
504
 
package and reuse code to provide new widgets features, without being bound to a static all-or-nothing class hierarchy.
505
 
 
506
 
These code reuse mechanisms are known as <a href="../base/#plugins"><em>Plugins</em></a> and <a href="../base/#extensions"><em>Extensions</em></a> and support for both of them is provided through Base.</p>
507
 
 
508
 
<p>Generally widget developers should aim to provide the core set of features or functionality for any widget by sub-classing <code>Widget</code> or an existing class derived from <code>Widget</code> using <code>Y.extend</code>.</p>
509
 
 
510
 
<p>Additional incremental features or functionality should be packaged into extensions or plugins so they can be reused across classes (in the case of extensions), or instances (in the case of plugins).</p>
511
 
 
512
 
<h3 id="pluginorextension">Plugin or Extension?</h3>
513
 
 
514
 
<p>The question about whether a given piece of incremental functionality should be a Plugin or an Extension comes up frequently, and it's a design decision widget developers need to consider based on use cases for their widget.</p>
515
 
 
516
 
<p>As mentioned above, both Plugins and Extensions provide a mechanism to write and deliver atomic, incremental pieces of functionality which add to the core implementation. Where they differ is discussed below:</p>
517
 
 
518
 
<dl>
519
 
    <dt>Extensions - A Class Level Concept</dt>
520
 
    <dd>
521
 
        <ul>
522
 
            <li><p>Extensions provide features which can be mixed and matched at the <strong>class</strong> level.</p></li> 
523
 
            
524
 
            <li><p>Extensions are used by <strong>widget developers</strong> to create new widget <strong>classes</strong> which share the extension functionality.</p></li>
525
 
 
526
 
            <li><p>If it contains functionality which is not optional for the class, it's an extension.</p>
527
 
                <p>Something baked into the class, but implemented so that it can also be re-used to build other classes.</p></li>
528
 
 
529
 
            <li>
530
 
                <p><a href="widget-parentchild-listbox.html">WidgetParent, WidgetChild</a> and <a href="widget-tooltip.html">WidgetPosition, WidgetStack</a> are good examples of extensions.</p>
531
 
                <p>
532
 
                A <code>Tree</code> widget class always needs Parent/Child support. However, so does a <code>Menu</code> widget class. 
533
 
                We want to reuse the Parent/Child support across both classes, without forcing them to extend a shared base class. 
534
 
                Additionally, the Parent/Child functionality is a required for both classes; it is not optional.
535
 
                </p>
536
 
            </li>
537
 
 
538
 
            <li><p>Extensions are applied to a <strong>class</strong> using the static <code>Base.build</code> method (or the <code>Base.create</code> or <code>Base.mix</code> sugar methods which sit on top of <code>Base.build</code>).</p></li>
539
 
        </ul>
540
 
    </dd>
541
 
    <dt>Plugins - An Instance Level Concept</dt>
542
 
    <dd>
543
 
        <ul>
544
 
            <li><p>Plugins provide features which can be mixed and matched at the <strong>instance</strong> level.</p></li>
545
 
 
546
 
            <li><p>Plugins are used by <strong>application developers</strong> to apply features to certain <strong>instances</strong> of a widget.</p></li>
547
 
            
548
 
            <li><p>If it contains functionality which is not required for <em>all</em> instances of the class, it's a plugin.</p>
549
 
                <p>A feature which you may only want to apply to one instance, out of the ten instances of your widget on a page, is a plugin.</p></li>
550
 
 
551
 
            <li>
552
 
                <p>The <a href="../overlay/overlay-anim-plugin.html">Animation</a> and <a href="../overlay/overlay-io-plugin.html">IO</a> plugin examples are good use cases.</p>
553
 
 
554
 
                <p>
555
 
                You don't want to have to bake Animation or IO support into a class (potentially resulting in the need to ship <code>MyAnimatedWidget</code>, <code>MyIOEnabledWidget</code>, <code>MyAnimatedAndIOEnabledWidget</code> and <code>MyWidget</code> classes). 
556
 
                The functionality is optional and can be plugged into just the <em>instances</em> of the single <code>MyWidget</code> class which need them.
557
 
                </p>
558
 
            </li>
559
 
 
560
 
            <li><p>Plugins are applied to an <strong>instance</strong> using the instance's <code>plug</code> method.</p></li>
561
 
        </ul>
562
 
    </dd>
563
 
</dl>
564
 
 
565
 
<h3 id="extensions">Widget Extensions</h3>
566
 
 
567
 
<p>As you start to develop widgets in YUI 3, there are a number of extensions packaged as part of the library which you can use with <code>Base.build</code> (or <code>Base.create, Base.mix</code>) to add functionality to your custom widget classes:</p>
568
 
 
569
 
<table>
570
 
    <tr>
571
 
        <th width="30%">Extension</th>
572
 
        <th>Functionality</th>
573
 
    </tr>
574
 
    <tr>
575
 
        <td>widget-position</td>
576
 
        <td>Adds XY positioning support to the class.</td>
577
 
    </tr>
578
 
    <tr>
579
 
        <td>widget-position-align</td>
580
 
        <td>Adds XY aligned positioning support to the class.</td>
581
 
    </tr>
582
 
    <tr>
583
 
        <td>widget-position-constrain</td>
584
 
        <td>Adds constrained XY positioning support to the class.</td>
585
 
    </tr>
586
 
    <tr>
587
 
        <td>widget-stack</td>
588
 
        <td>Adds stacking (zIndex) support to the class.</td>
589
 
    </tr>
590
 
    <tr>
591
 
        <td>widget-stdmod</td>
592
 
        <td>Adds Standard Module (header, body, footer) support to the class.</td>
593
 
    </tr>
594
 
    <tr>
595
 
        <td>widget-parent</td>
596
 
        <td>Adds support to allow the widget to contain, manage and select child widgets.</td>
597
 
    </tr>
598
 
    <tr>
599
 
        <td>widget-child</td>
600
 
        <td>Adds support to allow the widget to be contained within a widget parent.</td>
601
 
    </tr>
602
 
    <tr>
603
 
        <td>widget-buttons</td>
604
 
        <td>Adds header/footer buttons support to a widget that implements the <code>WidgetStdMod</code> extension.</td>
605
 
    </tr>
606
 
    <tr>
607
 
        <td>widget-autohide</td>
608
 
        <td>Adds support to hide the widget when certain DOM events occur.</td>
609
 
    </tr>
610
 
    <tr>
611
 
        <td>widget-modality</td>
612
 
        <td>Adds support for modality to widgets.</td>
613
 
    </tr>
614
 
</table>
615
 
 
616
 
<p>The functionality provided by the <code>widget-parent</code> and <code>widget-child</code> extensions, allowing widget developers to build nested widgets, is worth discussing in a little more detail:</p>
617
 
 
618
 
<dl>
619
 
        <dt>widget-parent</dt>
620
 
        <dd>Adds support to allow the widget to contain, manage and select child widgets:
621
 
            <ul>
622
 
                <li>
623
 
                    <p>It provides a consistent API for creating parent/child relationships:</p>
624
 
 
625
 
<pre class="code prettyprint">parent.add(child, n);
626
 
parent.remove(n);</pre>
627
 
 
628
 
 
629
 
                </li>
630
 
                <li><p>These can be single level relationships (e.g. Tabs in a TabList, or Buttons in a Toolbar) or nested hierarchical relationships (e.g. Menus and MenuItems, or Trees and TreeNodes).</p></li>
631
 
                <li><p>Parents are automatically set up as event targets for their children's events, allowing you to leverage custom event bubbling to listen for events higher up in the hierarchy.</p></li>
632
 
                <li><p>Parents automatically render their children when rendered.</p></li> 
633
 
                <li>
634
 
                    <p>Widget Parent augments the <a href="http://yuilibrary.com/yui/docs/api/ArrayList.html">ArrayList API</a>, providing a full range of iteration and traversal methods for it's children:</p>
635
 
 
636
 
<pre class="code prettyprint">parent.each(function(child) {...});
637
 
parent.item(n);
638
 
parent.indexOf(child);
639
 
parent.size();</pre>
640
 
 
641
 
 
642
 
                </li>
643
 
                <li><p>It also provides selection support, including support for non-binary selection states (all, none, some).</p></li>
644
 
                <li><p>Finally, it provides a sugar layer to simplify adding children to the parent during construction, by supporting an object literal format to initialize children.</p>
645
 
 
646
 
<pre class="code prettyprint">var tabview = new Y.TabView({
647
 
    children: [{
648
 
        label: &#x27;foo&#x27;,
649
 
        content: &#x27;&lt;p&gt;foo content&lt;&#x2F;p&gt;&#x27;
650
 
    }, {
651
 
        label: &#x27;bar&#x27;,
652
 
        content: &#x27;&lt;p&gt;bar content&lt;&#x2F;p&gt;&#x27;
653
 
    }]
654
 
});</pre>
655
 
 
656
 
                </li>
657
 
            </ul>
658
 
        </dd>
659
 
        <dt>widget-child</dt>
660
 
        <dd>
661
 
            <p>Adds support to allow the widget to be contained within a widget parent.</p>
662
 
            <p>Used together with widget-parent, allows you to support hierarchical parent/child structures. As with Widget Parent, it provides a consistent API for child widgets to 
663
 
            interact with their siblings and parents, e.g., <code>child.next()</code>, <code>child.previous()</code> and <code>child.ancestor()</code>.
664
 
            </p>
665
 
        </dd>
666
 
</dl>
667
 
 
668
 
<p>Below are some examples showing how you can use some of these extensions:</p>
669
 
 
670
 
<ul>
671
 
    <li>Using Extensions: <a href="widget-build.html">Building Custom Widget Classes</a></li>
672
 
    <li>Widget-Position, Widget-Stack: <a href="widget-tooltip.html">A Simple Tooltip Widget</a></li>
673
 
    <li>Widget-Parent, Widget-Child: <a href="widget-parentchild-listbox.html">A Hierarchical ListBox Widget</a></li>
674
 
</ul>
675
 
 
676
 
<p>You can also look at some of the bundled widgets which are built using extensions:</p>
677
 
 
678
 
<ul>
679
 
    <li><a href="../overlay/index.html">Overlay</a><p>Uses widget-position, widget-position-align, widget-position-constrain, widget-stack, widget-stdmod</p></li>
680
 
    <li><a href="../tabview/index.html">TabView</a><p>Uses widget-parent, widget-child</p></li>
681
 
</ul>
682
 
 
683
 
<p>The <a href="../assets/widget/../base/myextension.js.txt">"MyExtension" template file</a> provides a starting point for you to create your own extensions.</p>
684
 
 
685
 
<h3 id="plugins">Widget Plugins</h3>
686
 
 
687
 
<p>The YUI 3 library ships with a couple of Widget plugins for the 3.1.0 release, and also provides examples which show how you can create your own plugins:</p>
688
 
 
689
 
<ul>
690
 
    <li><a href="http://yuilibrary.com/yui/docs/api/Plugin.WidgetAnim.html">Widget Animation Plugin</a> (api documentation)</li>
691
 
    <li><a href="http://yuilibrary.com/yui/docs/api/Plugin.Drag.html">Widget (and Node) Drag/Drop Plugin</a> (api documentation)</li>
692
 
 
693
 
    <li><a href="widget-plugin.html">Creating Widget Plugins</a> (example)</li>
694
 
    <li><a href="../overlay/overlay-io-plugin.html">Creating An Overlay IO Plugin</a> (example)</li>
695
 
    <li><a href="../overlay/overlay-anim-plugin.html">Creating An Overlay Animation Plugin</a> (example)</li>
696
 
</ul>
697
 
 
698
 
<p>Additionally, the YUI Gallery is another source for plugins which provide additional functionality for YUI Widgets, such as the <a href="http://yuilibrary.com/gallery/show/overlay-modal">Modal Overlay Plugin</a> and the <a href="http://yuilibrary.com/gallery/show/widget-io">Widget IO Plugin</a>.</p>
699
 
 
700
 
<p>The <a href="../assets/widget/../plugin/myplugin.js.txt">"MyPlugin" template file</a> provides a starting point for you to create your own plugins.</p>
701
 
</div>
702
 
        </div>
703
 
 
704
 
        <div id="sidebar" class="yui3-u">
705
 
            
706
 
                <div id="toc" class="sidebox">
707
 
                    <div class="hd">
708
 
                        <h2 class="no-toc">Table of Contents</h2>
709
 
                    </div>
710
 
 
711
 
                    <div class="bd">
712
 
                        <ul class="toc">
713
 
<li>
714
 
<a href="#responsibilities">What Widget Provides</a>
715
 
<ul class="toc">
716
 
<li>
717
 
<a href="#structure">Class Structure And Responsibilities</a>
718
 
</li>
719
 
<li>
720
 
<a href="#attributes">Basic Attributes</a>
721
 
</li>
722
 
<li>
723
 
<a href="#rendering">Rendering Methods</a>
724
 
<ul class="toc">
725
 
<li>
726
 
<a href="#the-lifecycle-methods-init-destroy-render">The Lifecycle Methods: <code>init, destroy, render</code></a>
727
 
</li>
728
 
<li>
729
 
<a href="#widgets-renderer-method">Widget's <code>renderer</code> Method</a>
730
 
</li>
731
 
</ul>
732
 
</li>
733
 
<li>
734
 
<a href="#progressive">Progressive Enhancement</a>
735
 
<ul class="toc">
736
 
<li>
737
 
<a href="#hidingmarkup">Hiding Progressively Enhanced Markup</a>
738
 
</li>
739
 
</ul>
740
 
</li>
741
 
<li>
742
 
<a href="#markup">Rendered Markup</a>
743
 
<ul class="toc">
744
 
<li>
745
 
<a href="#the-bounding-box">The Bounding Box</a>
746
 
</li>
747
 
<li>
748
 
<a href="#the-content-box">The Content Box</a>
749
 
</li>
750
 
<li>
751
 
<a href="#widget-markup-diagram">Widget Markup Diagram</a>
752
 
</li>
753
 
<li>
754
 
<a href="#why-two-nested-boxes">Why Two Nested Boxes?</a>
755
 
</li>
756
 
</ul>
757
 
</li>
758
 
<li>
759
 
<a href="#CSS">Class Names and CSS</a>
760
 
<ul class="toc">
761
 
<li>
762
 
<a href="#css-implications">CSS Implications</a>
763
 
</li>
764
 
</ul>
765
 
</li>
766
 
<li>
767
 
<a href="#uievents">Default UI Events</a>
768
 
</li>
769
 
</ul>
770
 
</li>
771
 
<li>
772
 
<a href="#creatingwidgets">Developing Your Own Widgets</a>
773
 
</li>
774
 
<li>
775
 
<a href="#pluginsandextensions">Plugins And Extensions</a>
776
 
<ul class="toc">
777
 
<li>
778
 
<a href="#pluginorextension">Plugin or Extension?</a>
779
 
</li>
780
 
<li>
781
 
<a href="#extensions">Widget Extensions</a>
782
 
</li>
783
 
<li>
784
 
<a href="#plugins">Widget Plugins</a>
785
 
</li>
786
 
</ul>
787
 
</li>
788
 
</ul>
789
 
                    </div>
790
 
                </div>
791
 
            
792
 
 
793
 
            
794
 
                <div class="sidebox">
795
 
                    <div class="hd">
796
 
                        <h2 class="no-toc">Examples</h2>
797
 
                    </div>
798
 
 
799
 
                    <div class="bd">
800
 
                        <ul class="examples">
801
 
                            
802
 
                                
803
 
                                    <li data-description="Shows how to extend the base widget class, to create your own Widgets.">
804
 
                                        <a href="widget-extend.html">Extending the Base Widget Class</a>
805
 
                                    </li>
806
 
                                
807
 
                            
808
 
                                
809
 
                                    <li data-description="Shows how to use Base.create and mix/match extensions to create custom Widget classes.">
810
 
                                        <a href="widget-build.html">Creating Custom Widget Classes With Extensions</a>
811
 
                                    </li>
812
 
                                
813
 
                            
814
 
                                
815
 
                                    <li data-description="Shows how to create an IO plugin for Widget.">
816
 
                                        <a href="widget-plugin.html">Creating a Widget Plugin</a>
817
 
                                    </li>
818
 
                                
819
 
                            
820
 
                                
821
 
                                    <li data-description="Shows how to extend the Widget class, and add WidgetPosition and WidgetStack to create a Tooltip widget class.">
822
 
                                        <a href="widget-tooltip.html">Creating a Simple Tooltip Widget With Extensions</a>
823
 
                                    </li>
824
 
                                
825
 
                            
826
 
                                
827
 
                                    <li data-description="Shows how to extend the Widget class, and add WidgetParent and WidgetChild to create a simple ListBox widget.">
828
 
                                        <a href="widget-parentchild-listbox.html">Creating a Hierarchical ListBox Widget</a>
829
 
                                    </li>
830
 
                                
831
 
                            
832
 
                        </ul>
833
 
                    </div>
834
 
                </div>
835
 
            
836
 
 
837
 
            
838
 
        </div>
839
 
    </div>
840
 
</div>
841
 
 
842
 
<script src="../assets/vendor/prettify/prettify-min.js"></script>
843
 
<script>prettyPrint();</script>
844
 
 
845
 
</body>
846
 
</html>