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