Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('yui2-button', function(Y) {
2
    var YAHOO    = Y.YUI2;
3
    /*
4
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
5
Code licensed under the BSD License:
6
http://developer.yahoo.com/yui/license.html
7
version: 2.9.0
8
*/
9
/**
10
* @module button
11
* @description <p>The Button Control enables the creation of rich, graphical
12
* buttons that function like traditional HTML form buttons.  <em>Unlike</em>
13
* traditional HTML form buttons, buttons created with the Button Control can have
14
* a label that is different from its value.  With the inclusion of the optional
15
* <a href="module_menu.html">Menu Control</a>, the Button Control can also be
16
* used to create menu buttons and split buttons, controls that are not
17
* available natively in HTML.  The Button Control can also be thought of as a
18
* way to create more visually engaging implementations of the browser's
19
* default radio-button and check-box controls.</p>
20
* <p>The Button Control supports the following types:</p>
21
* <dl>
22
* <dt>push</dt>
23
* <dd>Basic push button that can execute a user-specified command when
24
* pressed.</dd>
25
* <dt>link</dt>
26
* <dd>Navigates to a specified url when pressed.</dd>
27
* <dt>submit</dt>
28
* <dd>Submits the parent form when pressed.</dd>
29
* <dt>reset</dt>
30
* <dd>Resets the parent form when pressed.</dd>
31
* <dt>checkbox</dt>
32
* <dd>Maintains a "checked" state that can be toggled on and off.</dd>
33
* <dt>radio</dt>
34
* <dd>Maintains a "checked" state that can be toggled on and off.  Use with
35
* the ButtonGroup class to create a set of controls that are mutually
36
* exclusive; checking one button in the set will uncheck all others in
37
* the group.</dd>
38
* <dt>menu</dt>
39
* <dd>When pressed will show/hide a menu.</dd>
40
* <dt>split</dt>
41
* <dd>Can execute a user-specified command or display a menu when pressed.</dd>
42
* </dl>
43
* @title Button
44
* @namespace YAHOO.widget
45
* @requires yahoo, dom, element, event
46
* @optional container, menu
47
*/
48
 
49
 
50
(function () {
51
 
52
 
53
    /**
54
    * The Button class creates a rich, graphical button.
55
    * @param {String} p_oElement String specifying the id attribute of the
56
    * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
57
    * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to
58
    * be used to create the button.
59
    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
60
    * one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://www.w3.org
61
    * /TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-34812697">
62
    * HTMLButtonElement</a>|<a href="
63
    * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#
64
    * ID-33759296">HTMLElement</a>} p_oElement Object reference for the
65
    * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
66
    * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to be
67
    * used to create the button.
68
    * @param {Object} p_oElement Object literal specifying a set of
69
    * configuration attributes used to create the button.
70
    * @param {Object} p_oAttributes Optional. Object literal specifying a set
71
    * of configuration attributes used to create the button.
72
    * @namespace YAHOO.widget
73
    * @class Button
74
    * @constructor
75
    * @extends YAHOO.util.Element
76
    */
77
 
78
 
79
 
80
    // Shorthard for utilities
81
 
82
    var Dom = YAHOO.util.Dom,
83
        Event = YAHOO.util.Event,
84
        Lang = YAHOO.lang,
85
        UA = YAHOO.env.ua,
86
        Overlay = YAHOO.widget.Overlay,
87
        Menu = YAHOO.widget.Menu,
88
 
89
 
90
        // Private member variables
91
 
92
        m_oButtons = {},    // Collection of all Button instances
93
        m_oOverlayManager = null,   // YAHOO.widget.OverlayManager instance
94
        m_oSubmitTrigger = null,    // The button that submitted the form
95
        m_oFocusedButton = null;    // The button that has focus
96
 
97
 
98
 
99
    // Private methods
100
 
101
 
102
 
103
    /**
104
    * @method createInputElement
105
    * @description Creates an <code>&#60;input&#62;</code> element of the
106
    * specified type.
107
    * @private
108
    * @param {String} p_sType String specifying the type of
109
    * <code>&#60;input&#62;</code> element to create.
110
    * @param {String} p_sName String specifying the name of
111
    * <code>&#60;input&#62;</code> element to create.
112
    * @param {String} p_sValue String specifying the value of
113
    * <code>&#60;input&#62;</code> element to create.
114
    * @param {String} p_bChecked Boolean specifying if the
115
    * <code>&#60;input&#62;</code> element is to be checked.
116
    * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
117
    * one-html.html#ID-6043025">HTMLInputElement</a>}
118
    */
119
    function createInputElement(p_sType, p_sName, p_sValue, p_bChecked) {
120
 
121
        var oInput,
122
            sInput;
123
 
124
        if (Lang.isString(p_sType) && Lang.isString(p_sName)) {
125
 
126
            if (UA.ie && (UA.ie < 9)) {
127
 
128
                /*
129
                    For IE it is necessary to create the element with the
130
                    "type," "name," "value," and "checked" properties set all
131
                    at once.
132
                */
133
 
134
                sInput = "<input type=\"" + p_sType + "\" name=\"" +
135
                    p_sName + "\"";
136
 
137
                if (p_bChecked) {
138
 
139
                    sInput += " checked";
140
 
141
                }
142
 
143
                sInput += ">";
144
 
145
                oInput = document.createElement(sInput);
146
 
147
                oInput.value = p_sValue;
148
 
149
            } else {
150
 
151
                oInput = document.createElement("input");
152
                oInput.name = p_sName;
153
                oInput.type = p_sType;
154
                oInput.value = p_sValue;
155
 
156
                if (p_bChecked) {
157
 
158
                    oInput.checked = true;
159
 
160
                }
161
 
162
            }
163
 
164
 
165
        }
166
 
167
		return oInput;
168
 
169
    }
170
 
171
 
172
    /**
173
    * @method setAttributesFromSrcElement
174
    * @description Gets the values for all the attributes of the source element
175
    * (either <code>&#60;input&#62;</code> or <code>&#60;a&#62;</code>) that
176
    * map to Button configuration attributes and sets them into a collection
177
    * that is passed to the Button constructor.
178
    * @private
179
    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
180
    * one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://www.w3.org/
181
    * TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-
182
    * 48250443">HTMLAnchorElement</a>} p_oElement Object reference to the HTML
183
    * element (either <code>&#60;input&#62;</code> or <code>&#60;span&#62;
184
    * </code>) used to create the button.
185
    * @param {Object} p_oAttributes Object reference for the collection of
186
    * configuration attributes used to create the button.
187
    */
188
    function setAttributesFromSrcElement(p_oElement, p_oAttributes) {
189
 
190
        var sSrcElementNodeName = p_oElement.nodeName.toUpperCase(),
191
			sClass = (this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME),
192
            me = this,
193
            oAttribute,
194
            oRootNode,
195
            sText;
196
 
197
 
198
        /**
199
        * @method setAttributeFromDOMAttribute
200
        * @description Gets the value of the specified DOM attribute and sets it
201
        * into the collection of configuration attributes used to configure
202
        * the button.
203
        * @private
204
        * @param {String} p_sAttribute String representing the name of the
205
        * attribute to retrieve from the DOM element.
206
        */
207
        function setAttributeFromDOMAttribute(p_sAttribute) {
208
 
209
            if (!(p_sAttribute in p_oAttributes)) {
210
 
211
                /*
212
                    Need to use "getAttributeNode" instead of "getAttribute"
213
                    because using "getAttribute," IE will return the innerText
214
                    of a <code>&#60;button&#62;</code> for the value attribute
215
                    rather than the value of the "value" attribute.
216
                */
217
 
218
                oAttribute = p_oElement.getAttributeNode(p_sAttribute);
219
 
220
 
221
                if (oAttribute && ("value" in oAttribute)) {
222
 
223
                    YAHOO.log("Setting attribute \"" + p_sAttribute +
224
                        "\" using source element's attribute value of \"" +
225
                        oAttribute.value + "\"", "info", me.toString());
226
 
227
                    p_oAttributes[p_sAttribute] = oAttribute.value;
228
 
229
                }
230
 
231
            }
232
 
233
        }
234
 
235
 
236
        /**
237
        * @method setFormElementProperties
238
        * @description Gets the value of the attributes from the form element
239
        * and sets them into the collection of configuration attributes used to
240
        * configure the button.
241
        * @private
242
        */
243
        function setFormElementProperties() {
244
 
245
            setAttributeFromDOMAttribute("type");
246
 
247
            if (p_oAttributes.type == "button") {
248
 
249
                p_oAttributes.type = "push";
250
 
251
            }
252
 
253
            if (!("disabled" in p_oAttributes)) {
254
 
255
                p_oAttributes.disabled = p_oElement.disabled;
256
 
257
            }
258
 
259
            setAttributeFromDOMAttribute("name");
260
            setAttributeFromDOMAttribute("value");
261
            setAttributeFromDOMAttribute("title");
262
 
263
        }
264
 
265
 
266
        switch (sSrcElementNodeName) {
267
 
268
        case "A":
269
 
270
            p_oAttributes.type = "link";
271
 
272
            setAttributeFromDOMAttribute("href");
273
            setAttributeFromDOMAttribute("target");
274
 
275
            break;
276
 
277
        case "INPUT":
278
 
279
            setFormElementProperties();
280
 
281
            if (!("checked" in p_oAttributes)) {
282
 
283
                p_oAttributes.checked = p_oElement.checked;
284
 
285
            }
286
 
287
            break;
288
 
289
        case "BUTTON":
290
 
291
            setFormElementProperties();
292
 
293
            oRootNode = p_oElement.parentNode.parentNode;
294
 
295
            if (Dom.hasClass(oRootNode, sClass + "-checked")) {
296
 
297
                p_oAttributes.checked = true;
298
 
299
            }
300
 
301
            if (Dom.hasClass(oRootNode, sClass + "-disabled")) {
302
 
303
                p_oAttributes.disabled = true;
304
 
305
            }
306
 
307
            p_oElement.removeAttribute("value");
308
 
309
            p_oElement.setAttribute("type", "button");
310
 
311
            break;
312
 
313
        }
314
 
315
        p_oElement.removeAttribute("id");
316
        p_oElement.removeAttribute("name");
317
 
318
        if (!("tabindex" in p_oAttributes)) {
319
 
320
            p_oAttributes.tabindex = p_oElement.tabIndex;
321
 
322
        }
323
 
324
        if (!("label" in p_oAttributes)) {
325
 
326
            // Set the "label" property
327
 
328
            sText = sSrcElementNodeName == "INPUT" ?
329
                            p_oElement.value : p_oElement.innerHTML;
330
 
331
 
332
            if (sText && sText.length > 0) {
333
 
334
                p_oAttributes.label = sText;
335
 
336
            }
337
 
338
        }
339
 
340
    }
341
 
342
 
343
    /**
344
    * @method initConfig
345
    * @description Initializes the set of configuration attributes that are
346
    * used to instantiate the button.
347
    * @private
348
    * @param {Object} Object representing the button's set of
349
    * configuration attributes.
350
    */
351
    function initConfig(p_oConfig) {
352
 
353
        var oAttributes = p_oConfig.attributes,
354
            oSrcElement = oAttributes.srcelement,
355
            sSrcElementNodeName = oSrcElement.nodeName.toUpperCase(),
356
            me = this;
357
 
358
 
359
        if (sSrcElementNodeName == this.NODE_NAME) {
360
 
361
            p_oConfig.element = oSrcElement;
362
            p_oConfig.id = oSrcElement.id;
363
 
364
            Dom.getElementsBy(function (p_oElement) {
365
 
366
                switch (p_oElement.nodeName.toUpperCase()) {
367
 
368
                case "BUTTON":
369
                case "A":
370
                case "INPUT":
371
 
372
                    setAttributesFromSrcElement.call(me, p_oElement,
373
                        oAttributes);
374
 
375
                    break;
376
 
377
                }
378
 
379
            }, "*", oSrcElement);
380
 
381
        }
382
        else {
383
 
384
            switch (sSrcElementNodeName) {
385
 
386
            case "BUTTON":
387
            case "A":
388
            case "INPUT":
389
 
390
                setAttributesFromSrcElement.call(this, oSrcElement,
391
                    oAttributes);
392
 
393
                break;
394
 
395
            }
396
 
397
        }
398
 
399
    }
400
 
401
 
402
 
403
    //  Constructor
404
 
405
    YAHOO.widget.Button = function (p_oElement, p_oAttributes) {
406
 
407
		if (!Overlay && YAHOO.widget.Overlay) {
408
 
409
			Overlay = YAHOO.widget.Overlay;
410
 
411
		}
412
 
413
 
414
		if (!Menu && YAHOO.widget.Menu) {
415
 
416
			Menu = YAHOO.widget.Menu;
417
 
418
		}
419
 
420
 
421
        var fnSuperClass = YAHOO.widget.Button.superclass.constructor,
422
            oConfig,
423
            oElement;
424
 
425
 
426
        if (arguments.length == 1 && !Lang.isString(p_oElement) && !p_oElement.nodeName) {
427
 
428
            if (!p_oElement.id) {
429
 
430
                p_oElement.id = Dom.generateId();
431
 
432
                YAHOO.log("No value specified for the button's \"id\" " +
433
                    "attribute. Setting button id to \"" + p_oElement.id +
434
                    "\".", "info", this.toString());
435
 
436
            }
437
 
438
            YAHOO.log("No source HTML element.  Building the button " +
439
                    "using the set of configuration attributes.", "info", this.toString());
440
 
441
            fnSuperClass.call(this, (this.createButtonElement(p_oElement.type)), p_oElement);
442
 
443
        }
444
        else {
445
 
446
            oConfig = { element: null, attributes: (p_oAttributes || {}) };
447
 
448
 
449
            if (Lang.isString(p_oElement)) {
450
 
451
                oElement = Dom.get(p_oElement);
452
 
453
                if (oElement) {
454
 
455
                    if (!oConfig.attributes.id) {
456
 
457
                        oConfig.attributes.id = p_oElement;
458
 
459
                    }
460
 
461
                    YAHOO.log("Building the button using an existing " +
462
                            "HTML element as a source element.", "info", this.toString());
463
 
464
 
465
                    oConfig.attributes.srcelement = oElement;
466
 
467
                    initConfig.call(this, oConfig);
468
 
469
 
470
                    if (!oConfig.element) {
471
 
472
                        YAHOO.log("Source element could not be used " +
473
                                "as is.  Creating a new HTML element for " +
474
                                "the button.", "info", this.toString());
475
 
476
                        oConfig.element = this.createButtonElement(oConfig.attributes.type);
477
 
478
                    }
479
 
480
                    fnSuperClass.call(this, oConfig.element, oConfig.attributes);
481
 
482
                }
483
 
484
            }
485
            else if (p_oElement.nodeName) {
486
 
487
                if (!oConfig.attributes.id) {
488
 
489
                    if (p_oElement.id) {
490
 
491
                        oConfig.attributes.id = p_oElement.id;
492
 
493
                    }
494
                    else {
495
 
496
                        oConfig.attributes.id = Dom.generateId();
497
 
498
                        YAHOO.log("No value specified for the button's " +
499
                            "\"id\" attribute. Setting button id to \"" +
500
                            oConfig.attributes.id + "\".", "info", this.toString());
501
 
502
                    }
503
 
504
                }
505
 
506
                YAHOO.log("Building the button using an existing HTML " +
507
                    "element as a source element.", "info", this.toString());
508
 
509
 
510
                oConfig.attributes.srcelement = p_oElement;
511
 
512
                initConfig.call(this, oConfig);
513
 
514
 
515
                if (!oConfig.element) {
516
 
517
                    YAHOO.log("Source element could not be used as is." +
518
                            "  Creating a new HTML element for the button.",
519
                            "info", this.toString());
520
 
521
                    oConfig.element = this.createButtonElement(oConfig.attributes.type);
522
 
523
                }
524
 
525
                fnSuperClass.call(this, oConfig.element, oConfig.attributes);
526
 
527
            }
528
 
529
        }
530
 
531
    };
532
 
533
 
534
 
535
    YAHOO.extend(YAHOO.widget.Button, YAHOO.util.Element, {
536
 
537
 
538
        // Protected properties
539
 
540
 
541
        /**
542
        * @property _button
543
        * @description Object reference to the button's internal
544
        * <code>&#60;a&#62;</code> or <code>&#60;button&#62;</code> element.
545
        * @default null
546
        * @protected
547
        * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
548
        * level-one-html.html#ID-48250443">HTMLAnchorElement</a>|<a href="
549
        * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
550
        * #ID-34812697">HTMLButtonElement</a>
551
        */
552
        _button: null,
553
 
554
 
555
        /**
556
        * @property _menu
557
        * @description Object reference to the button's menu.
558
        * @default null
559
        * @protected
560
        * @type {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|
561
        * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
562
        */
563
        _menu: null,
564
 
565
 
566
        /**
567
        * @property _hiddenFields
568
        * @description Object reference to the <code>&#60;input&#62;</code>
569
        * element, or array of HTML form elements used to represent the button
570
        *  when its parent form is submitted.
571
        * @default null
572
        * @protected
573
        * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
574
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array
575
        */
576
        _hiddenFields: null,
577
 
578
 
579
        /**
580
        * @property _onclickAttributeValue
581
        * @description Object reference to the button's current value for the
582
        * "onclick" configuration attribute.
583
        * @default null
584
        * @protected
585
        * @type Object
586
        */
587
        _onclickAttributeValue: null,
588
 
589
 
590
        /**
591
        * @property _activationKeyPressed
592
        * @description Boolean indicating if the key(s) that toggle the button's
593
        * "active" state have been pressed.
594
        * @default false
595
        * @protected
596
        * @type Boolean
597
        */
598
        _activationKeyPressed: false,
599
 
600
 
601
        /**
602
        * @property _activationButtonPressed
603
        * @description Boolean indicating if the mouse button that toggles
604
        * the button's "active" state has been pressed.
605
        * @default false
606
        * @protected
607
        * @type Boolean
608
        */
609
        _activationButtonPressed: false,
610
 
611
 
612
        /**
613
        * @property _hasKeyEventHandlers
614
        * @description Boolean indicating if the button's "blur", "keydown" and
615
        * "keyup" event handlers are assigned
616
        * @default false
617
        * @protected
618
        * @type Boolean
619
        */
620
        _hasKeyEventHandlers: false,
621
 
622
 
623
        /**
624
        * @property _hasMouseEventHandlers
625
        * @description Boolean indicating if the button's "mouseout,"
626
        * "mousedown," and "mouseup" event handlers are assigned
627
        * @default false
628
        * @protected
629
        * @type Boolean
630
        */
631
        _hasMouseEventHandlers: false,
632
 
633
 
634
        /**
635
        * @property _nOptionRegionX
636
        * @description Number representing the X coordinate of the leftmost edge of the Button's
637
        * option region.  Applies only to Buttons of type "split".
638
        * @default 0
639
        * @protected
640
        * @type Number
641
        */
642
        _nOptionRegionX: 0,
643
 
644
 
645
 
646
        // Constants
647
 
648
        /**
649
        * @property CLASS_NAME_PREFIX
650
        * @description Prefix used for all class names applied to a Button.
651
        * @default "yui-"
652
        * @final
653
        * @type String
654
        */
655
        CLASS_NAME_PREFIX: "yui-",
656
 
657
 
658
        /**
659
        * @property NODE_NAME
660
        * @description The name of the node to be used for the button's
661
        * root element.
662
        * @default "SPAN"
663
        * @final
664
        * @type String
665
        */
666
        NODE_NAME: "SPAN",
667
 
668
 
669
        /**
670
        * @property CHECK_ACTIVATION_KEYS
671
        * @description Array of numbers representing keys that (when pressed)
672
        * toggle the button's "checked" attribute.
673
        * @default [32]
674
        * @final
675
        * @type Array
676
        */
677
        CHECK_ACTIVATION_KEYS: [32],
678
 
679
 
680
        /**
681
        * @property ACTIVATION_KEYS
682
        * @description Array of numbers representing keys that (when presed)
683
        * toggle the button's "active" state.
684
        * @default [13, 32]
685
        * @final
686
        * @type Array
687
        */
688
        ACTIVATION_KEYS: [13, 32],
689
 
690
 
691
        /**
692
        * @property OPTION_AREA_WIDTH
693
        * @description Width (in pixels) of the area of a split button that
694
        * when pressed will display a menu.
695
        * @default 20
696
        * @final
697
        * @type Number
698
        */
699
        OPTION_AREA_WIDTH: 20,
700
 
701
 
702
        /**
703
        * @property CSS_CLASS_NAME
704
        * @description String representing the CSS class(es) to be applied to
705
        * the button's root element.
706
        * @default "button"
707
        * @final
708
        * @type String
709
        */
710
        CSS_CLASS_NAME: "button",
711
 
712
 
713
 
714
        // Protected attribute setter methods
715
 
716
 
717
        /**
718
        * @method _setType
719
        * @description Sets the value of the button's "type" attribute.
720
        * @protected
721
        * @param {String} p_sType String indicating the value for the button's
722
        * "type" attribute.
723
        */
724
        _setType: function (p_sType) {
725
 
726
            if (p_sType == "split") {
727
 
728
                this.on("option", this._onOption);
729
 
730
            }
731
 
732
        },
733
 
734
 
735
        /**
736
        * @method _setLabel
737
        * @description Sets the value of the button's "label" attribute.
738
        * @protected
739
        * @param {HTML} p_sLabel String indicating the value for the button's
740
        * "label" attribute.
741
        */
742
        _setLabel: function (p_sLabel) {
743
 
744
            this._button.innerHTML = p_sLabel;
745
 
746
 
747
            /*
748
                Remove and add the default class name from the root element
749
                for Gecko to ensure that the button shrinkwraps to the label.
750
                Without this the button will not be rendered at the correct
751
                width when the label changes.  The most likely cause for this
752
                bug is button's use of the Gecko-specific CSS display type of
753
                "-moz-inline-box" to simulate "inline-block" supported by IE,
754
                Safari and Opera.
755
            */
756
 
757
            var sClass,
758
                nGeckoVersion = UA.gecko;
759
 
760
 
761
            if (nGeckoVersion && nGeckoVersion < 1.9 && Dom.inDocument(this.get("element"))) {
762
 
763
                sClass = (this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME);
764
 
765
                this.removeClass(sClass);
766
 
767
                Lang.later(0, this, this.addClass, sClass);
768
 
769
            }
770
 
771
        },
772
 
773
 
774
        /**
775
        * @method _setTabIndex
776
        * @description Sets the value of the button's "tabindex" attribute.
777
        * @protected
778
        * @param {Number} p_nTabIndex Number indicating the value for the
779
        * button's "tabindex" attribute.
780
        */
781
        _setTabIndex: function (p_nTabIndex) {
782
 
783
            this._button.tabIndex = p_nTabIndex;
784
 
785
        },
786
 
787
 
788
        /**
789
        * @method _setTitle
790
        * @description Sets the value of the button's "title" attribute.
791
        * @protected
792
        * @param {String} p_nTabIndex Number indicating the value for
793
        * the button's "title" attribute.
794
        */
795
        _setTitle: function (p_sTitle) {
796
 
797
            if (this.get("type") != "link") {
798
 
799
                this._button.title = p_sTitle;
800
 
801
            }
802
 
803
        },
804
 
805
 
806
        /**
807
        * @method _setDisabled
808
        * @description Sets the value of the button's "disabled" attribute.
809
        * @protected
810
        * @param {Boolean} p_bDisabled Boolean indicating the value for
811
        * the button's "disabled" attribute.
812
        */
813
        _setDisabled: function (p_bDisabled) {
814
 
815
            if (this.get("type") != "link") {
816
 
817
                if (p_bDisabled) {
818
 
819
                    if (this._menu) {
820
 
821
                        this._menu.hide();
822
 
823
                    }
824
 
825
                    if (this.hasFocus()) {
826
 
827
                        this.blur();
828
 
829
                    }
830
 
831
                    this._button.setAttribute("disabled", "disabled");
832
 
833
                    this.addStateCSSClasses("disabled");
834
 
835
                    this.removeStateCSSClasses("hover");
836
                    this.removeStateCSSClasses("active");
837
                    this.removeStateCSSClasses("focus");
838
 
839
                }
840
                else {
841
 
842
                    this._button.removeAttribute("disabled");
843
 
844
                    this.removeStateCSSClasses("disabled");
845
 
846
                }
847
 
848
            }
849
 
850
        },
851
 
852
 
853
        /**
854
        * @method _setHref
855
        * @description Sets the value of the button's "href" attribute.
856
        * @protected
857
        * @param {String} p_sHref String indicating the value for the button's
858
        * "href" attribute.
859
        */
860
        _setHref: function (p_sHref) {
861
 
862
            if (this.get("type") == "link") {
863
 
864
                this._button.href = p_sHref;
865
 
866
            }
867
 
868
        },
869
 
870
 
871
        /**
872
        * @method _setTarget
873
        * @description Sets the value of the button's "target" attribute.
874
        * @protected
875
        * @param {String} p_sTarget String indicating the value for the button's
876
        * "target" attribute.
877
        */
878
        _setTarget: function (p_sTarget) {
879
 
880
            if (this.get("type") == "link") {
881
 
882
                this._button.setAttribute("target", p_sTarget);
883
 
884
            }
885
 
886
        },
887
 
888
 
889
        /**
890
        * @method _setChecked
891
        * @description Sets the value of the button's "target" attribute.
892
        * @protected
893
        * @param {Boolean} p_bChecked Boolean indicating the value for
894
        * the button's "checked" attribute.
895
        */
896
        _setChecked: function (p_bChecked) {
897
 
898
            var sType = this.get("type");
899
 
900
            if (sType == "checkbox" || sType == "radio") {
901
 
902
                if (p_bChecked) {
903
                    this.addStateCSSClasses("checked");
904
                }
905
                else {
906
                    this.removeStateCSSClasses("checked");
907
                }
908
 
909
            }
910
 
911
        },
912
 
913
 
914
        /**
915
        * @method _setMenu
916
        * @description Sets the value of the button's "menu" attribute.
917
        * @protected
918
        * @param {Object} p_oMenu Object indicating the value for the button's
919
        * "menu" attribute.
920
        */
921
        _setMenu: function (p_oMenu) {
922
 
923
            var bLazyLoad = this.get("lazyloadmenu"),
924
                oButtonElement = this.get("element"),
925
                sMenuCSSClassName,
926
 
927
                /*
928
                    Boolean indicating if the value of p_oMenu is an instance
929
                    of YAHOO.widget.Menu or YAHOO.widget.Overlay.
930
                */
931
 
932
                bInstance = false,
933
                oMenu,
934
                oMenuElement,
935
                oSrcElement;
936
 
937
 
938
			function onAppendTo() {
939
 
940
				oMenu.render(oButtonElement.parentNode);
941
 
942
				this.removeListener("appendTo", onAppendTo);
943
 
944
			}
945
 
946
 
947
			function setMenuContainer() {
948
 
949
				oMenu.cfg.queueProperty("container", oButtonElement.parentNode);
950
 
951
				this.removeListener("appendTo", setMenuContainer);
952
 
953
			}
954
 
955
 
956
			function initMenu() {
957
 
958
				var oContainer;
959
 
960
				if (oMenu) {
961
 
962
					Dom.addClass(oMenu.element, this.get("menuclassname"));
963
					Dom.addClass(oMenu.element, this.CLASS_NAME_PREFIX + this.get("type") + "-button-menu");
964
 
965
					oMenu.showEvent.subscribe(this._onMenuShow, null, this);
966
					oMenu.hideEvent.subscribe(this._onMenuHide, null, this);
967
					oMenu.renderEvent.subscribe(this._onMenuRender, null, this);
968
 
969
 
970
					if (Menu && oMenu instanceof Menu) {
971
 
972
						if (bLazyLoad) {
973
 
974
							oContainer = this.get("container");
975
 
976
							if (oContainer) {
977
 
978
								oMenu.cfg.queueProperty("container", oContainer);
979
 
980
							}
981
							else {
982
 
983
								this.on("appendTo", setMenuContainer);
984
 
985
							}
986
 
987
						}
988
 
989
						oMenu.cfg.queueProperty("clicktohide", false);
990
 
991
						oMenu.keyDownEvent.subscribe(this._onMenuKeyDown, this, true);
992
						oMenu.subscribe("click", this._onMenuClick, this, true);
993
 
994
						this.on("selectedMenuItemChange", this._onSelectedMenuItemChange);
995
 
996
						oSrcElement = oMenu.srcElement;
997
 
998
						if (oSrcElement && oSrcElement.nodeName.toUpperCase() == "SELECT") {
999
 
1000
							oSrcElement.style.display = "none";
1001
							oSrcElement.parentNode.removeChild(oSrcElement);
1002
 
1003
						}
1004
 
1005
					}
1006
					else if (Overlay && oMenu instanceof Overlay) {
1007
 
1008
						if (!m_oOverlayManager) {
1009
 
1010
							m_oOverlayManager = new YAHOO.widget.OverlayManager();
1011
 
1012
						}
1013
 
1014
						m_oOverlayManager.register(oMenu);
1015
 
1016
					}
1017
 
1018
 
1019
					this._menu = oMenu;
1020
 
1021
 
1022
					if (!bInstance && !bLazyLoad) {
1023
 
1024
						if (Dom.inDocument(oButtonElement)) {
1025
 
1026
							oMenu.render(oButtonElement.parentNode);
1027
 
1028
						}
1029
						else {
1030
 
1031
							this.on("appendTo", onAppendTo);
1032
 
1033
						}
1034
 
1035
					}
1036
 
1037
				}
1038
 
1039
			}
1040
 
1041
 
1042
            if (Overlay) {
1043
 
1044
				if (Menu) {
1045
 
1046
					sMenuCSSClassName = Menu.prototype.CSS_CLASS_NAME;
1047
 
1048
				}
1049
 
1050
				if (p_oMenu && Menu && (p_oMenu instanceof Menu)) {
1051
 
1052
					oMenu = p_oMenu;
1053
					bInstance = true;
1054
 
1055
					initMenu.call(this);
1056
 
1057
				}
1058
				else if (Overlay && p_oMenu && (p_oMenu instanceof Overlay)) {
1059
 
1060
					oMenu = p_oMenu;
1061
					bInstance = true;
1062
 
1063
					oMenu.cfg.queueProperty("visible", false);
1064
 
1065
					initMenu.call(this);
1066
 
1067
				}
1068
				else if (Menu && Lang.isArray(p_oMenu)) {
1069
 
1070
					oMenu = new Menu(Dom.generateId(), { lazyload: bLazyLoad, itemdata: p_oMenu });
1071
 
1072
					this._menu = oMenu;
1073
 
1074
					this.on("appendTo", initMenu);
1075
 
1076
				}
1077
				else if (Lang.isString(p_oMenu)) {
1078
 
1079
					oMenuElement = Dom.get(p_oMenu);
1080
 
1081
					if (oMenuElement) {
1082
 
1083
						if (Menu && Dom.hasClass(oMenuElement, sMenuCSSClassName) ||
1084
							oMenuElement.nodeName.toUpperCase() == "SELECT") {
1085
 
1086
							oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1087
 
1088
							initMenu.call(this);
1089
 
1090
						}
1091
						else if (Overlay) {
1092
 
1093
							oMenu = new Overlay(p_oMenu, { visible: false });
1094
 
1095
							initMenu.call(this);
1096
 
1097
						}
1098
 
1099
					}
1100
 
1101
				}
1102
				else if (p_oMenu && p_oMenu.nodeName) {
1103
 
1104
					if (Menu && Dom.hasClass(p_oMenu, sMenuCSSClassName) ||
1105
							p_oMenu.nodeName.toUpperCase() == "SELECT") {
1106
 
1107
						oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1108
 
1109
						initMenu.call(this);
1110
 
1111
					}
1112
					else if (Overlay) {
1113
 
1114
						if (!p_oMenu.id) {
1115
 
1116
							Dom.generateId(p_oMenu);
1117
 
1118
						}
1119
 
1120
						oMenu = new Overlay(p_oMenu, { visible: false });
1121
 
1122
						initMenu.call(this);
1123
 
1124
					}
1125
 
1126
				}
1127
 
1128
            }
1129
 
1130
        },
1131
 
1132
 
1133
        /**
1134
        * @method _setOnClick
1135
        * @description Sets the value of the button's "onclick" attribute.
1136
        * @protected
1137
        * @param {Object} p_oObject Object indicating the value for the button's
1138
        * "onclick" attribute.
1139
        */
1140
        _setOnClick: function (p_oObject) {
1141
 
1142
            /*
1143
                Remove any existing listeners if a "click" event handler
1144
                has already been specified.
1145
            */
1146
 
1147
            if (this._onclickAttributeValue &&
1148
                (this._onclickAttributeValue != p_oObject)) {
1149
 
1150
                this.removeListener("click", this._onclickAttributeValue.fn);
1151
 
1152
                this._onclickAttributeValue = null;
1153
 
1154
            }
1155
 
1156
 
1157
            if (!this._onclickAttributeValue &&
1158
                Lang.isObject(p_oObject) &&
1159
                Lang.isFunction(p_oObject.fn)) {
1160
 
1161
                this.on("click", p_oObject.fn, p_oObject.obj, p_oObject.scope);
1162
 
1163
                this._onclickAttributeValue = p_oObject;
1164
 
1165
            }
1166
 
1167
        },
1168
 
1169
 
1170
 
1171
        // Protected methods
1172
 
1173
 
1174
 
1175
        /**
1176
        * @method _isActivationKey
1177
        * @description Determines if the specified keycode is one that toggles
1178
        * the button's "active" state.
1179
        * @protected
1180
        * @param {Number} p_nKeyCode Number representing the keycode to
1181
        * be evaluated.
1182
        * @return {Boolean}
1183
        */
1184
        _isActivationKey: function (p_nKeyCode) {
1185
 
1186
            var sType = this.get("type"),
1187
                aKeyCodes = (sType == "checkbox" || sType == "radio") ?
1188
                    this.CHECK_ACTIVATION_KEYS : this.ACTIVATION_KEYS,
1189
 
1190
                nKeyCodes = aKeyCodes.length,
1191
                bReturnVal = false,
1192
                i;
1193
 
1194
 
1195
            if (nKeyCodes > 0) {
1196
 
1197
                i = nKeyCodes - 1;
1198
 
1199
                do {
1200
 
1201
                    if (p_nKeyCode == aKeyCodes[i]) {
1202
 
1203
                        bReturnVal = true;
1204
                        break;
1205
 
1206
                    }
1207
 
1208
                }
1209
                while (i--);
1210
 
1211
            }
1212
 
1213
            return bReturnVal;
1214
 
1215
        },
1216
 
1217
 
1218
        /**
1219
        * @method _isSplitButtonOptionKey
1220
        * @description Determines if the specified keycode is one that toggles
1221
        * the display of the split button's menu.
1222
        * @protected
1223
        * @param {Event} p_oEvent Object representing the DOM event object
1224
        * passed back by the event utility (YAHOO.util.Event).
1225
        * @return {Boolean}
1226
        */
1227
        _isSplitButtonOptionKey: function (p_oEvent) {
1228
 
1229
			var bShowMenu = (Event.getCharCode(p_oEvent) == 40);
1230
 
1231
 
1232
			var onKeyPress = function (p_oEvent) {
1233
 
1234
				Event.preventDefault(p_oEvent);
1235
 
1236
				this.removeListener("keypress", onKeyPress);
1237
 
1238
			};
1239
 
1240
 
1241
			// Prevent the browser from scrolling the window
1242
			if (bShowMenu) {
1243
 
1244
				if (UA.opera) {
1245
 
1246
					this.on("keypress", onKeyPress);
1247
 
1248
				}
1249
 
1250
				Event.preventDefault(p_oEvent);
1251
			}
1252
 
1253
            return bShowMenu;
1254
 
1255
        },
1256
 
1257
 
1258
        /**
1259
        * @method _addListenersToForm
1260
        * @description Adds event handlers to the button's form.
1261
        * @protected
1262
        */
1263
        _addListenersToForm: function () {
1264
 
1265
            var oForm = this.getForm(),
1266
                onFormKeyPress = YAHOO.widget.Button.onFormKeyPress,
1267
                bHasKeyPressListener,
1268
                oSrcElement,
1269
                aListeners,
1270
                nListeners,
1271
                i;
1272
 
1273
 
1274
            if (oForm) {
1275
 
1276
                Event.on(oForm, "reset", this._onFormReset, null, this);
1277
                Event.on(oForm, "submit", this._onFormSubmit, null, this);
1278
 
1279
                oSrcElement = this.get("srcelement");
1280
 
1281
 
1282
                if (this.get("type") == "submit" ||
1283
                    (oSrcElement && oSrcElement.type == "submit"))
1284
                {
1285
 
1286
                    aListeners = Event.getListeners(oForm, "keypress");
1287
                    bHasKeyPressListener = false;
1288
 
1289
                    if (aListeners) {
1290
 
1291
                        nListeners = aListeners.length;
1292
 
1293
                        if (nListeners > 0) {
1294
 
1295
                            i = nListeners - 1;
1296
 
1297
                            do {
1298
 
1299
                                if (aListeners[i].fn == onFormKeyPress) {
1300
 
1301
                                    bHasKeyPressListener = true;
1302
                                    break;
1303
 
1304
                                }
1305
 
1306
                            }
1307
                            while (i--);
1308
 
1309
                        }
1310
 
1311
                    }
1312
 
1313
 
1314
                    if (!bHasKeyPressListener) {
1315
 
1316
                        Event.on(oForm, "keypress", onFormKeyPress);
1317
 
1318
                    }
1319
 
1320
                }
1321
 
1322
            }
1323
 
1324
        },
1325
 
1326
 
1327
 
1328
        /**
1329
        * @method _showMenu
1330
        * @description Shows the button's menu.
1331
        * @protected
1332
        * @param {Event} p_oEvent Object representing the DOM event object
1333
        * passed back by the event utility (YAHOO.util.Event) that triggered
1334
        * the display of the menu.
1335
        */
1336
        _showMenu: function (p_oEvent) {
1337
 
1338
            if (YAHOO.widget.MenuManager) {
1339
                YAHOO.widget.MenuManager.hideVisible();
1340
            }
1341
 
1342
 
1343
            if (m_oOverlayManager) {
1344
                m_oOverlayManager.hideAll();
1345
            }
1346
 
1347
 
1348
            var oMenu = this._menu,
1349
            	aMenuAlignment = this.get("menualignment"),
1350
            	bFocusMenu = this.get("focusmenu"),
1351
				fnFocusMethod;
1352
 
1353
 
1354
			if (this._renderedMenu) {
1355
 
1356
				oMenu.cfg.setProperty("context",
1357
								[this.get("element"), aMenuAlignment[0], aMenuAlignment[1]]);
1358
 
1359
				oMenu.cfg.setProperty("preventcontextoverlap", true);
1360
				oMenu.cfg.setProperty("constraintoviewport", true);
1361
 
1362
			}
1363
			else {
1364
 
1365
				oMenu.cfg.queueProperty("context",
1366
								[this.get("element"), aMenuAlignment[0], aMenuAlignment[1]]);
1367
 
1368
				oMenu.cfg.queueProperty("preventcontextoverlap", true);
1369
				oMenu.cfg.queueProperty("constraintoviewport", true);
1370
 
1371
			}
1372
 
1373
 
1374
			/*
1375
				 Refocus the Button before showing its Menu in case the call to
1376
				 YAHOO.widget.MenuManager.hideVisible() resulted in another element in the
1377
				 DOM being focused after another Menu was hidden.
1378
			*/
1379
 
1380
			this.focus();
1381
 
1382
 
1383
            if (Menu && oMenu && (oMenu instanceof Menu)) {
1384
 
1385
				// Since Menus automatically focus themselves when made visible, temporarily
1386
				// replace the Menu focus method so that the value of the Button's "focusmenu"
1387
				// attribute determines if the Menu should be focus when made visible.
1388
 
1389
				fnFocusMethod = oMenu.focus;
1390
 
1391
				oMenu.focus = function () {};
1392
 
1393
				if (this._renderedMenu) {
1394
 
1395
					oMenu.cfg.setProperty("minscrollheight", this.get("menuminscrollheight"));
1396
					oMenu.cfg.setProperty("maxheight", this.get("menumaxheight"));
1397
 
1398
				}
1399
				else {
1400
 
1401
					oMenu.cfg.queueProperty("minscrollheight", this.get("menuminscrollheight"));
1402
					oMenu.cfg.queueProperty("maxheight", this.get("menumaxheight"));
1403
 
1404
				}
1405
 
1406
 
1407
                oMenu.show();
1408
 
1409
        		oMenu.focus = fnFocusMethod;
1410
 
1411
				oMenu.align();
1412
 
1413
 
1414
                /*
1415
                    Stop the propagation of the event so that the MenuManager
1416
                    doesn't blur the menu after it gets focus.
1417
                */
1418
 
1419
                if (p_oEvent.type == "mousedown") {
1420
                    Event.stopPropagation(p_oEvent);
1421
                }
1422
 
1423
 
1424
                if (bFocusMenu) {
1425
                    oMenu.focus();
1426
                }
1427
 
1428
            }
1429
            else if (Overlay && oMenu && (oMenu instanceof Overlay)) {
1430
 
1431
				if (!this._renderedMenu) {
1432
		            oMenu.render(this.get("element").parentNode);
1433
				}
1434
 
1435
                oMenu.show();
1436
				oMenu.align();
1437
 
1438
            }
1439
 
1440
        },
1441
 
1442
 
1443
        /**
1444
        * @method _hideMenu
1445
        * @description Hides the button's menu.
1446
        * @protected
1447
        */
1448
        _hideMenu: function () {
1449
 
1450
            var oMenu = this._menu;
1451
 
1452
            if (oMenu) {
1453
 
1454
                oMenu.hide();
1455
 
1456
            }
1457
 
1458
        },
1459
 
1460
 
1461
 
1462
 
1463
        // Protected event handlers
1464
 
1465
 
1466
        /**
1467
        * @method _onMouseOver
1468
        * @description "mouseover" event handler for the button.
1469
        * @protected
1470
        * @param {Event} p_oEvent Object representing the DOM event object
1471
        * passed back by the event utility (YAHOO.util.Event).
1472
        */
1473
        _onMouseOver: function (p_oEvent) {
1474
 
1475
        	var sType = this.get("type"),
1476
        		oElement,
1477
				nOptionRegionX;
1478
 
1479
 
1480
			if (sType === "split") {
1481
 
1482
				oElement = this.get("element");
1483
				nOptionRegionX =
1484
					(Dom.getX(oElement) + (oElement.offsetWidth - this.OPTION_AREA_WIDTH));
1485
 
1486
				this._nOptionRegionX = nOptionRegionX;
1487
 
1488
			}
1489
 
1490
 
1491
            if (!this._hasMouseEventHandlers) {
1492
 
1493
				if (sType === "split") {
1494
 
1495
	        		this.on("mousemove", this._onMouseMove);
1496
 
1497
        		}
1498
 
1499
                this.on("mouseout", this._onMouseOut);
1500
 
1501
                this._hasMouseEventHandlers = true;
1502
 
1503
            }
1504
 
1505
 
1506
            this.addStateCSSClasses("hover");
1507
 
1508
 
1509
			if (sType === "split" && (Event.getPageX(p_oEvent) > nOptionRegionX)) {
1510
 
1511
				this.addStateCSSClasses("hoveroption");
1512
 
1513
			}
1514
 
1515
 
1516
            if (this._activationButtonPressed) {
1517
 
1518
                this.addStateCSSClasses("active");
1519
 
1520
            }
1521
 
1522
 
1523
            if (this._bOptionPressed) {
1524
 
1525
                this.addStateCSSClasses("activeoption");
1526
 
1527
            }
1528
 
1529
 
1530
            if (this._activationButtonPressed || this._bOptionPressed) {
1531
 
1532
                Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
1533
 
1534
            }
1535
 
1536
        },
1537
 
1538
 
1539
        /**
1540
        * @method _onMouseMove
1541
        * @description "mousemove" event handler for the button.
1542
        * @protected
1543
        * @param {Event} p_oEvent Object representing the DOM event object
1544
        * passed back by the event utility (YAHOO.util.Event).
1545
        */
1546
        _onMouseMove: function (p_oEvent) {
1547
 
1548
        	var nOptionRegionX = this._nOptionRegionX;
1549
 
1550
        	if (nOptionRegionX) {
1551
 
1552
				if (Event.getPageX(p_oEvent) > nOptionRegionX) {
1553
 
1554
					this.addStateCSSClasses("hoveroption");
1555
 
1556
				}
1557
				else {
1558
 
1559
					this.removeStateCSSClasses("hoveroption");
1560
 
1561
				}
1562
 
1563
        	}
1564
 
1565
        },
1566
 
1567
        /**
1568
        * @method _onMouseOut
1569
        * @description "mouseout" event handler for the button.
1570
        * @protected
1571
        * @param {Event} p_oEvent Object representing the DOM event object
1572
        * passed back by the event utility (YAHOO.util.Event).
1573
        */
1574
        _onMouseOut: function (p_oEvent) {
1575
 
1576
			var sType = this.get("type");
1577
 
1578
            this.removeStateCSSClasses("hover");
1579
 
1580
 
1581
            if (sType != "menu") {
1582
 
1583
                this.removeStateCSSClasses("active");
1584
 
1585
            }
1586
 
1587
 
1588
            if (this._activationButtonPressed || this._bOptionPressed) {
1589
 
1590
                Event.on(document, "mouseup", this._onDocumentMouseUp, null, this);
1591
 
1592
            }
1593
 
1594
 
1595
			if (sType === "split" && (Event.getPageX(p_oEvent) > this._nOptionRegionX)) {
1596
 
1597
				this.removeStateCSSClasses("hoveroption");
1598
 
1599
			}
1600
 
1601
        },
1602
 
1603
 
1604
        /**
1605
        * @method _onDocumentMouseUp
1606
        * @description "mouseup" event handler for the button.
1607
        * @protected
1608
        * @param {Event} p_oEvent Object representing the DOM event object
1609
        * passed back by the event utility (YAHOO.util.Event).
1610
        */
1611
        _onDocumentMouseUp: function (p_oEvent) {
1612
 
1613
            this._activationButtonPressed = false;
1614
            this._bOptionPressed = false;
1615
 
1616
            var sType = this.get("type"),
1617
                oTarget,
1618
                oMenuElement;
1619
 
1620
            if (sType == "menu" || sType == "split") {
1621
 
1622
                oTarget = Event.getTarget(p_oEvent);
1623
                oMenuElement = this._menu.element;
1624
 
1625
                if (oTarget != oMenuElement &&
1626
                    !Dom.isAncestor(oMenuElement, oTarget)) {
1627
 
1628
                    this.removeStateCSSClasses((sType == "menu" ?
1629
                        "active" : "activeoption"));
1630
 
1631
                    this._hideMenu();
1632
 
1633
                }
1634
 
1635
            }
1636
 
1637
            Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
1638
 
1639
        },
1640
 
1641
 
1642
        /**
1643
        * @method _onMouseDown
1644
        * @description "mousedown" event handler for the button.
1645
        * @protected
1646
        * @param {Event} p_oEvent Object representing the DOM event object
1647
        * passed back by the event utility (YAHOO.util.Event).
1648
        */
1649
        _onMouseDown: function (p_oEvent) {
1650
 
1651
            var sType,
1652
            	bReturnVal = true;
1653
 
1654
 
1655
            function onMouseUp() {
1656
 
1657
                this._hideMenu();
1658
                this.removeListener("mouseup", onMouseUp);
1659
 
1660
            }
1661
 
1662
 
1663
            if ((p_oEvent.which || p_oEvent.button) == 1) {
1664
 
1665
 
1666
                if (!this.hasFocus()) {
1667
                    Lang.later(0, this, this.focus);
1668
                    //this.focus();
1669
                }
1670
 
1671
 
1672
                sType = this.get("type");
1673
 
1674
 
1675
                if (sType == "split") {
1676
 
1677
                    if (Event.getPageX(p_oEvent) > this._nOptionRegionX) {
1678
 
1679
                        this.fireEvent("option", p_oEvent);
1680
						bReturnVal = false;
1681
 
1682
                    }
1683
                    else {
1684
 
1685
                        this.addStateCSSClasses("active");
1686
 
1687
                        this._activationButtonPressed = true;
1688
 
1689
                    }
1690
 
1691
                }
1692
                else if (sType == "menu") {
1693
 
1694
                    if (this.isActive()) {
1695
 
1696
                        this._hideMenu();
1697
 
1698
                        this._activationButtonPressed = false;
1699
 
1700
                    }
1701
                    else {
1702
 
1703
                        this._showMenu(p_oEvent);
1704
 
1705
                        this._activationButtonPressed = true;
1706
 
1707
                    }
1708
 
1709
                }
1710
                else {
1711
 
1712
                    this.addStateCSSClasses("active");
1713
 
1714
                    this._activationButtonPressed = true;
1715
 
1716
                }
1717
 
1718
 
1719
 
1720
                if (sType == "split" || sType == "menu") {
1721
 
1722
                    this._hideMenuTimer = Lang.later(250, this, this.on, ["mouseup", onMouseUp]);
1723
 
1724
                }
1725
 
1726
            }
1727
 
1728
            return bReturnVal;
1729
 
1730
        },
1731
 
1732
 
1733
        /**
1734
        * @method _onMouseUp
1735
        * @description "mouseup" event handler for the button.
1736
        * @protected
1737
        * @param {Event} p_oEvent Object representing the DOM event object
1738
        * passed back by the event utility (YAHOO.util.Event).
1739
        */
1740
        _onMouseUp: function (p_oEvent) {
1741
            this.inMouseDown = false;
1742
 
1743
            var sType = this.get("type"),
1744
            	oHideMenuTimer = this._hideMenuTimer,
1745
            	bReturnVal = true;
1746
 
1747
 
1748
            if (oHideMenuTimer) {
1749
 
1750
  				oHideMenuTimer.cancel();
1751
 
1752
            }
1753
 
1754
 
1755
            if (sType == "checkbox" || sType == "radio") {
1756
                if ((p_oEvent.which || p_oEvent.button) != 1) {
1757
                    return;
1758
                }
1759
 
1760
                this.set("checked", !(this.get("checked")));
1761
 
1762
            }
1763
 
1764
 
1765
            this._activationButtonPressed = false;
1766
 
1767
 
1768
            if (sType != "menu") {
1769
 
1770
                this.removeStateCSSClasses("active");
1771
 
1772
            }
1773
 
1774
 
1775
			if (sType == "split" && Event.getPageX(p_oEvent) > this._nOptionRegionX) {
1776
 
1777
				bReturnVal = false;
1778
 
1779
			}
1780
 
1781
			return bReturnVal;
1782
 
1783
        },
1784
 
1785
 
1786
        /**
1787
        * @method _onFocus
1788
        * @description "focus" event handler for the button.
1789
        * @protected
1790
        * @param {Event} p_oEvent Object representing the DOM event object
1791
        * passed back by the event utility (YAHOO.util.Event).
1792
        */
1793
        _onFocus: function (p_oEvent) {
1794
 
1795
            var oElement;
1796
 
1797
            this.addStateCSSClasses("focus");
1798
 
1799
            if (this._activationKeyPressed) {
1800
 
1801
                this.addStateCSSClasses("active");
1802
 
1803
            }
1804
 
1805
            m_oFocusedButton = this;
1806
 
1807
 
1808
            if (!this._hasKeyEventHandlers) {
1809
 
1810
                oElement = this._button;
1811
 
1812
                Event.on(oElement, "blur", this._onBlur, null, this);
1813
                Event.on(oElement, "keydown", this._onKeyDown, null, this);
1814
                Event.on(oElement, "keyup", this._onKeyUp, null, this);
1815
 
1816
                this._hasKeyEventHandlers = true;
1817
 
1818
            }
1819
 
1820
 
1821
            this.fireEvent("focus", p_oEvent);
1822
 
1823
        },
1824
 
1825
 
1826
        /**
1827
        * @method _onBlur
1828
        * @description "blur" event handler for the button.
1829
        * @protected
1830
        * @param {Event} p_oEvent Object representing the DOM event object
1831
        * passed back by the event utility (YAHOO.util.Event).
1832
        */
1833
        _onBlur: function (p_oEvent) {
1834
 
1835
            this.removeStateCSSClasses("focus");
1836
 
1837
            if (this.get("type") != "menu") {
1838
 
1839
                this.removeStateCSSClasses("active");
1840
 
1841
            }
1842
 
1843
            if (this._activationKeyPressed) {
1844
 
1845
                Event.on(document, "keyup", this._onDocumentKeyUp, null, this);
1846
 
1847
            }
1848
 
1849
 
1850
            m_oFocusedButton = null;
1851
 
1852
            this.fireEvent("blur", p_oEvent);
1853
 
1854
        },
1855
 
1856
 
1857
        /**
1858
        * @method _onDocumentKeyUp
1859
        * @description "keyup" event handler for the document.
1860
        * @protected
1861
        * @param {Event} p_oEvent Object representing the DOM event object
1862
        * passed back by the event utility (YAHOO.util.Event).
1863
        */
1864
        _onDocumentKeyUp: function (p_oEvent) {
1865
 
1866
            if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1867
 
1868
                this._activationKeyPressed = false;
1869
 
1870
                Event.removeListener(document, "keyup", this._onDocumentKeyUp);
1871
 
1872
            }
1873
 
1874
        },
1875
 
1876
 
1877
        /**
1878
        * @method _onKeyDown
1879
        * @description "keydown" event handler for the button.
1880
        * @protected
1881
        * @param {Event} p_oEvent Object representing the DOM event object
1882
        * passed back by the event utility (YAHOO.util.Event).
1883
        */
1884
        _onKeyDown: function (p_oEvent) {
1885
 
1886
            var oMenu = this._menu;
1887
 
1888
 
1889
            if (this.get("type") == "split" &&
1890
                this._isSplitButtonOptionKey(p_oEvent)) {
1891
 
1892
                this.fireEvent("option", p_oEvent);
1893
 
1894
            }
1895
            else if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1896
 
1897
                if (this.get("type") == "menu") {
1898
 
1899
                    this._showMenu(p_oEvent);
1900
 
1901
                }
1902
                else {
1903
 
1904
                    this._activationKeyPressed = true;
1905
 
1906
                    this.addStateCSSClasses("active");
1907
 
1908
                }
1909
 
1910
            }
1911
 
1912
 
1913
            if (oMenu && oMenu.cfg.getProperty("visible") &&
1914
                Event.getCharCode(p_oEvent) == 27) {
1915
 
1916
                oMenu.hide();
1917
                this.focus();
1918
 
1919
            }
1920
 
1921
        },
1922
 
1923
 
1924
        /**
1925
        * @method _onKeyUp
1926
        * @description "keyup" event handler for the button.
1927
        * @protected
1928
        * @param {Event} p_oEvent Object representing the DOM event object
1929
        * passed back by the event utility (YAHOO.util.Event).
1930
        */
1931
        _onKeyUp: function (p_oEvent) {
1932
 
1933
            var sType;
1934
 
1935
            if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1936
 
1937
                sType = this.get("type");
1938
 
1939
                if (sType == "checkbox" || sType == "radio") {
1940
 
1941
                    this.set("checked", !(this.get("checked")));
1942
 
1943
                }
1944
 
1945
                this._activationKeyPressed = false;
1946
 
1947
                if (this.get("type") != "menu") {
1948
 
1949
                    this.removeStateCSSClasses("active");
1950
 
1951
                }
1952
 
1953
            }
1954
 
1955
        },
1956
 
1957
 
1958
        /**
1959
        * @method _onClick
1960
        * @description "click" event handler for the button.
1961
        * @protected
1962
        * @param {Event} p_oEvent Object representing the DOM event object
1963
        * passed back by the event utility (YAHOO.util.Event).
1964
        */
1965
        _onClick: function (p_oEvent) {
1966
 
1967
            var sType = this.get("type"),
1968
                oForm,
1969
                oSrcElement,
1970
                bReturnVal;
1971
 
1972
 
1973
			switch (sType) {
1974
 
1975
			case "submit":
1976
 
1977
				if (p_oEvent.returnValue !== false) {
1978
 
1979
					this.submitForm();
1980
 
1981
				}
1982
 
1983
				break;
1984
 
1985
			case "reset":
1986
 
1987
				oForm = this.getForm();
1988
 
1989
				if (oForm) {
1990
 
1991
					oForm.reset();
1992
 
1993
				}
1994
 
1995
				break;
1996
 
1997
 
1998
			case "split":
1999
 
2000
				if (this._nOptionRegionX > 0 &&
2001
						(Event.getPageX(p_oEvent) > this._nOptionRegionX)) {
2002
 
2003
					bReturnVal = false;
2004
 
2005
				}
2006
				else {
2007
 
2008
					this._hideMenu();
2009
 
2010
					oSrcElement = this.get("srcelement");
2011
 
2012
					if (oSrcElement && oSrcElement.type == "submit" &&
2013
							p_oEvent.returnValue !== false) {
2014
 
2015
						this.submitForm();
2016
 
2017
					}
2018
 
2019
				}
2020
 
2021
				break;
2022
 
2023
			}
2024
 
2025
			return bReturnVal;
2026
 
2027
        },
2028
 
2029
 
2030
        /**
2031
        * @method _onDblClick
2032
        * @description "dblclick" event handler for the button.
2033
        * @protected
2034
        * @param {Event} p_oEvent Object representing the DOM event object
2035
        * passed back by the event utility (YAHOO.util.Event).
2036
        */
2037
        _onDblClick: function (p_oEvent) {
2038
 
2039
            var bReturnVal = true;
2040
 
2041
			if (this.get("type") == "split" && Event.getPageX(p_oEvent) > this._nOptionRegionX) {
2042
 
2043
				bReturnVal = false;
2044
 
2045
			}
2046
 
2047
        	return bReturnVal;
2048
 
2049
        },
2050
 
2051
 
2052
        /**
2053
        * @method _onAppendTo
2054
        * @description "appendTo" event handler for the button.
2055
        * @protected
2056
        * @param {Event} p_oEvent Object representing the DOM event object
2057
        * passed back by the event utility (YAHOO.util.Event).
2058
        */
2059
        _onAppendTo: function (p_oEvent) {
2060
 
2061
            /*
2062
                It is necessary to call "_addListenersToForm" using
2063
                "setTimeout" to make sure that the button's "form" property
2064
                returns a node reference.  Sometimes, if you try to get the
2065
                reference immediately after appending the field, it is null.
2066
            */
2067
 
2068
            Lang.later(0, this, this._addListenersToForm);
2069
 
2070
        },
2071
 
2072
 
2073
        /**
2074
        * @method _onFormReset
2075
        * @description "reset" event handler for the button's form.
2076
        * @protected
2077
        * @param {Event} p_oEvent Object representing the DOM event
2078
        * object passed back by the event utility (YAHOO.util.Event).
2079
        */
2080
        _onFormReset: function (p_oEvent) {
2081
 
2082
            var sType = this.get("type"),
2083
                oMenu = this._menu;
2084
 
2085
            if (sType == "checkbox" || sType == "radio") {
2086
 
2087
                this.resetValue("checked");
2088
 
2089
            }
2090
 
2091
 
2092
            if (Menu && oMenu && (oMenu instanceof Menu)) {
2093
 
2094
                this.resetValue("selectedMenuItem");
2095
 
2096
            }
2097
 
2098
        },
2099
 
2100
 
2101
        /**
2102
        * @method _onFormSubmit
2103
        * @description "submit" event handler for the button's form.
2104
        * @protected
2105
        * @param {Event} p_oEvent Object representing the DOM event
2106
        * object passed back by the event utility (YAHOO.util.Event).
2107
        */
2108
        _onFormSubmit: function (p_oEvent) {
2109
 
2110
        	this.createHiddenFields();
2111
 
2112
        },
2113
 
2114
 
2115
        /**
2116
        * @method _onDocumentMouseDown
2117
        * @description "mousedown" event handler for the document.
2118
        * @protected
2119
        * @param {Event} p_oEvent Object representing the DOM event object
2120
        * passed back by the event utility (YAHOO.util.Event).
2121
        */
2122
        _onDocumentMouseDown: function (p_oEvent) {
2123
 
2124
            var oTarget = Event.getTarget(p_oEvent),
2125
                oButtonElement = this.get("element"),
2126
                oMenuElement = this._menu.element;
2127
 
2128
            function findTargetInSubmenus(aSubmenus) {
2129
                var i, iMax, oSubmenuElement;
2130
                if (!aSubmenus) {
2131
                    return true;
2132
                }
2133
                for (i = 0, iMax = aSubmenus.length; i < iMax; i++) {
2134
                    oSubmenuElement = aSubmenus[i].element;
2135
                    if (oTarget == oSubmenuElement || Dom.isAncestor(oSubmenuElement, oTarget)) {
2136
                        return true;
2137
                    }
2138
                    if (aSubmenus[i] && aSubmenus[i].getSubmenus) {
2139
                        if (findTargetInSubmenus(aSubmenus[i].getSubmenus())) {
2140
                            return true;
2141
                        }
2142
                    }
2143
                }
2144
 
2145
                return false;
2146
            }
2147
 
2148
            if (oTarget != oButtonElement &&
2149
                !Dom.isAncestor(oButtonElement, oTarget) &&
2150
                oTarget != oMenuElement &&
2151
                !Dom.isAncestor(oMenuElement, oTarget)) {
2152
 
2153
 
2154
                if (this._menu  && this._menu.getSubmenus) {
2155
                    if (!findTargetInSubmenus(this._menu.getSubmenus())) {
2156
                        return;
2157
                    }
2158
                }
2159
 
2160
 
2161
                this._hideMenu();
2162
 
2163
				//	In IE when the user mouses down on a focusable element
2164
				//	that element will be focused and become the "activeElement".
2165
				//	(http://msdn.microsoft.com/en-us/library/ms533065(VS.85).aspx)
2166
				//	However, there is a bug in IE where if there is a
2167
				//	positioned element with a focused descendant that is
2168
				//	hidden in response to the mousedown event, the target of
2169
				//	the mousedown event will appear to have focus, but will
2170
				//	not be set as the activeElement.  This will result
2171
				//	in the element not firing key events, even though it
2172
				//	appears to have focus.	The following call to "setActive"
2173
				//	fixes this bug.
2174
 
2175
                if (UA.ie && (UA.ie < 9) && oTarget.focus) {
2176
					oTarget.setActive();
2177
				}
2178
 
2179
                Event.removeListener(document, "mousedown",
2180
                    this._onDocumentMouseDown);
2181
 
2182
            }
2183
 
2184
        },
2185
 
2186
 
2187
        /**
2188
        * @method _onOption
2189
        * @description "option" event handler for the button.
2190
        * @protected
2191
        * @param {Event} p_oEvent Object representing the DOM event object
2192
        * passed back by the event utility (YAHOO.util.Event).
2193
        */
2194
        _onOption: function (p_oEvent) {
2195
 
2196
            if (this.hasClass(this.CLASS_NAME_PREFIX + "split-button-activeoption")) {
2197
 
2198
                this._hideMenu();
2199
 
2200
                this._bOptionPressed = false;
2201
 
2202
            }
2203
            else {
2204
 
2205
                this._showMenu(p_oEvent);
2206
 
2207
                this._bOptionPressed = true;
2208
 
2209
            }
2210
 
2211
        },
2212
 
2213
 
2214
        /**
2215
        * @method _onMenuShow
2216
        * @description "show" event handler for the button's menu.
2217
        * @private
2218
        * @param {String} p_sType String representing the name of the event
2219
        * that was fired.
2220
        */
2221
        _onMenuShow: function (p_sType) {
2222
 
2223
            Event.on(document, "mousedown", this._onDocumentMouseDown,
2224
                null, this);
2225
 
2226
            var sState = (this.get("type") == "split") ? "activeoption" : "active";
2227
 
2228
            this.addStateCSSClasses(sState);
2229
 
2230
        },
2231
 
2232
 
2233
        /**
2234
        * @method _onMenuHide
2235
        * @description "hide" event handler for the button's menu.
2236
        * @private
2237
        * @param {String} p_sType String representing the name of the event
2238
        * that was fired.
2239
        */
2240
        _onMenuHide: function (p_sType) {
2241
 
2242
            var sState = (this.get("type") == "split") ? "activeoption" : "active";
2243
 
2244
            this.removeStateCSSClasses(sState);
2245
 
2246
 
2247
            if (this.get("type") == "split") {
2248
 
2249
                this._bOptionPressed = false;
2250
 
2251
            }
2252
 
2253
        },
2254
 
2255
 
2256
        /**
2257
        * @method _onMenuKeyDown
2258
        * @description "keydown" event handler for the button's menu.
2259
        * @private
2260
        * @param {String} p_sType String representing the name of the event
2261
        * that was fired.
2262
        * @param {Array} p_aArgs Array of arguments sent when the event
2263
        * was fired.
2264
        */
2265
        _onMenuKeyDown: function (p_sType, p_aArgs) {
2266
 
2267
            var oEvent = p_aArgs[0];
2268
 
2269
            if (Event.getCharCode(oEvent) == 27) {
2270
 
2271
                this.focus();
2272
 
2273
                if (this.get("type") == "split") {
2274
 
2275
                    this._bOptionPressed = false;
2276
 
2277
                }
2278
 
2279
            }
2280
 
2281
        },
2282
 
2283
 
2284
        /**
2285
        * @method _onMenuRender
2286
        * @description "render" event handler for the button's menu.
2287
        * @private
2288
        * @param {String} p_sType String representing the name of the
2289
        * event thatwas fired.
2290
        */
2291
        _onMenuRender: function (p_sType) {
2292
 
2293
            var oButtonElement = this.get("element"),
2294
                oButtonParent = oButtonElement.parentNode,
2295
				oMenu = this._menu,
2296
                oMenuElement = oMenu.element,
2297
				oSrcElement = oMenu.srcElement,
2298
				oItem;
2299
 
2300
 
2301
            if (oButtonParent != oMenuElement.parentNode) {
2302
 
2303
                oButtonParent.appendChild(oMenuElement);
2304
 
2305
            }
2306
 
2307
			this._renderedMenu = true;
2308
 
2309
			//	If the user has designated an <option> of the Menu's source
2310
			//	<select> element to be selected, sync the selectedIndex with
2311
			//	the "selectedMenuItem" Attribute.
2312
 
2313
			if (oSrcElement &&
2314
					oSrcElement.nodeName.toLowerCase() === "select" &&
2315
					oSrcElement.value) {
2316
 
2317
 
2318
				oItem = oMenu.getItem(oSrcElement.selectedIndex);
2319
 
2320
				//	Set the value of the "selectedMenuItem" attribute
2321
				//	silently since this is the initial set--synchronizing
2322
				//	the value of the source <SELECT> element in the DOM with
2323
				//	its corresponding Menu instance.
2324
 
2325
				this.set("selectedMenuItem", oItem, true);
2326
 
2327
				//	Call the "_onSelectedMenuItemChange" method since the
2328
				//	attribute was set silently.
2329
 
2330
				this._onSelectedMenuItemChange({ newValue: oItem });
2331
 
2332
			}
2333
 
2334
        },
2335
 
2336
 
2337
 
2338
        /**
2339
        * @method _onMenuClick
2340
        * @description "click" event handler for the button's menu.
2341
        * @private
2342
        * @param {String} p_sType String representing the name of the event
2343
        * that was fired.
2344
        * @param {Array} p_aArgs Array of arguments sent when the event
2345
        * was fired.
2346
        */
2347
        _onMenuClick: function (p_sType, p_aArgs) {
2348
 
2349
            var oItem = p_aArgs[1],
2350
                oSrcElement;
2351
 
2352
            if (oItem) {
2353
 
2354
				this.set("selectedMenuItem", oItem);
2355
 
2356
                oSrcElement = this.get("srcelement");
2357
 
2358
                if (oSrcElement && oSrcElement.type == "submit") {
2359
 
2360
                    this.submitForm();
2361
 
2362
                }
2363
 
2364
                this._hideMenu();
2365
 
2366
            }
2367
 
2368
        },
2369
 
2370
 
2371
        /**
2372
        * @method _onSelectedMenuItemChange
2373
        * @description "selectedMenuItemChange" event handler for the Button's
2374
		* "selectedMenuItem" attribute.
2375
        * @param {Event} event Object representing the DOM event object
2376
        * passed back by the event utility (YAHOO.util.Event).
2377
        */
2378
		_onSelectedMenuItemChange: function (event) {
2379
 
2380
			var oSelected = event.prevValue,
2381
				oItem = event.newValue,
2382
				sPrefix = this.CLASS_NAME_PREFIX;
2383
 
2384
			if (oSelected) {
2385
				Dom.removeClass(oSelected.element, (sPrefix + "button-selectedmenuitem"));
2386
			}
2387
 
2388
			if (oItem) {
2389
				Dom.addClass(oItem.element, (sPrefix + "button-selectedmenuitem"));
2390
			}
2391
 
2392
		},
2393
 
2394
 
2395
        /**
2396
        * @method _onLabelClick
2397
        * @description "click" event handler for the Button's
2398
		* <code>&#60;label&#62;</code> element.
2399
        * @param {Event} event Object representing the DOM event object
2400
        * passed back by the event utility (YAHOO.util.Event).
2401
        */
2402
		_onLabelClick: function (event) {
2403
 
2404
			this.focus();
2405
 
2406
			var sType = this.get("type");
2407
 
2408
			if (sType == "radio" || sType == "checkbox") {
2409
				this.set("checked", (!this.get("checked")));
2410
			}
2411
 
2412
		},
2413
 
2414
 
2415
        // Public methods
2416
 
2417
 
2418
        /**
2419
        * @method createButtonElement
2420
        * @description Creates the button's HTML elements.
2421
        * @param {String} p_sType String indicating the type of element
2422
        * to create.
2423
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2424
        * level-one-html.html#ID-58190037">HTMLElement</a>}
2425
        */
2426
        createButtonElement: function (p_sType) {
2427
 
2428
            var sNodeName = this.NODE_NAME,
2429
                oElement = document.createElement(sNodeName);
2430
 
2431
            oElement.innerHTML =  "<" + sNodeName + " class=\"first-child\">" +
2432
                (p_sType == "link" ? "<a></a>" :
2433
                "<button type=\"button\"></button>") + "</" + sNodeName + ">";
2434
 
2435
            return oElement;
2436
 
2437
        },
2438
 
2439
 
2440
        /**
2441
        * @method addStateCSSClasses
2442
        * @description Appends state-specific CSS classes to the button's root
2443
        * DOM element.
2444
        */
2445
        addStateCSSClasses: function (p_sState) {
2446
 
2447
            var sType = this.get("type"),
2448
				sPrefix = this.CLASS_NAME_PREFIX;
2449
 
2450
            if (Lang.isString(p_sState)) {
2451
 
2452
                if (p_sState != "activeoption" && p_sState != "hoveroption") {
2453
 
2454
                    this.addClass(sPrefix + this.CSS_CLASS_NAME + ("-" + p_sState));
2455
 
2456
                }
2457
 
2458
                this.addClass(sPrefix + sType + ("-button-" + p_sState));
2459
 
2460
            }
2461
 
2462
        },
2463
 
2464
 
2465
        /**
2466
        * @method removeStateCSSClasses
2467
        * @description Removes state-specific CSS classes to the button's root
2468
        * DOM element.
2469
        */
2470
        removeStateCSSClasses: function (p_sState) {
2471
 
2472
            var sType = this.get("type"),
2473
				sPrefix = this.CLASS_NAME_PREFIX;
2474
 
2475
            if (Lang.isString(p_sState)) {
2476
 
2477
                this.removeClass(sPrefix + this.CSS_CLASS_NAME + ("-" + p_sState));
2478
                this.removeClass(sPrefix + sType + ("-button-" + p_sState));
2479
 
2480
            }
2481
 
2482
        },
2483
 
2484
 
2485
        /**
2486
        * @method createHiddenFields
2487
        * @description Creates the button's hidden form field and appends it
2488
        * to its parent form.
2489
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2490
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
2491
        */
2492
        createHiddenFields: function () {
2493
 
2494
            this.removeHiddenFields();
2495
 
2496
            var oForm = this.getForm(),
2497
                oButtonField,
2498
                sType,
2499
                bCheckable,
2500
                oMenu,
2501
                oMenuItem,
2502
                sButtonName,
2503
                oValue,
2504
                oMenuField,
2505
                oReturnVal,
2506
				sMenuFieldName,
2507
				oMenuSrcElement,
2508
				bMenuSrcElementIsSelect = false;
2509
 
2510
 
2511
            if (oForm && !this.get("disabled")) {
2512
 
2513
                sType = this.get("type");
2514
                bCheckable = (sType == "checkbox" || sType == "radio");
2515
 
2516
 
2517
                if ((bCheckable && this.get("checked")) || (m_oSubmitTrigger == this)) {
2518
 
2519
                    YAHOO.log("Creating hidden field.", "info", this.toString());
2520
 
2521
                    oButtonField = createInputElement((bCheckable ? sType : "hidden"),
2522
                                    this.get("name"), this.get("value"), this.get("checked"));
2523
 
2524
 
2525
                    if (oButtonField) {
2526
 
2527
                        if (bCheckable) {
2528
 
2529
                            oButtonField.style.display = "none";
2530
 
2531
                        }
2532
 
2533
                        oForm.appendChild(oButtonField);
2534
 
2535
                    }
2536
 
2537
                }
2538
 
2539
 
2540
                oMenu = this._menu;
2541
 
2542
 
2543
                if (Menu && oMenu && (oMenu instanceof Menu)) {
2544
 
2545
                    YAHOO.log("Creating hidden field for menu.", "info", this.toString());
2546
 
2547
                    oMenuItem = this.get("selectedMenuItem");
2548
					oMenuSrcElement = oMenu.srcElement;
2549
					bMenuSrcElementIsSelect = (oMenuSrcElement &&
2550
												oMenuSrcElement.nodeName.toUpperCase() == "SELECT");
2551
 
2552
                    if (oMenuItem) {
2553
 
2554
						oValue = (oMenuItem.value === null || oMenuItem.value === "") ?
2555
									oMenuItem.cfg.getProperty("text") : oMenuItem.value;
2556
 
2557
						sButtonName = this.get("name");
2558
 
2559
 
2560
						if (bMenuSrcElementIsSelect) {
2561
 
2562
							sMenuFieldName = oMenuSrcElement.name;
2563
 
2564
						}
2565
						else if (sButtonName) {
2566
 
2567
							sMenuFieldName = (sButtonName + "_options");
2568
 
2569
						}
2570
 
2571
 
2572
						if (oValue && sMenuFieldName) {
2573
 
2574
							oMenuField = createInputElement("hidden", sMenuFieldName, oValue);
2575
							oForm.appendChild(oMenuField);
2576
 
2577
						}
2578
 
2579
                    }
2580
                    else if (bMenuSrcElementIsSelect) {
2581
 
2582
						oMenuField = oForm.appendChild(oMenuSrcElement);
2583
 
2584
                    }
2585
 
2586
                }
2587
 
2588
 
2589
                if (oButtonField && oMenuField) {
2590
 
2591
                    this._hiddenFields = [oButtonField, oMenuField];
2592
 
2593
                }
2594
                else if (!oButtonField && oMenuField) {
2595
 
2596
                    this._hiddenFields = oMenuField;
2597
 
2598
                }
2599
                else if (oButtonField && !oMenuField) {
2600
 
2601
                    this._hiddenFields = oButtonField;
2602
 
2603
                }
2604
 
2605
        		oReturnVal = this._hiddenFields;
2606
 
2607
            }
2608
 
2609
			return oReturnVal;
2610
 
2611
        },
2612
 
2613
 
2614
        /**
2615
        * @method removeHiddenFields
2616
        * @description Removes the button's hidden form field(s) from its
2617
        * parent form.
2618
        */
2619
        removeHiddenFields: function () {
2620
 
2621
            var oField = this._hiddenFields,
2622
                nFields,
2623
                i;
2624
 
2625
            function removeChild(p_oElement) {
2626
 
2627
                if (Dom.inDocument(p_oElement)) {
2628
 
2629
                    p_oElement.parentNode.removeChild(p_oElement);
2630
 
2631
                }
2632
 
2633
            }
2634
 
2635
 
2636
            if (oField) {
2637
 
2638
                if (Lang.isArray(oField)) {
2639
 
2640
                    nFields = oField.length;
2641
 
2642
                    if (nFields > 0) {
2643
 
2644
                        i = nFields - 1;
2645
 
2646
                        do {
2647
 
2648
                            removeChild(oField[i]);
2649
 
2650
                        }
2651
                        while (i--);
2652
 
2653
                    }
2654
 
2655
                }
2656
                else {
2657
 
2658
                    removeChild(oField);
2659
 
2660
                }
2661
 
2662
                this._hiddenFields = null;
2663
 
2664
            }
2665
 
2666
        },
2667
 
2668
 
2669
        /**
2670
        * @method submitForm
2671
        * @description Submits the form to which the button belongs.  Returns
2672
        * true if the form was submitted successfully, false if the submission
2673
        * was cancelled.
2674
        * @protected
2675
        * @return {Boolean}
2676
        */
2677
        submitForm: function () {
2678
 
2679
            var oForm = this.getForm(),
2680
 
2681
                oSrcElement = this.get("srcelement"),
2682
 
2683
                /*
2684
                    Boolean indicating if the event fired successfully
2685
                    (was not cancelled by any handlers)
2686
                */
2687
 
2688
                bSubmitForm = false,
2689
 
2690
                oEvent;
2691
 
2692
 
2693
            if (oForm) {
2694
 
2695
                if (this.get("type") == "submit" || (oSrcElement && oSrcElement.type == "submit")) {
2696
 
2697
                    m_oSubmitTrigger = this;
2698
 
2699
                }
2700
 
2701
 
2702
                if (UA.ie && (UA.ie < 9)) {
2703
 
2704
                    bSubmitForm = oForm.fireEvent("onsubmit");
2705
 
2706
                }
2707
                else {  // Gecko, Opera, and Safari
2708
 
2709
                    oEvent = document.createEvent("HTMLEvents");
2710
                    oEvent.initEvent("submit", true, true);
2711
 
2712
                    bSubmitForm = oForm.dispatchEvent(oEvent);
2713
 
2714
                }
2715
 
2716
 
2717
                /*
2718
                    In IE and Safari, dispatching a "submit" event to a form
2719
                    WILL cause the form's "submit" event to fire, but WILL NOT
2720
                    submit the form.  Therefore, we need to call the "submit"
2721
                    method as well.
2722
                */
2723
 
2724
                if ((UA.ie || UA.webkit) && bSubmitForm) {
2725
 
2726
                    oForm.submit();
2727
 
2728
                }
2729
 
2730
            }
2731
 
2732
            return bSubmitForm;
2733
 
2734
        },
2735
 
2736
 
2737
        /**
2738
        * @method init
2739
        * @description The Button class's initialization method.
2740
        * @param {String} p_oElement String specifying the id attribute of the
2741
        * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
2742
        * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to
2743
        * be used to create the button.
2744
        * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2745
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://
2746
        * www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
2747
        * #ID-34812697">HTMLButtonElement</a>|<a href="http://www.w3.org/TR
2748
        * /2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-33759296">
2749
        * HTMLElement</a>} p_oElement Object reference for the
2750
        * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
2751
        * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to be
2752
        * used to create the button.
2753
        * @param {Object} p_oElement Object literal specifying a set of
2754
        * configuration attributes used to create the button.
2755
        * @param {Object} p_oAttributes Optional. Object literal specifying a
2756
        * set of configuration attributes used to create the button.
2757
        */
2758
        init: function (p_oElement, p_oAttributes) {
2759
 
2760
            var sNodeName = p_oAttributes.type == "link" ? "a" : "button",
2761
                oSrcElement = p_oAttributes.srcelement,
2762
                oButton = p_oElement.getElementsByTagName(sNodeName)[0],
2763
                oInput;
2764
 
2765
 
2766
            if (!oButton) {
2767
 
2768
                oInput = p_oElement.getElementsByTagName("input")[0];
2769
 
2770
 
2771
                if (oInput) {
2772
 
2773
                    oButton = document.createElement("button");
2774
                    oButton.setAttribute("type", "button");
2775
 
2776
                    oInput.parentNode.replaceChild(oButton, oInput);
2777
 
2778
                }
2779
 
2780
            }
2781
 
2782
            this._button = oButton;
2783
 
2784
 
2785
            YAHOO.widget.Button.superclass.init.call(this, p_oElement, p_oAttributes);
2786
 
2787
 
2788
			var sId = this.get("id"),
2789
				sButtonId = sId + "-button";
2790
 
2791
 
2792
        	oButton.id = sButtonId;
2793
 
2794
 
2795
			var aLabels,
2796
				oLabel;
2797
 
2798
 
2799
        	var hasLabel = function (element) {
2800
 
2801
				return (element.htmlFor === sId);
2802
 
2803
        	};
2804
 
2805
 
2806
			var setLabel = function () {
2807
 
2808
				oLabel.setAttribute((UA.ie ? "htmlFor" : "for"), sButtonId);
2809
 
2810
			};
2811
 
2812
 
2813
			if (oSrcElement && this.get("type") != "link") {
2814
 
2815
				aLabels = Dom.getElementsBy(hasLabel, "label");
2816
 
2817
				if (Lang.isArray(aLabels) && aLabels.length > 0) {
2818
 
2819
					oLabel = aLabels[0];
2820
 
2821
				}
2822
 
2823
			}
2824
 
2825
 
2826
            m_oButtons[sId] = this;
2827
 
2828
        	var sPrefix = this.CLASS_NAME_PREFIX;
2829
 
2830
            this.addClass(sPrefix + this.CSS_CLASS_NAME);
2831
            this.addClass(sPrefix + this.get("type") + "-button");
2832
 
2833
            Event.on(this._button, "focus", this._onFocus, null, this);
2834
            this.on("mouseover", this._onMouseOver);
2835
			this.on("mousedown", this._onMouseDown);
2836
			this.on("mouseup", this._onMouseUp);
2837
            this.on("click", this._onClick);
2838
 
2839
			//	Need to reset the value of the "onclick" Attribute so that any
2840
			//	handlers registered via the "onclick" Attribute are fired after
2841
			//	Button's default "_onClick" listener.
2842
 
2843
			var fnOnClick = this.get("onclick");
2844
 
2845
			this.set("onclick", null);
2846
			this.set("onclick", fnOnClick);
2847
 
2848
            this.on("dblclick", this._onDblClick);
2849
 
2850
 
2851
			var oParentNode;
2852
 
2853
            if (oLabel) {
2854
 
2855
				if (this.get("replaceLabel")) {
2856
 
2857
					this.set("label", oLabel.innerHTML);
2858
 
2859
					oParentNode = oLabel.parentNode;
2860
 
2861
					oParentNode.removeChild(oLabel);
2862
 
2863
				}
2864
				else {
2865
 
2866
					this.on("appendTo", setLabel);
2867
 
2868
					Event.on(oLabel, "click", this._onLabelClick, null, this);
2869
 
2870
					this._label = oLabel;
2871
 
2872
				}
2873
 
2874
            }
2875
 
2876
            this.on("appendTo", this._onAppendTo);
2877
 
2878
 
2879
 
2880
            var oContainer = this.get("container"),
2881
                oElement = this.get("element"),
2882
                bElInDoc = Dom.inDocument(oElement);
2883
 
2884
 
2885
            if (oContainer) {
2886
 
2887
                if (oSrcElement && oSrcElement != oElement) {
2888
 
2889
                    oParentNode = oSrcElement.parentNode;
2890
 
2891
                    if (oParentNode) {
2892
 
2893
                        oParentNode.removeChild(oSrcElement);
2894
 
2895
                    }
2896
 
2897
                }
2898
 
2899
                if (Lang.isString(oContainer)) {
2900
 
2901
                    Event.onContentReady(oContainer, this.appendTo, oContainer, this);
2902
 
2903
                }
2904
                else {
2905
 
2906
        			this.on("init", function () {
2907
 
2908
        				Lang.later(0, this, this.appendTo, oContainer);
2909
 
2910
        			});
2911
 
2912
                }
2913
 
2914
            }
2915
            else if (!bElInDoc && oSrcElement && oSrcElement != oElement) {
2916
 
2917
                oParentNode = oSrcElement.parentNode;
2918
 
2919
                if (oParentNode) {
2920
 
2921
                    this.fireEvent("beforeAppendTo", {
2922
                        type: "beforeAppendTo",
2923
                        target: oParentNode
2924
                    });
2925
 
2926
                    oParentNode.replaceChild(oElement, oSrcElement);
2927
 
2928
                    this.fireEvent("appendTo", {
2929
                        type: "appendTo",
2930
                        target: oParentNode
2931
                    });
2932
 
2933
                }
2934
 
2935
            }
2936
            else if (this.get("type") != "link" && bElInDoc && oSrcElement &&
2937
                oSrcElement == oElement) {
2938
 
2939
                this._addListenersToForm();
2940
 
2941
            }
2942
 
2943
            YAHOO.log("Initialization completed.", "info", this.toString());
2944
 
2945
 
2946
			this.fireEvent("init", {
2947
				type: "init",
2948
				target: this
2949
			});
2950
 
2951
        },
2952
 
2953
 
2954
        /**
2955
        * @method initAttributes
2956
        * @description Initializes all of the configuration attributes used to
2957
        * create the button.
2958
        * @param {Object} p_oAttributes Object literal specifying a set of
2959
        * configuration attributes used to create the button.
2960
        */
2961
        initAttributes: function (p_oAttributes) {
2962
 
2963
            var oAttributes = p_oAttributes || {};
2964
 
2965
            YAHOO.widget.Button.superclass.initAttributes.call(this,
2966
                oAttributes);
2967
 
2968
 
2969
            /**
2970
            * @attribute type
2971
            * @description String specifying the button's type.  Possible
2972
            * values are: "push," "link," "submit," "reset," "checkbox,"
2973
            * "radio," "menu," and "split."
2974
            * @default "push"
2975
            * @type String
2976
			* @writeonce
2977
            */
2978
            this.setAttributeConfig("type", {
2979
 
2980
                value: (oAttributes.type || "push"),
2981
                validator: Lang.isString,
2982
                writeOnce: true,
2983
                method: this._setType
2984
 
2985
            });
2986
 
2987
 
2988
            /**
2989
            * @attribute label
2990
            * @description {HTML} specifying the button's text label
2991
            * or innerHTML.
2992
            * @default null
2993
            * @type String
2994
            */
2995
            this.setAttributeConfig("label", {
2996
 
2997
                value: oAttributes.label,
2998
                validator: Lang.isString,
2999
                method: this._setLabel
3000
 
3001
            });
3002
 
3003
 
3004
            /**
3005
            * @attribute value
3006
            * @description Object specifying the value for the button.
3007
            * @default null
3008
            * @type Object
3009
            */
3010
            this.setAttributeConfig("value", {
3011
 
3012
                value: oAttributes.value
3013
 
3014
            });
3015
 
3016
 
3017
            /**
3018
            * @attribute name
3019
            * @description String specifying the name for the button.
3020
            * @default null
3021
            * @type String
3022
            */
3023
            this.setAttributeConfig("name", {
3024
 
3025
                value: oAttributes.name,
3026
                validator: Lang.isString
3027
 
3028
            });
3029
 
3030
 
3031
            /**
3032
            * @attribute tabindex
3033
            * @description Number specifying the tabindex for the button.
3034
            * @default null
3035
            * @type Number
3036
            */
3037
            this.setAttributeConfig("tabindex", {
3038
 
3039
                value: oAttributes.tabindex,
3040
                validator: Lang.isNumber,
3041
                method: this._setTabIndex
3042
 
3043
            });
3044
 
3045
 
3046
            /**
3047
            * @attribute title
3048
            * @description String specifying the title for the button.
3049
            * @default null
3050
            * @type String
3051
            */
3052
            this.configureAttribute("title", {
3053
 
3054
                value: oAttributes.title,
3055
                validator: Lang.isString,
3056
                method: this._setTitle
3057
 
3058
            });
3059
 
3060
 
3061
            /**
3062
            * @attribute disabled
3063
            * @description Boolean indicating if the button should be disabled.
3064
            * (Disabled buttons are dimmed and will not respond to user input
3065
            * or fire events.  Does not apply to button's of type "link.")
3066
            * @default false
3067
            * @type Boolean
3068
            */
3069
            this.setAttributeConfig("disabled", {
3070
 
3071
                value: (oAttributes.disabled || false),
3072
                validator: Lang.isBoolean,
3073
                method: this._setDisabled
3074
 
3075
            });
3076
 
3077
 
3078
            /**
3079
            * @attribute href
3080
            * @description String specifying the href for the button.  Applies
3081
            * only to buttons of type "link."
3082
            * @type String
3083
            */
3084
            this.setAttributeConfig("href", {
3085
 
3086
                value: oAttributes.href,
3087
                validator: Lang.isString,
3088
                method: this._setHref
3089
 
3090
            });
3091
 
3092
 
3093
            /**
3094
            * @attribute target
3095
            * @description String specifying the target for the button.
3096
            * Applies only to buttons of type "link."
3097
            * @type String
3098
            */
3099
            this.setAttributeConfig("target", {
3100
 
3101
                value: oAttributes.target,
3102
                validator: Lang.isString,
3103
                method: this._setTarget
3104
 
3105
            });
3106
 
3107
 
3108
            /**
3109
            * @attribute checked
3110
            * @description Boolean indicating if the button is checked.
3111
            * Applies only to buttons of type "radio" and "checkbox."
3112
            * @default false
3113
            * @type Boolean
3114
            */
3115
            this.setAttributeConfig("checked", {
3116
 
3117
                value: (oAttributes.checked || false),
3118
                validator: Lang.isBoolean,
3119
                method: this._setChecked
3120
 
3121
            });
3122
 
3123
 
3124
            /**
3125
            * @attribute container
3126
            * @description HTML element reference or string specifying the id
3127
            * attribute of the HTML element that the button's markup should be
3128
            * rendered into.
3129
            * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3130
            * level-one-html.html#ID-58190037">HTMLElement</a>|String
3131
            * @default null
3132
			* @writeonce
3133
            */
3134
            this.setAttributeConfig("container", {
3135
 
3136
                value: oAttributes.container,
3137
                writeOnce: true
3138
 
3139
            });
3140
 
3141
 
3142
            /**
3143
            * @attribute srcelement
3144
            * @description Object reference to the HTML element (either
3145
            * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code>)
3146
            * used to create the button.
3147
            * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3148
            * level-one-html.html#ID-58190037">HTMLElement</a>|String
3149
            * @default null
3150
			* @writeonce
3151
            */
3152
            this.setAttributeConfig("srcelement", {
3153
 
3154
                value: oAttributes.srcelement,
3155
                writeOnce: true
3156
 
3157
            });
3158
 
3159
 
3160
            /**
3161
            * @attribute menu
3162
            * @description Object specifying the menu for the button.
3163
            * The value can be one of the following:
3164
            * <ul>
3165
            * <li>Object specifying a rendered <a href="YAHOO.widget.Menu.html">
3166
            * YAHOO.widget.Menu</a> instance.</li>
3167
            * <li>Object specifying a rendered <a href="YAHOO.widget.Overlay.html">
3168
            * YAHOO.widget.Overlay</a> instance.</li>
3169
            * <li>String specifying the id attribute of the <code>&#60;div&#62;
3170
            * </code> element used to create the menu.  By default the menu
3171
            * will be created as an instance of
3172
            * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>.
3173
            * If the <a href="YAHOO.widget.Menu.html#CSS_CLASS_NAME">
3174
            * default CSS class name for YAHOO.widget.Menu</a> is applied to
3175
            * the <code>&#60;div&#62;</code> element, it will be created as an
3176
            * instance of <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu
3177
            * </a>.</li><li>String specifying the id attribute of the
3178
            * <code>&#60;select&#62;</code> element used to create the menu.
3179
            * </li><li>Object specifying the <code>&#60;div&#62;</code> element
3180
            * used to create the menu.</li>
3181
            * <li>Object specifying the <code>&#60;select&#62;</code> element
3182
            * used to create the menu.</li>
3183
            * <li>Array of object literals, each representing a set of
3184
            * <a href="YAHOO.widget.MenuItem.html">YAHOO.widget.MenuItem</a>
3185
            * configuration attributes.</li>
3186
            * <li>Array of strings representing the text labels for each menu
3187
            * item in the menu.</li>
3188
            * </ul>
3189
            * @type <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>|<a
3190
            * href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|<a
3191
            * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3192
            * one-html.html#ID-58190037">HTMLElement</a>|String|Array
3193
            * @default null
3194
			* @writeonce
3195
            */
3196
            this.setAttributeConfig("menu", {
3197
 
3198
                value: null,
3199
                method: this._setMenu,
3200
                writeOnce: true
3201
 
3202
            });
3203
 
3204
 
3205
            /**
3206
            * @attribute lazyloadmenu
3207
            * @description Boolean indicating the value to set for the
3208
            * <a href="YAHOO.widget.Menu.html#lazyLoad">"lazyload"</a>
3209
            * configuration property of the button's menu.  Setting
3210
            * "lazyloadmenu" to <code>true </code> will defer rendering of
3211
            * the button's menu until the first time it is made visible.
3212
            * If "lazyloadmenu" is set to <code>false</code>, the button's
3213
            * menu will be rendered immediately if the button is in the
3214
            * document, or in response to the button's "appendTo" event if
3215
            * the button is not yet in the document.  In either case, the
3216
            * menu is rendered into the button's parent HTML element.
3217
            * <em>This attribute does not apply if a
3218
            * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a> or
3219
            * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>
3220
            * instance is passed as the value of the button's "menu"
3221
            * configuration attribute. <a href="YAHOO.widget.Menu.html">
3222
            * YAHOO.widget.Menu</a> or <a href="YAHOO.widget.Overlay.html">
3223
            * YAHOO.widget.Overlay</a> instances should be rendered before
3224
            * being set as the value for the "menu" configuration
3225
            * attribute.</em>
3226
            * @default true
3227
            * @type Boolean
3228
			* @writeonce
3229
            */
3230
            this.setAttributeConfig("lazyloadmenu", {
3231
 
3232
                value: (oAttributes.lazyloadmenu === false ? false : true),
3233
                validator: Lang.isBoolean,
3234
                writeOnce: true
3235
 
3236
            });
3237
 
3238
 
3239
            /**
3240
            * @attribute menuclassname
3241
            * @description String representing the CSS class name to be
3242
            * applied to the root element of the button's menu.
3243
            * @type String
3244
            * @default "yui-button-menu"
3245
			* @writeonce
3246
            */
3247
            this.setAttributeConfig("menuclassname", {
3248
 
3249
                value: (oAttributes.menuclassname || (this.CLASS_NAME_PREFIX + "button-menu")),
3250
                validator: Lang.isString,
3251
                method: this._setMenuClassName,
3252
                writeOnce: true
3253
 
3254
            });
3255
 
3256
 
3257
			/**
3258
			* @attribute menuminscrollheight
3259
			* @description Number defining the minimum threshold for the "menumaxheight"
3260
			* configuration attribute.  When set this attribute is automatically applied
3261
			* to all submenus.
3262
			* @default 90
3263
			* @type Number
3264
			*/
3265
            this.setAttributeConfig("menuminscrollheight", {
3266
 
3267
                value: (oAttributes.menuminscrollheight || 90),
3268
                validator: Lang.isNumber
3269
 
3270
            });
3271
 
3272
 
3273
            /**
3274
            * @attribute menumaxheight
3275
			* @description Number defining the maximum height (in pixels) for a menu's
3276
			* body element (<code>&#60;div class="bd"&#60;</code>).  Once a menu's body
3277
			* exceeds this height, the contents of the body are scrolled to maintain
3278
			* this value.  This value cannot be set lower than the value of the
3279
			* "minscrollheight" configuration property.
3280
            * @type Number
3281
            * @default 0
3282
            */
3283
            this.setAttributeConfig("menumaxheight", {
3284
 
3285
                value: (oAttributes.menumaxheight || 0),
3286
                validator: Lang.isNumber
3287
 
3288
            });
3289
 
3290
 
3291
            /**
3292
            * @attribute menualignment
3293
			* @description Array defining how the Button's Menu is aligned to the Button.
3294
            * The default value of ["tl", "bl"] aligns the Menu's top left corner to the Button's
3295
            * bottom left corner.
3296
            * @type Array
3297
            * @default ["tl", "bl"]
3298
            */
3299
            this.setAttributeConfig("menualignment", {
3300
 
3301
                value: (oAttributes.menualignment || ["tl", "bl"]),
3302
                validator: Lang.isArray
3303
 
3304
            });
3305
 
3306
 
3307
            /**
3308
            * @attribute selectedMenuItem
3309
            * @description Object representing the item in the button's menu
3310
            * that is currently selected.
3311
            * @type YAHOO.widget.MenuItem
3312
            * @default null
3313
            */
3314
            this.setAttributeConfig("selectedMenuItem", {
3315
 
3316
                value: null
3317
 
3318
            });
3319
 
3320
 
3321
            /**
3322
            * @attribute onclick
3323
            * @description Object literal representing the code to be executed
3324
            * when the button is clicked.  Format:<br> <code> {<br>
3325
            * <strong>fn:</strong> Function,   &#47;&#47; The handler to call
3326
            * when the event fires.<br> <strong>obj:</strong> Object,
3327
            * &#47;&#47; An object to pass back to the handler.<br>
3328
            * <strong>scope:</strong> Object &#47;&#47;  The object to use
3329
            * for the scope of the handler.<br> } </code>
3330
            * @type Object
3331
            * @default null
3332
            */
3333
            this.setAttributeConfig("onclick", {
3334
 
3335
                value: oAttributes.onclick,
3336
                method: this._setOnClick
3337
 
3338
            });
3339
 
3340
 
3341
            /**
3342
            * @attribute focusmenu
3343
            * @description Boolean indicating whether or not the button's menu
3344
            * should be focused when it is made visible.
3345
            * @type Boolean
3346
            * @default true
3347
            */
3348
            this.setAttributeConfig("focusmenu", {
3349
 
3350
                value: (oAttributes.focusmenu === false ? false : true),
3351
                validator: Lang.isBoolean
3352
 
3353
            });
3354
 
3355
 
3356
            /**
3357
            * @attribute replaceLabel
3358
            * @description Boolean indicating whether or not the text of the
3359
			* button's <code>&#60;label&#62;</code> element should be used as
3360
			* the source for the button's label configuration attribute and
3361
			* removed from the DOM.
3362
            * @type Boolean
3363
            * @default false
3364
            */
3365
            this.setAttributeConfig("replaceLabel", {
3366
 
3367
                value: false,
3368
                validator: Lang.isBoolean,
3369
                writeOnce: true
3370
 
3371
            });
3372
 
3373
        },
3374
 
3375
 
3376
        /**
3377
        * @method focus
3378
        * @description Causes the button to receive the focus and fires the
3379
        * button's "focus" event.
3380
        */
3381
        focus: function () {
3382
 
3383
            if (!this.get("disabled")) {
3384
                //Adding a try/catch in case the element is not
3385
                //  visible by the time it's focus is being called.
3386
                //  for example, on a dialog that closes on button click
3387
                try {
3388
                    this._button.focus();
3389
                } catch (e) {}
3390
 
3391
            }
3392
 
3393
        },
3394
 
3395
 
3396
        /**
3397
        * @method blur
3398
        * @description Causes the button to lose focus and fires the button's
3399
        * "blur" event.
3400
        */
3401
        blur: function () {
3402
 
3403
            if (!this.get("disabled")) {
3404
                //Adding a try/catch in case the element is not
3405
                //  visible by the time it's focus is being called.
3406
                //  for example, on a dialog that closes on button click
3407
                try {
3408
                    this._button.blur();
3409
                } catch (e) {}
3410
 
3411
            }
3412
 
3413
        },
3414
 
3415
 
3416
        /**
3417
        * @method hasFocus
3418
        * @description Returns a boolean indicating whether or not the button
3419
        * has focus.
3420
        * @return {Boolean}
3421
        */
3422
        hasFocus: function () {
3423
 
3424
            return (m_oFocusedButton == this);
3425
 
3426
        },
3427
 
3428
 
3429
        /**
3430
        * @method isActive
3431
        * @description Returns a boolean indicating whether or not the button
3432
        * is active.
3433
        * @return {Boolean}
3434
        */
3435
        isActive: function () {
3436
 
3437
            return this.hasClass(this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME + "-active");
3438
 
3439
        },
3440
 
3441
 
3442
        /**
3443
        * @method getMenu
3444
        * @description Returns a reference to the button's menu.
3445
        * @return {<a href="YAHOO.widget.Overlay.html">
3446
        * YAHOO.widget.Overlay</a>|<a
3447
        * href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
3448
        */
3449
        getMenu: function () {
3450
 
3451
            return this._menu;
3452
 
3453
        },
3454
 
3455
 
3456
        /**
3457
        * @method getForm
3458
        * @description Returns a reference to the button's parent form.
3459
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-
3460
        * 20000929/level-one-html.html#ID-40002357">HTMLFormElement</a>}
3461
        */
3462
        getForm: function () {
3463
 
3464
        	var oButton = this._button,
3465
        		oForm;
3466
 
3467
            if (oButton) {
3468
 
3469
            	oForm = oButton.form;
3470
 
3471
            }
3472
 
3473
        	return oForm;
3474
 
3475
        },
3476
 
3477
 
3478
        /**
3479
        * @method getHiddenFields
3480
        * @description Returns an <code>&#60;input&#62;</code> element or
3481
        * array of form elements used to represent the button when its parent
3482
        * form is submitted.
3483
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3484
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
3485
        */
3486
        getHiddenFields: function () {
3487
 
3488
            return this._hiddenFields;
3489
 
3490
        },
3491
 
3492
 
3493
        /**
3494
        * @method destroy
3495
        * @description Removes the button's element from its parent element and
3496
        * removes all event handlers.
3497
        */
3498
        destroy: function () {
3499
 
3500
            YAHOO.log("Destroying ...", "info", this.toString());
3501
 
3502
            var oElement = this.get("element"),
3503
                oMenu = this._menu,
3504
				oLabel = this._label,
3505
                oParentNode,
3506
                aButtons;
3507
 
3508
            if (oMenu) {
3509
 
3510
                YAHOO.log("Destroying menu.", "info", this.toString());
3511
 
3512
                if (m_oOverlayManager && m_oOverlayManager.find(oMenu)) {
3513
 
3514
                    m_oOverlayManager.remove(oMenu);
3515
 
3516
                }
3517
 
3518
                oMenu.destroy();
3519
 
3520
            }
3521
 
3522
            YAHOO.log("Removing DOM event listeners.", "info", this.toString());
3523
 
3524
            Event.purgeElement(oElement);
3525
            Event.purgeElement(this._button);
3526
            Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
3527
            Event.removeListener(document, "keyup", this._onDocumentKeyUp);
3528
            Event.removeListener(document, "mousedown", this._onDocumentMouseDown);
3529
 
3530
 
3531
			if (oLabel) {
3532
 
3533
            	Event.removeListener(oLabel, "click", this._onLabelClick);
3534
 
3535
				oParentNode = oLabel.parentNode;
3536
				oParentNode.removeChild(oLabel);
3537
 
3538
			}
3539
 
3540
 
3541
            var oForm = this.getForm();
3542
 
3543
            if (oForm) {
3544
 
3545
                Event.removeListener(oForm, "reset", this._onFormReset);
3546
                Event.removeListener(oForm, "submit", this._onFormSubmit);
3547
 
3548
            }
3549
 
3550
            YAHOO.log("Removing CustomEvent listeners.", "info", this.toString());
3551
 
3552
            this.unsubscribeAll();
3553
 
3554
			oParentNode = oElement.parentNode;
3555
 
3556
            if (oParentNode) {
3557
 
3558
                oParentNode.removeChild(oElement);
3559
 
3560
            }
3561
 
3562
            YAHOO.log("Removing from document.", "info", this.toString());
3563
 
3564
            delete m_oButtons[this.get("id")];
3565
 
3566
			var sClass = (this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME);
3567
 
3568
            aButtons = Dom.getElementsByClassName(sClass,
3569
                                this.NODE_NAME, oForm);
3570
 
3571
            if (Lang.isArray(aButtons) && aButtons.length === 0) {
3572
 
3573
                Event.removeListener(oForm, "keypress",
3574
                        YAHOO.widget.Button.onFormKeyPress);
3575
 
3576
            }
3577
 
3578
            YAHOO.log("Destroyed.", "info", this.toString());
3579
 
3580
        },
3581
 
3582
 
3583
        fireEvent: function (p_sType , p_aArgs) {
3584
 
3585
			var sType = arguments[0];
3586
 
3587
			//  Disabled buttons should not respond to DOM events
3588
 
3589
			if (this.DOM_EVENTS[sType] && this.get("disabled")) {
3590
 
3591
				return false;
3592
 
3593
			}
3594
 
3595
			return YAHOO.widget.Button.superclass.fireEvent.apply(this, arguments);
3596
 
3597
        },
3598
 
3599
 
3600
        /**
3601
        * @method toString
3602
        * @description Returns a string representing the button.
3603
        * @return {String}
3604
        */
3605
        toString: function () {
3606
 
3607
            return ("Button " + this.get("id"));
3608
 
3609
        }
3610
 
3611
    });
3612
 
3613
 
3614
    /**
3615
    * @method YAHOO.widget.Button.onFormKeyPress
3616
    * @description "keypress" event handler for the button's form.
3617
    * @param {Event} p_oEvent Object representing the DOM event object passed
3618
    * back by the event utility (YAHOO.util.Event).
3619
    */
3620
    YAHOO.widget.Button.onFormKeyPress = function (p_oEvent) {
3621
 
3622
        var oTarget = Event.getTarget(p_oEvent),
3623
            nCharCode = Event.getCharCode(p_oEvent),
3624
            sNodeName = oTarget.nodeName && oTarget.nodeName.toUpperCase(),
3625
            sType = oTarget.type,
3626
 
3627
            /*
3628
                Boolean indicating if the form contains any enabled or
3629
                disabled YUI submit buttons
3630
            */
3631
 
3632
            bFormContainsYUIButtons = false,
3633
 
3634
            oButton,
3635
 
3636
            oYUISubmitButton,   // The form's first, enabled YUI submit button
3637
 
3638
            /*
3639
                 The form's first, enabled HTML submit button that precedes any
3640
                 YUI submit button
3641
            */
3642
 
3643
            oPrecedingSubmitButton,
3644
 
3645
            oEvent;
3646
 
3647
 
3648
        function isSubmitButton(p_oElement) {
3649
 
3650
            var sId,
3651
                oSrcElement;
3652
 
3653
            switch (p_oElement.nodeName.toUpperCase()) {
3654
 
3655
            case "INPUT":
3656
            case "BUTTON":
3657
 
3658
                if (p_oElement.type == "submit" && !p_oElement.disabled) {
3659
 
3660
                    if (!bFormContainsYUIButtons && !oPrecedingSubmitButton) {
3661
 
3662
                        oPrecedingSubmitButton = p_oElement;
3663
 
3664
                    }
3665
 
3666
                }
3667
 
3668
                break;
3669
 
3670
 
3671
            default:
3672
 
3673
                sId = p_oElement.id;
3674
 
3675
                if (sId) {
3676
 
3677
                    oButton = m_oButtons[sId];
3678
 
3679
                    if (oButton) {
3680
 
3681
                        bFormContainsYUIButtons = true;
3682
 
3683
                        if (!oButton.get("disabled")) {
3684
 
3685
                            oSrcElement = oButton.get("srcelement");
3686
 
3687
                            if (!oYUISubmitButton && (oButton.get("type") == "submit" ||
3688
                                (oSrcElement && oSrcElement.type == "submit"))) {
3689
 
3690
                                oYUISubmitButton = oButton;
3691
 
3692
                            }
3693
 
3694
                        }
3695
 
3696
                    }
3697
 
3698
                }
3699
 
3700
                break;
3701
 
3702
            }
3703
 
3704
        }
3705
 
3706
 
3707
        if (nCharCode == 13 && ((sNodeName == "INPUT" && (sType == "text" ||
3708
            sType == "password" || sType == "checkbox" || sType == "radio" ||
3709
            sType == "file")) || sNodeName == "SELECT")) {
3710
 
3711
            Dom.getElementsBy(isSubmitButton, "*", this);
3712
 
3713
 
3714
            if (oPrecedingSubmitButton) {
3715
 
3716
                /*
3717
                     Need to set focus to the first enabled submit button
3718
                     to make sure that IE includes its name and value
3719
                     in the form's data set.
3720
                */
3721
 
3722
                oPrecedingSubmitButton.focus();
3723
 
3724
            }
3725
            else if (!oPrecedingSubmitButton && oYUISubmitButton) {
3726
 
3727
				/*
3728
					Need to call "preventDefault" to ensure that the form doesn't end up getting
3729
					submitted twice.
3730
				*/
3731
 
3732
    			Event.preventDefault(p_oEvent);
3733
 
3734
 
3735
				if (UA.ie) {
3736
 
3737
					oYUISubmitButton.get("element").fireEvent("onclick");
3738
 
3739
				}
3740
				else {
3741
 
3742
					oEvent = document.createEvent("HTMLEvents");
3743
					oEvent.initEvent("click", true, true);
3744
 
3745
 
3746
					if (UA.gecko < 1.9) {
3747
 
3748
						oYUISubmitButton.fireEvent("click", oEvent);
3749
 
3750
					}
3751
					else {
3752
 
3753
						oYUISubmitButton.get("element").dispatchEvent(oEvent);
3754
 
3755
					}
3756
 
3757
                }
3758
 
3759
            }
3760
 
3761
        }
3762
 
3763
    };
3764
 
3765
 
3766
    /**
3767
    * @method YAHOO.widget.Button.addHiddenFieldsToForm
3768
    * @description Searches the specified form and adds hidden fields for
3769
    * instances of YAHOO.widget.Button that are of type "radio," "checkbox,"
3770
    * "menu," and "split."
3771
    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3772
    * one-html.html#ID-40002357">HTMLFormElement</a>} p_oForm Object reference
3773
    * for the form to search.
3774
    */
3775
    YAHOO.widget.Button.addHiddenFieldsToForm = function (p_oForm) {
3776
 
3777
        var proto = YAHOO.widget.Button.prototype,
3778
			aButtons = Dom.getElementsByClassName(
3779
							(proto.CLASS_NAME_PREFIX + proto.CSS_CLASS_NAME),
3780
                            "*",
3781
                            p_oForm),
3782
 
3783
            nButtons = aButtons.length,
3784
            oButton,
3785
            sId,
3786
            i;
3787
 
3788
        if (nButtons > 0) {
3789
 
3790
            YAHOO.log("Form contains " + nButtons + " YUI buttons.", "info", this.toString());
3791
 
3792
            for (i = 0; i < nButtons; i++) {
3793
 
3794
                sId = aButtons[i].id;
3795
 
3796
                if (sId) {
3797
 
3798
                    oButton = m_oButtons[sId];
3799
 
3800
                    if (oButton) {
3801
 
3802
                        oButton.createHiddenFields();
3803
 
3804
                    }
3805
 
3806
                }
3807
 
3808
            }
3809
 
3810
        }
3811
 
3812
    };
3813
 
3814
 
3815
    /**
3816
    * @method YAHOO.widget.Button.getButton
3817
    * @description Returns a button with the specified id.
3818
    * @param {String} p_sId String specifying the id of the root node of the
3819
    * HTML element representing the button to be retrieved.
3820
    * @return {YAHOO.widget.Button}
3821
    */
3822
    YAHOO.widget.Button.getButton = function (p_sId) {
3823
 
3824
		return m_oButtons[p_sId];
3825
 
3826
    };
3827
 
3828
 
3829
    // Events
3830
 
3831
 
3832
    /**
3833
    * @event focus
3834
    * @description Fires when the menu item receives focus.  Passes back a
3835
    * single object representing the original DOM event object passed back by
3836
    * the event utility (YAHOO.util.Event) when the event was fired.  See
3837
    * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
3838
    * for more information on listening for this event.
3839
    * @type YAHOO.util.CustomEvent
3840
    */
3841
 
3842
 
3843
    /**
3844
    * @event blur
3845
    * @description Fires when the menu item loses the input focus.  Passes back
3846
    * a single object representing the original DOM event object passed back by
3847
    * the event utility (YAHOO.util.Event) when the event was fired.  See
3848
    * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for
3849
    * more information on listening for this event.
3850
    * @type YAHOO.util.CustomEvent
3851
    */
3852
 
3853
 
3854
    /**
3855
    * @event option
3856
    * @description Fires when the user invokes the button's option.  Passes
3857
    * back a single object representing the original DOM event (either
3858
    * "mousedown" or "keydown") that caused the "option" event to fire.  See
3859
    * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
3860
    * for more information on listening for this event.
3861
    * @type YAHOO.util.CustomEvent
3862
    */
3863
 
3864
})();
3865
(function () {
3866
 
3867
    // Shorthard for utilities
3868
 
3869
    var Dom = YAHOO.util.Dom,
3870
        Event = YAHOO.util.Event,
3871
        Lang = YAHOO.lang,
3872
        Button = YAHOO.widget.Button,
3873
 
3874
        // Private collection of radio buttons
3875
 
3876
        m_oButtons = {};
3877
 
3878
 
3879
 
3880
    /**
3881
    * The ButtonGroup class creates a set of buttons that are mutually
3882
    * exclusive; checking one button in the set will uncheck all others in the
3883
    * button group.
3884
    * @param {String} p_oElement String specifying the id attribute of the
3885
    * <code>&#60;div&#62;</code> element of the button group.
3886
    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3887
    * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
3888
    * specifying the <code>&#60;div&#62;</code> element of the button group.
3889
    * @param {Object} p_oElement Object literal specifying a set of
3890
    * configuration attributes used to create the button group.
3891
    * @param {Object} p_oAttributes Optional. Object literal specifying a set
3892
    * of configuration attributes used to create the button group.
3893
    * @namespace YAHOO.widget
3894
    * @class ButtonGroup
3895
    * @constructor
3896
    * @extends YAHOO.util.Element
3897
    */
3898
    YAHOO.widget.ButtonGroup = function (p_oElement, p_oAttributes) {
3899
 
3900
        var fnSuperClass = YAHOO.widget.ButtonGroup.superclass.constructor,
3901
            sNodeName,
3902
            oElement,
3903
            sId;
3904
 
3905
        if (arguments.length == 1 && !Lang.isString(p_oElement) &&
3906
            !p_oElement.nodeName) {
3907
 
3908
            if (!p_oElement.id) {
3909
 
3910
                sId = Dom.generateId();
3911
 
3912
                p_oElement.id = sId;
3913
 
3914
                YAHOO.log("No value specified for the button group's \"id\"" +
3915
                    " attribute. Setting button group id to \"" + sId + "\".",
3916
                    "info");
3917
 
3918
            }
3919
 
3920
            this.logger = new YAHOO.widget.LogWriter("ButtonGroup " + sId);
3921
 
3922
            this.logger.log("No source HTML element.  Building the button " +
3923
                    "group using the set of configuration attributes.");
3924
 
3925
            fnSuperClass.call(this, (this._createGroupElement()), p_oElement);
3926
 
3927
        }
3928
        else if (Lang.isString(p_oElement)) {
3929
 
3930
            oElement = Dom.get(p_oElement);
3931
 
3932
            if (oElement) {
3933
 
3934
                if (oElement.nodeName.toUpperCase() == this.NODE_NAME) {
3935
 
3936
                    this.logger =
3937
                        new YAHOO.widget.LogWriter("ButtonGroup " + p_oElement);
3938
 
3939
                    fnSuperClass.call(this, oElement, p_oAttributes);
3940
 
3941
                }
3942
 
3943
            }
3944
 
3945
        }
3946
        else {
3947
 
3948
            sNodeName = p_oElement.nodeName.toUpperCase();
3949
 
3950
            if (sNodeName && sNodeName == this.NODE_NAME) {
3951
 
3952
                if (!p_oElement.id) {
3953
 
3954
                    p_oElement.id = Dom.generateId();
3955
 
3956
                    YAHOO.log("No value specified for the button group's" +
3957
                        " \"id\" attribute. Setting button group id " +
3958
                        "to \"" + p_oElement.id + "\".", "warn");
3959
 
3960
                }
3961
 
3962
                this.logger =
3963
                    new YAHOO.widget.LogWriter("ButtonGroup " + p_oElement.id);
3964
 
3965
                fnSuperClass.call(this, p_oElement, p_oAttributes);
3966
 
3967
            }
3968
 
3969
        }
3970
 
3971
    };
3972
 
3973
 
3974
    YAHOO.extend(YAHOO.widget.ButtonGroup, YAHOO.util.Element, {
3975
 
3976
 
3977
        // Protected properties
3978
 
3979
 
3980
        /**
3981
        * @property _buttons
3982
        * @description Array of buttons in the button group.
3983
        * @default null
3984
        * @protected
3985
        * @type Array
3986
        */
3987
        _buttons: null,
3988
 
3989
 
3990
 
3991
        // Constants
3992
 
3993
 
3994
        /**
3995
        * @property NODE_NAME
3996
        * @description The name of the tag to be used for the button
3997
        * group's element.
3998
        * @default "DIV"
3999
        * @final
4000
        * @type String
4001
        */
4002
        NODE_NAME: "DIV",
4003
 
4004
 
4005
        /**
4006
        * @property CLASS_NAME_PREFIX
4007
        * @description Prefix used for all class names applied to a ButtonGroup.
4008
        * @default "yui-"
4009
        * @final
4010
        * @type String
4011
        */
4012
        CLASS_NAME_PREFIX: "yui-",
4013
 
4014
 
4015
        /**
4016
        * @property CSS_CLASS_NAME
4017
        * @description String representing the CSS class(es) to be applied
4018
        * to the button group's element.
4019
        * @default "buttongroup"
4020
        * @final
4021
        * @type String
4022
        */
4023
        CSS_CLASS_NAME: "buttongroup",
4024
 
4025
 
4026
 
4027
        // Protected methods
4028
 
4029
 
4030
        /**
4031
        * @method _createGroupElement
4032
        * @description Creates the button group's element.
4033
        * @protected
4034
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4035
        * level-one-html.html#ID-22445964">HTMLDivElement</a>}
4036
        */
4037
        _createGroupElement: function () {
4038
 
4039
            var oElement = document.createElement(this.NODE_NAME);
4040
 
4041
            return oElement;
4042
 
4043
        },
4044
 
4045
 
4046
 
4047
        // Protected attribute setter methods
4048
 
4049
 
4050
        /**
4051
        * @method _setDisabled
4052
        * @description Sets the value of the button groups's
4053
        * "disabled" attribute.
4054
        * @protected
4055
        * @param {Boolean} p_bDisabled Boolean indicating the value for
4056
        * the button group's "disabled" attribute.
4057
        */
4058
        _setDisabled: function (p_bDisabled) {
4059
 
4060
            var nButtons = this.getCount(),
4061
                i;
4062
 
4063
            if (nButtons > 0) {
4064
 
4065
                i = nButtons - 1;
4066
 
4067
                do {
4068
 
4069
                    this._buttons[i].set("disabled", p_bDisabled);
4070
 
4071
                }
4072
                while (i--);
4073
 
4074
            }
4075
 
4076
        },
4077
 
4078
 
4079
 
4080
        // Protected event handlers
4081
 
4082
 
4083
        /**
4084
        * @method _onKeyDown
4085
        * @description "keydown" event handler for the button group.
4086
        * @protected
4087
        * @param {Event} p_oEvent Object representing the DOM event object
4088
        * passed back by the event utility (YAHOO.util.Event).
4089
        */
4090
        _onKeyDown: function (p_oEvent) {
4091
 
4092
            var oTarget = Event.getTarget(p_oEvent),
4093
                nCharCode = Event.getCharCode(p_oEvent),
4094
                sId = oTarget.parentNode.parentNode.id,
4095
                oButton = m_oButtons[sId],
4096
                nIndex = -1;
4097
 
4098
 
4099
            if (nCharCode == 37 || nCharCode == 38) {
4100
 
4101
                nIndex = (oButton.index === 0) ?
4102
                            (this._buttons.length - 1) : (oButton.index - 1);
4103
 
4104
            }
4105
            else if (nCharCode == 39 || nCharCode == 40) {
4106
 
4107
                nIndex = (oButton.index === (this._buttons.length - 1)) ?
4108
 
4109
 
4110
            }
4111
 
4112
 
4113
            if (nIndex > -1) {
4114
 
4115
                this.check(nIndex);
4116
                this.getButton(nIndex).focus();
4117
 
4118
            }
4119
 
4120
        },
4121
 
4122
 
4123
        /**
4124
        * @method _onAppendTo
4125
        * @description "appendTo" event handler for the button group.
4126
        * @protected
4127
        * @param {Event} p_oEvent Object representing the event that was fired.
4128
        */
4129
        _onAppendTo: function (p_oEvent) {
4130
 
4131
            var aButtons = this._buttons,
4132
                nButtons = aButtons.length,
4133
                i;
4134
 
4135
            for (i = 0; i < nButtons; i++) {
4136
 
4137
                aButtons[i].appendTo(this.get("element"));
4138
 
4139
            }
4140
 
4141
        },
4142
 
4143
 
4144
        /**
4145
        * @method _onButtonCheckedChange
4146
        * @description "checkedChange" event handler for each button in the
4147
        * button group.
4148
        * @protected
4149
        * @param {Event} p_oEvent Object representing the event that was fired.
4150
        * @param {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4151
        * p_oButton Object representing the button that fired the event.
4152
        */
4153
        _onButtonCheckedChange: function (p_oEvent, p_oButton) {
4154
 
4155
            var bChecked = p_oEvent.newValue,
4156
                oCheckedButton = this.get("checkedButton");
4157
 
4158
            if (bChecked && oCheckedButton != p_oButton) {
4159
 
4160
                if (oCheckedButton) {
4161
 
4162
                    oCheckedButton.set("checked", false, true);
4163
 
4164
                }
4165
 
4166
                this.set("checkedButton", p_oButton);
4167
                this.set("value", p_oButton.get("value"));
4168
 
4169
            }
4170
            else if (oCheckedButton && !oCheckedButton.set("checked")) {
4171
 
4172
                oCheckedButton.set("checked", true, true);
4173
 
4174
            }
4175
 
4176
        },
4177
 
4178
 
4179
 
4180
        // Public methods
4181
 
4182
 
4183
        /**
4184
        * @method init
4185
        * @description The ButtonGroup class's initialization method.
4186
        * @param {String} p_oElement String specifying the id attribute of the
4187
        * <code>&#60;div&#62;</code> element of the button group.
4188
        * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4189
        * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
4190
        * specifying the <code>&#60;div&#62;</code> element of the button group.
4191
        * @param {Object} p_oElement Object literal specifying a set of
4192
        * configuration attributes used to create the button group.
4193
        * @param {Object} p_oAttributes Optional. Object literal specifying a
4194
        * set of configuration attributes used to create the button group.
4195
        */
4196
        init: function (p_oElement, p_oAttributes) {
4197
 
4198
            this._buttons = [];
4199
 
4200
            YAHOO.widget.ButtonGroup.superclass.init.call(this, p_oElement,
4201
                    p_oAttributes);
4202
 
4203
            this.addClass(this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME);
4204
 
4205
 
4206
            var sClass = (YAHOO.widget.Button.prototype.CLASS_NAME_PREFIX + "radio-button"),
4207
				aButtons = this.getElementsByClassName(sClass);
4208
 
4209
            this.logger.log("Searching for child nodes with the class name " +
4210
                sClass + " to add to the button group.");
4211
 
4212
 
4213
            if (aButtons.length > 0) {
4214
 
4215
                this.logger.log("Found " + aButtons.length +
4216
                    " child nodes with the class name " + sClass +
4217
                    "  Attempting to add to button group.");
4218
 
4219
                this.addButtons(aButtons);
4220
 
4221
            }
4222
 
4223
 
4224
            this.logger.log("Searching for child nodes with the type of " +
4225
                " \"radio\" to add to the button group.");
4226
 
4227
            function isRadioButton(p_oElement) {
4228
 
4229
                return (p_oElement.type == "radio");
4230
 
4231
            }
4232
 
4233
            aButtons =
4234
                Dom.getElementsBy(isRadioButton, "input", this.get("element"));
4235
 
4236
 
4237
            if (aButtons.length > 0) {
4238
 
4239
                this.logger.log("Found " + aButtons.length + " child nodes" +
4240
                    " with the type of \"radio.\"  Attempting to add to" +
4241
                    " button group.");
4242
 
4243
                this.addButtons(aButtons);
4244
 
4245
            }
4246
 
4247
            this.on("keydown", this._onKeyDown);
4248
            this.on("appendTo", this._onAppendTo);
4249
 
4250
 
4251
            var oContainer = this.get("container");
4252
 
4253
            if (oContainer) {
4254
 
4255
                if (Lang.isString(oContainer)) {
4256
 
4257
                    Event.onContentReady(oContainer, function () {
4258
 
4259
                        this.appendTo(oContainer);
4260
 
4261
                    }, null, this);
4262
 
4263
                }
4264
                else {
4265
 
4266
                    this.appendTo(oContainer);
4267
 
4268
                }
4269
 
4270
            }
4271
 
4272
 
4273
            this.logger.log("Initialization completed.");
4274
 
4275
        },
4276
 
4277
 
4278
        /**
4279
        * @method initAttributes
4280
        * @description Initializes all of the configuration attributes used to
4281
        * create the button group.
4282
        * @param {Object} p_oAttributes Object literal specifying a set of
4283
        * configuration attributes used to create the button group.
4284
        */
4285
        initAttributes: function (p_oAttributes) {
4286
 
4287
            var oAttributes = p_oAttributes || {};
4288
 
4289
            YAHOO.widget.ButtonGroup.superclass.initAttributes.call(
4290
                this, oAttributes);
4291
 
4292
 
4293
            /**
4294
            * @attribute name
4295
            * @description String specifying the name for the button group.
4296
            * This name will be applied to each button in the button group.
4297
            * @default null
4298
            * @type String
4299
            */
4300
            this.setAttributeConfig("name", {
4301
 
4302
                value: oAttributes.name,
4303
                validator: Lang.isString
4304
 
4305
            });
4306
 
4307
 
4308
            /**
4309
            * @attribute disabled
4310
            * @description Boolean indicating if the button group should be
4311
            * disabled.  Disabling the button group will disable each button
4312
            * in the button group.  Disabled buttons are dimmed and will not
4313
            * respond to user input or fire events.
4314
            * @default false
4315
            * @type Boolean
4316
            */
4317
            this.setAttributeConfig("disabled", {
4318
 
4319
                value: (oAttributes.disabled || false),
4320
                validator: Lang.isBoolean,
4321
                method: this._setDisabled
4322
 
4323
            });
4324
 
4325
 
4326
            /**
4327
            * @attribute value
4328
            * @description Object specifying the value for the button group.
4329
            * @default null
4330
            * @type Object
4331
            */
4332
            this.setAttributeConfig("value", {
4333
 
4334
                value: oAttributes.value
4335
 
4336
            });
4337
 
4338
 
4339
            /**
4340
            * @attribute container
4341
            * @description HTML element reference or string specifying the id
4342
            * attribute of the HTML element that the button group's markup
4343
            * should be rendered into.
4344
            * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4345
            * level-one-html.html#ID-58190037">HTMLElement</a>|String
4346
            * @default null
4347
			* @writeonce
4348
            */
4349
            this.setAttributeConfig("container", {
4350
 
4351
                value: oAttributes.container,
4352
                writeOnce: true
4353
 
4354
            });
4355
 
4356
 
4357
            /**
4358
            * @attribute checkedButton
4359
            * @description Reference for the button in the button group that
4360
            * is checked.
4361
            * @type {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4362
            * @default null
4363
            */
4364
            this.setAttributeConfig("checkedButton", {
4365
 
4366
                value: null
4367
 
4368
            });
4369
 
4370
        },
4371
 
4372
 
4373
        /**
4374
        * @method addButton
4375
        * @description Adds the button to the button group.
4376
        * @param {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4377
        * p_oButton Object reference for the <a href="YAHOO.widget.Button.html">
4378
        * YAHOO.widget.Button</a> instance to be added to the button group.
4379
        * @param {String} p_oButton String specifying the id attribute of the
4380
        * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code> element
4381
        * to be used to create the button to be added to the button group.
4382
        * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4383
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="
4384
        * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#
4385
        * ID-33759296">HTMLElement</a>} p_oButton Object reference for the
4386
        * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code> element
4387
        * to be used to create the button to be added to the button group.
4388
        * @param {Object} p_oButton Object literal specifying a set of
4389
        * <a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>
4390
        * configuration attributes used to configure the button to be added to
4391
        * the button group.
4392
        * @return {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4393
        */
4394
        addButton: function (p_oButton) {
4395
 
4396
            var oButton,
4397
                oButtonElement,
4398
                oGroupElement,
4399
                nIndex,
4400
                sButtonName,
4401
                sGroupName;
4402
 
4403
 
4404
            if (p_oButton instanceof Button &&
4405
                p_oButton.get("type") == "radio") {
4406
 
4407
                oButton = p_oButton;
4408
 
4409
            }
4410
            else if (!Lang.isString(p_oButton) && !p_oButton.nodeName) {
4411
 
4412
                p_oButton.type = "radio";
4413
 
4414
                oButton = new Button(p_oButton);
4415
 
4416
            }
4417
            else {
4418
 
4419
                oButton = new Button(p_oButton, { type: "radio" });
4420
 
4421
            }
4422
 
4423
 
4424
            if (oButton) {
4425
 
4426
                nIndex = this._buttons.length;
4427
                sButtonName = oButton.get("name");
4428
                sGroupName = this.get("name");
4429
 
4430
                oButton.index = nIndex;
4431
 
4432
                this._buttons[nIndex] = oButton;
4433
                m_oButtons[oButton.get("id")] = oButton;
4434
 
4435
 
4436
                if (sButtonName != sGroupName) {
4437
 
4438
                    oButton.set("name", sGroupName);
4439
 
4440
                }
4441
 
4442
 
4443
                if (this.get("disabled")) {
4444
 
4445
                    oButton.set("disabled", true);
4446
 
4447
                }
4448
 
4449
 
4450
                if (oButton.get("checked")) {
4451
 
4452
                    this.set("checkedButton", oButton);
4453
 
4454
                }
4455
 
4456
 
4457
                oButtonElement = oButton.get("element");
4458
                oGroupElement = this.get("element");
4459
 
4460
                if (oButtonElement.parentNode != oGroupElement) {
4461
 
4462
                    oGroupElement.appendChild(oButtonElement);
4463
 
4464
                }
4465
 
4466
 
4467
                oButton.on("checkedChange",
4468
                    this._onButtonCheckedChange, oButton, this);
4469
 
4470
                this.logger.log("Button " + oButton.get("id") + " added.");
4471
 
4472
            }
4473
 
4474
			return oButton;
4475
 
4476
        },
4477
 
4478
 
4479
        /**
4480
        * @method addButtons
4481
        * @description Adds the array of buttons to the button group.
4482
        * @param {Array} p_aButtons Array of <a href="YAHOO.widget.Button.html">
4483
        * YAHOO.widget.Button</a> instances to be added
4484
        * to the button group.
4485
        * @param {Array} p_aButtons Array of strings specifying the id
4486
        * attribute of the <code>&#60;input&#62;</code> or <code>&#60;span&#62;
4487
        * </code> elements to be used to create the buttons to be added to the
4488
        * button group.
4489
        * @param {Array} p_aButtons Array of object references for the
4490
        * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code> elements
4491
        * to be used to create the buttons to be added to the button group.
4492
        * @param {Array} p_aButtons Array of object literals, each containing
4493
        * a set of <a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>
4494
        * configuration attributes used to configure each button to be added
4495
        * to the button group.
4496
        * @return {Array}
4497
        */
4498
        addButtons: function (p_aButtons) {
4499
 
4500
            var nButtons,
4501
                oButton,
4502
                aButtons,
4503
                i;
4504
 
4505
            if (Lang.isArray(p_aButtons)) {
4506
 
4507
                nButtons = p_aButtons.length;
4508
                aButtons = [];
4509
 
4510
                if (nButtons > 0) {
4511
 
4512
                    for (i = 0; i < nButtons; i++) {
4513
 
4514
                        oButton = this.addButton(p_aButtons[i]);
4515
 
4516
                        if (oButton) {
4517
 
4518
                            aButtons[aButtons.length] = oButton;
4519
 
4520
                        }
4521
 
4522
                    }
4523
 
4524
                }
4525
 
4526
            }
4527
 
4528
			return aButtons;
4529
 
4530
        },
4531
 
4532
 
4533
        /**
4534
        * @method removeButton
4535
        * @description Removes the button at the specified index from the
4536
        * button group.
4537
        * @param {Number} p_nIndex Number specifying the index of the button
4538
        * to be removed from the button group.
4539
        */
4540
        removeButton: function (p_nIndex) {
4541
 
4542
            var oButton = this.getButton(p_nIndex),
4543
                nButtons,
4544
                i;
4545
 
4546
            if (oButton) {
4547
 
4548
                this.logger.log("Removing button " + oButton.get("id") + ".");
4549
 
4550
                this._buttons.splice(p_nIndex, 1);
4551
                delete m_oButtons[oButton.get("id")];
4552
 
4553
                oButton.removeListener("checkedChange",
4554
                    this._onButtonCheckedChange);
4555
 
4556
                oButton.destroy();
4557
 
4558
 
4559
                nButtons = this._buttons.length;
4560
 
4561
                if (nButtons > 0) {
4562
 
4563
                    i = this._buttons.length - 1;
4564
 
4565
                    do {
4566
 
4567
                        this._buttons[i].index = i;
4568
 
4569
                    }
4570
                    while (i--);
4571
 
4572
                }
4573
 
4574
                this.logger.log("Button " + oButton.get("id") + " removed.");
4575
 
4576
            }
4577
 
4578
        },
4579
 
4580
 
4581
        /**
4582
        * @method getButton
4583
        * @description Returns the button at the specified index.
4584
        * @param {Number} p_nIndex The index of the button to retrieve from the
4585
        * button group.
4586
        * @return {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4587
        */
4588
        getButton: function (p_nIndex) {
4589
 
4590
            return this._buttons[p_nIndex];
4591
 
4592
        },
4593
 
4594
 
4595
        /**
4596
        * @method getButtons
4597
        * @description Returns an array of the buttons in the button group.
4598
        * @return {Array}
4599
        */
4600
        getButtons: function () {
4601
 
4602
            return this._buttons;
4603
 
4604
        },
4605
 
4606
 
4607
        /**
4608
        * @method getCount
4609
        * @description Returns the number of buttons in the button group.
4610
        * @return {Number}
4611
        */
4612
        getCount: function () {
4613
 
4614
            return this._buttons.length;
4615
 
4616
        },
4617
 
4618
 
4619
        /**
4620
        * @method focus
4621
        * @description Sets focus to the button at the specified index.
4622
        * @param {Number} p_nIndex Number indicating the index of the button
4623
        * to focus.
4624
        */
4625
        focus: function (p_nIndex) {
4626
 
4627
            var oButton,
4628
                nButtons,
4629
                i;
4630
 
4631
            if (Lang.isNumber(p_nIndex)) {
4632
 
4633
                oButton = this._buttons[p_nIndex];
4634
 
4635
                if (oButton) {
4636
 
4637
                    oButton.focus();
4638
 
4639
                }
4640
 
4641
            }
4642
            else {
4643
 
4644
                nButtons = this.getCount();
4645
 
4646
                for (i = 0; i < nButtons; i++) {
4647
 
4648
                    oButton = this._buttons[i];
4649
 
4650
                    if (!oButton.get("disabled")) {
4651
 
4652
                        oButton.focus();
4653
                        break;
4654
 
4655
                    }
4656
 
4657
                }
4658
 
4659
            }
4660
 
4661
        },
4662
 
4663
 
4664
        /**
4665
        * @method check
4666
        * @description Checks the button at the specified index.
4667
        * @param {Number} p_nIndex Number indicating the index of the button
4668
        * to check.
4669
        */
4670
        check: function (p_nIndex) {
4671
 
4672
            var oButton = this.getButton(p_nIndex);
4673
 
4674
            if (oButton) {
4675
 
4676
                oButton.set("checked", true);
4677
 
4678
            }
4679
 
4680
        },
4681
 
4682
 
4683
        /**
4684
        * @method destroy
4685
        * @description Removes the button group's element from its parent
4686
        * element and removes all event handlers.
4687
        */
4688
        destroy: function () {
4689
 
4690
            this.logger.log("Destroying...");
4691
 
4692
            var nButtons = this._buttons.length,
4693
                oElement = this.get("element"),
4694
                oParentNode = oElement.parentNode,
4695
                i;
4696
 
4697
            if (nButtons > 0) {
4698
 
4699
                i = this._buttons.length - 1;
4700
 
4701
                do {
4702
 
4703
                    this._buttons[i].destroy();
4704
 
4705
                }
4706
                while (i--);
4707
 
4708
            }
4709
 
4710
            this.logger.log("Removing DOM event handlers.");
4711
 
4712
            Event.purgeElement(oElement);
4713
 
4714
            this.logger.log("Removing from document.");
4715
 
4716
            oParentNode.removeChild(oElement);
4717
 
4718
        },
4719
 
4720
 
4721
        /**
4722
        * @method toString
4723
        * @description Returns a string representing the button group.
4724
        * @return {String}
4725
        */
4726
        toString: function () {
4727
 
4728
            return ("ButtonGroup " + this.get("id"));
4729
 
4730
        }
4731
 
4732
    });
4733
 
4734
})();
4735
YAHOO.register("button", YAHOO.widget.Button, {version: "2.9.0", build: "2800"});
4736
 
4737
}, '2.9.0' ,{"requires": ["yui2-yahoo", "yui2-dom", "yui2-event", "yui2-skin-sam-button", "yui2-element"], "optional": ["yui2-containercore", "yui2-skin-sam-menu", "yui2-menu"]});