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