adding current groupid to grade_export class - soon to be used in plugins
[moodle-pu.git] / lib / yui / button / button-beta-debug.js
blobc9dfa28cb72c7a03da8a4aaaaedcc07506f3f7cc
1 /*
2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 2.3.0
6 */
7 /**
8 * @module button
9 * @description <p>The Button Control enables the creation of rich, graphical
10 * buttons that function like traditional HTML form buttons. <em>Unlike</em>
11 * tradition HTML form buttons, buttons created with the Button Control can have
12 * a label that is different from its value. With the inclusion of the optional
13 * <a href="module_menu.html">Menu Control</a>, the Button Control can also be
14 * used to create menu buttons and split buttons, controls that are not
15 * available natively in HTML. The Button Control can also be thought of as a
16 * way to create more visually engaging implementations of the browser's
17 * default radio-button and check-box controls.</p>
18 * <p>The Button Control supports the following types:</p>
19 * <dl>
20 * <dt>push</dt>
21 * <dd>Basic push button that can execute a user-specified command when
22 * pressed.</dd>
23 * <dt>link</dt>
24 * <dd>Navigates to a specified url when pressed.</dd>
25 * <dt>submit</dt>
26 * <dd>Submits the parent form when pressed.</dd>
27 * <dt>reset</dt>
28 * <dd>Resets the parent form when pressed.</dd>
29 * <dt>checkbox</dt>
30 * <dd>Maintains a "checked" state that can be toggled on and off.</dd>
31 * <dt>radio</dt>
32 * <dd>Maintains a "checked" state that can be toggled on and off. Use with
33 * the ButtonGroup class to create a set of controls that are mutually
34 * exclusive; checking one button in the set will uncheck all others in
35 * the group.</dd>
36 * <dt>menu</dt>
37 * <dd>When pressed will show/hide a menu.</dd>
38 * <dt>split</dt>
39 * <dd>Can execute a user-specified command or display a menu when pressed.</dd>
40 * </dl>
41 * @title Button
42 * @namespace YAHOO.widget
43 * @requires yahoo, dom, element, event
44 * @optional container, menu
45 * @beta
49 (function () {
52 /**
53 * The Button class creates a rich, graphical button.
54 * @param {String} p_oElement String specifying the id attribute of the
55 * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
56 * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to
57 * be used to create the button.
58 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
59 * one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://www.w3.org
60 * /TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-34812697">
61 * HTMLButtonElement</a>|<a href="
62 * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#
63 * ID-33759296">HTMLElement</a>} p_oElement Object reference for the
64 * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
65 * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to be
66 * used to create the button.
67 * @param {Object} p_oElement Object literal specifying a set of
68 * configuration attributes used to create the button.
69 * @param {Object} p_oAttributes Optional. Object literal specifying a set
70 * of configuration attributes used to create the button.
71 * @namespace YAHOO.widget
72 * @class Button
73 * @constructor
74 * @extends YAHOO.util.Element
79 // Shorthard for utilities
81 var Dom = YAHOO.util.Dom,
82 Event = YAHOO.util.Event,
83 Lang = YAHOO.lang,
84 Overlay = YAHOO.widget.Overlay,
85 Menu = YAHOO.widget.Menu,
88 // Private member variables
90 m_oButtons = {}, // Collection of all Button instances
91 m_oOverlayManager = null, // YAHOO.widget.OverlayManager instance
92 m_oSubmitTrigger = null, // The button that submitted the form
93 m_oFocusedButton = null; // The button that has focus
97 // Private methods
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>}
117 function createInputElement(p_sType, p_sName, p_sValue, p_bChecked) {
119 var oInput,
120 sInput;
122 if (Lang.isString(p_sType) && Lang.isString(p_sName)) {
124 if (YAHOO.env.ua.ie) {
127 For IE it is necessary to create the element with the
128 "type," "name," "value," and "checked" properties set all
129 at once.
132 sInput = "<input type=\"" + p_sType + "\" name=\"" +
133 p_sName + "\"";
135 if (p_bChecked) {
137 sInput += " checked";
141 sInput += ">";
143 oInput = document.createElement(sInput);
146 else {
148 oInput = document.createElement("input");
149 oInput.name = p_sName;
150 oInput.type = p_sType;
152 if (p_bChecked) {
154 oInput.checked = true;
160 oInput.value = p_sValue;
162 return oInput;
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.
185 function setAttributesFromSrcElement(p_oElement, p_oAttributes) {
187 var sSrcElementNodeName = p_oElement.nodeName.toUpperCase(),
188 me = this,
189 oAttribute,
190 oRootNode,
191 sText;
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.
203 function setAttributeFromDOMAttribute(p_sAttribute) {
205 if ( !(p_sAttribute in p_oAttributes) ) {
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.
214 oAttribute = p_oElement.getAttributeNode(p_sAttribute);
217 if (oAttribute && ("value" in oAttribute)) {
219 me.logger.log("Setting attribute \"" + p_sAttribute +
220 "\" using source element's attribute value of \"" +
221 oAttribute.value + "\"");
223 p_oAttributes[p_sAttribute] = oAttribute.value;
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
239 function setFormElementProperties() {
241 setAttributeFromDOMAttribute("type");
243 if (p_oAttributes.type == "button") {
245 p_oAttributes.type = "push";
249 if ( !("disabled" in p_oAttributes) ) {
251 p_oAttributes.disabled = p_oElement.disabled;
255 setAttributeFromDOMAttribute("name");
256 setAttributeFromDOMAttribute("value");
257 setAttributeFromDOMAttribute("title");
262 switch (sSrcElementNodeName) {
264 case "A":
266 p_oAttributes.type = "link";
268 setAttributeFromDOMAttribute("href");
269 setAttributeFromDOMAttribute("target");
271 break;
273 case "INPUT":
275 setFormElementProperties();
277 if ( !("checked" in p_oAttributes) ) {
279 p_oAttributes.checked = p_oElement.checked;
283 break;
285 case "BUTTON":
287 setFormElementProperties();
289 oRootNode = p_oElement.parentNode.parentNode;
291 if (Dom.hasClass(oRootNode, this.CSS_CLASS_NAME + "-checked")) {
293 p_oAttributes.checked = true;
297 if (Dom.hasClass(oRootNode, this.CSS_CLASS_NAME + "-disabled")) {
299 p_oAttributes.disabled = true;
303 p_oElement.removeAttribute("value");
305 p_oElement.setAttribute("type", "button");
307 break;
311 p_oElement.removeAttribute("id");
312 p_oElement.removeAttribute("name");
314 if ( !("tabindex" in p_oAttributes) ) {
316 p_oAttributes.tabindex = p_oElement.tabIndex;
320 if ( !("label" in p_oAttributes) ) {
322 // Set the "label" property
324 sText = sSrcElementNodeName == "INPUT" ?
325 p_oElement.value : p_oElement.innerHTML;
328 if (sText && sText.length > 0) {
330 p_oAttributes.label = sText;
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.
347 function initConfig(p_oConfig) {
349 var oAttributes = p_oConfig.attributes,
350 oSrcElement = oAttributes.srcelement,
351 sSrcElementNodeName = oSrcElement.nodeName.toUpperCase(),
352 me = this;
355 if (sSrcElementNodeName == this.NODE_NAME) {
357 p_oConfig.element = oSrcElement;
358 p_oConfig.id = oSrcElement.id;
360 Dom.getElementsBy(function (p_oElement) {
362 switch (p_oElement.nodeName.toUpperCase()) {
364 case "BUTTON":
365 case "A":
366 case "INPUT":
368 setAttributesFromSrcElement.call(me, p_oElement,
369 oAttributes);
371 break;
375 }, "*", oSrcElement);
378 else {
380 switch (sSrcElementNodeName) {
382 case "BUTTON":
383 case "A":
384 case "INPUT":
386 setAttributesFromSrcElement.call(this, oSrcElement,
387 oAttributes);
389 break;
399 // Constructor
401 YAHOO.widget.Button = function (p_oElement, p_oAttributes) {
403 var fnSuperClass = YAHOO.widget.Button.superclass.constructor,
404 oConfig,
405 oElement;
407 if (arguments.length == 1 && !Lang.isString(p_oElement) &&
408 !p_oElement.nodeName) {
410 if (!p_oElement.id) {
412 p_oElement.id = Dom.generateId();
414 YAHOO.log("No value specified for the button's \"id\" " +
415 "attribute. Setting button id to \"" + p_oElement.id +
416 "\".", "warn");
420 this.logger = new YAHOO.widget.LogWriter("Button " + p_oElement.id);
422 this.logger.log("No source HTML element. Building the button " +
423 "using the set of configuration attributes.");
425 fnSuperClass.call(this,
426 (this.createButtonElement(p_oElement.type)),
427 p_oElement);
430 else {
432 oConfig = { element: null, attributes: (p_oAttributes || {}) };
435 if (Lang.isString(p_oElement)) {
437 oElement = Dom.get(p_oElement);
439 if (oElement) {
441 if (!oConfig.attributes.id) {
443 oConfig.attributes.id = p_oElement;
447 this.logger = new YAHOO.widget.LogWriter(
448 "Button " + oConfig.attributes.id);
450 this.logger.log("Building the button using an existing " +
451 "HTML element as a source element.");
454 oConfig.attributes.srcelement = oElement;
456 initConfig.call(this, oConfig);
459 if (!oConfig.element) {
461 this.logger.log("Source element could not be used " +
462 "as is. Creating a new HTML element for " +
463 "the button.");
465 oConfig.element =
466 this.createButtonElement(oConfig.attributes.type);
470 fnSuperClass.call(this, oConfig.element,
471 oConfig.attributes);
476 else if (p_oElement.nodeName) {
478 if (!oConfig.attributes.id) {
480 if (p_oElement.id) {
482 oConfig.attributes.id = p_oElement.id;
485 else {
487 oConfig.attributes.id = Dom.generateId();
489 YAHOO.log("No value specified for the button's " +
490 "\"id\" attribute. Setting button id to \"" +
491 oConfig.attributes.id + "\".", "warn");
498 this.logger = new YAHOO.widget.LogWriter(
499 "Button " + oConfig.attributes.id);
501 this.logger.log("Building the button using an existing HTML " +
502 "element as a source element.");
505 oConfig.attributes.srcelement = p_oElement;
507 initConfig.call(this, oConfig);
510 if (!oConfig.element) {
512 this.logger.log("Source element could not be used as is." +
513 " Creating a new HTML element for the button.");
515 oConfig.element =
516 this.createButtonElement(oConfig.attributes.type);
520 fnSuperClass.call(this, oConfig.element, oConfig.attributes);
530 YAHOO.extend(YAHOO.widget.Button, YAHOO.util.Element, {
533 // Protected properties
536 /**
537 * @property _button
538 * @description Object reference to the button's internal
539 * <code>&#60;a&#62;</code> or <code>&#60;button&#62;</code> element.
540 * @default null
541 * @protected
542 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
543 * level-one-html.html#ID-48250443">HTMLAnchorElement</a>|<a href="
544 * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
545 * #ID-34812697">HTMLButtonElement</a>
547 _button: null,
550 /**
551 * @property _menu
552 * @description Object reference to the button's menu.
553 * @default null
554 * @protected
555 * @type {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|
556 * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
558 _menu: null,
561 /**
562 * @property _hiddenFields
563 * @description Object reference to the <code>&#60;input&#62;</code>
564 * element, or array of HTML form elements used to represent the button
565 * when its parent form is submitted.
566 * @default null
567 * @protected
568 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
569 * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array
571 _hiddenFields: null,
574 /**
575 * @property _onclickAttributeValue
576 * @description Object reference to the button's current value for the
577 * "onclick" configuration attribute.
578 * @default null
579 * @protected
580 * @type Object
582 _onclickAttributeValue: null,
585 /**
586 * @property _activationKeyPressed
587 * @description Boolean indicating if the key(s) that toggle the button's
588 * "active" state have been pressed.
589 * @default false
590 * @protected
591 * @type Boolean
593 _activationKeyPressed: false,
596 /**
597 * @property _activationButtonPressed
598 * @description Boolean indicating if the mouse button that toggles
599 * the button's "active" state has been pressed.
600 * @default false
601 * @protected
602 * @type Boolean
604 _activationButtonPressed: false,
607 /**
608 * @property _hasKeyEventHandlers
609 * @description Boolean indicating if the button's "blur", "keydown" and
610 * "keyup" event handlers are assigned
611 * @default false
612 * @protected
613 * @type Boolean
615 _hasKeyEventHandlers: false,
618 /**
619 * @property _hasMouseEventHandlers
620 * @description Boolean indicating if the button's "mouseout,"
621 * "mousedown," and "mouseup" event handlers are assigned
622 * @default false
623 * @protected
624 * @type Boolean
626 _hasMouseEventHandlers: false,
630 // Constants
634 * @property NODE_NAME
635 * @description The name of the node to be used for the button's
636 * root element.
637 * @default "SPAN"
638 * @final
639 * @type String
641 NODE_NAME: "SPAN",
645 * @property CHECK_ACTIVATION_KEYS
646 * @description Array of numbers representing keys that (when pressed)
647 * toggle the button's "checked" attribute.
648 * @default [32]
649 * @final
650 * @type Array
652 CHECK_ACTIVATION_KEYS: [32],
656 * @property ACTIVATION_KEYS
657 * @description Array of numbers representing keys that (when presed)
658 * toggle the button's "active" state.
659 * @default [13, 32]
660 * @final
661 * @type Array
663 ACTIVATION_KEYS: [13, 32],
667 * @property OPTION_AREA_WIDTH
668 * @description Width (in pixels) of the area of a split button that
669 * when pressed will display a menu.
670 * @default 20
671 * @final
672 * @type Number
674 OPTION_AREA_WIDTH: 20,
678 * @property CSS_CLASS_NAME
679 * @description String representing the CSS class(es) to be applied to
680 * the button's root element.
681 * @default "yui-button"
682 * @final
683 * @type String
685 CSS_CLASS_NAME: "yui-button",
689 * @property RADIO_DEFAULT_TITLE
690 * @description String representing the default title applied to buttons
691 * of type "radio."
692 * @default "Unchecked. Click to check."
693 * @final
694 * @type String
696 RADIO_DEFAULT_TITLE: "Unchecked. Click to check.",
700 * @property RADIO_CHECKED_TITLE
701 * @description String representing the title applied to buttons of
702 * type "radio" when checked.
703 * @default "Checked. Click to uncheck."
704 * @final
705 * @type String
707 RADIO_CHECKED_TITLE: "Checked. Click to uncheck.",
711 * @property CHECKBOX_DEFAULT_TITLE
712 * @description String representing the default title applied to
713 * buttons of type "checkbox."
714 * @default "Unchecked. Click to check."
715 * @final
716 * @type String
718 CHECKBOX_DEFAULT_TITLE: "Unchecked. Click to check.",
722 * @property CHECKBOX_CHECKED_TITLE
723 * @description String representing the title applied to buttons of type
724 * "checkbox" when checked.
725 * @default "Checked. Click to uncheck."
726 * @final
727 * @type String
729 CHECKBOX_CHECKED_TITLE: "Checked. Click to uncheck.",
733 * @property MENUBUTTON_DEFAULT_TITLE
734 * @description String representing the default title applied to
735 * buttons of type "menu."
736 * @default "Menu collapsed. Click to expand."
737 * @final
738 * @type String
740 MENUBUTTON_DEFAULT_TITLE: "Menu collapsed. Click to expand.",
744 * @property MENUBUTTON_MENU_VISIBLE_TITLE
745 * @description String representing the title applied to buttons of type
746 * "menu" when the button's menu is visible.
747 * @default "Menu expanded. Click or press Esc to collapse."
748 * @final
749 * @type String
751 MENUBUTTON_MENU_VISIBLE_TITLE:
752 "Menu expanded. Click or press Esc to collapse.",
756 * @property SPLITBUTTON_DEFAULT_TITLE
757 * @description String representing the default title applied to
758 * buttons of type "split."
759 * @default "Menu collapsed. Click inside option region or press
760 * Ctrl + Shift + M to show the menu."
761 * @final
762 * @type String
764 SPLITBUTTON_DEFAULT_TITLE: ("Menu collapsed. Click inside option " +
765 "region or press Ctrl + Shift + M to show the menu."),
769 * @property SPLITBUTTON_OPTION_VISIBLE_TITLE
770 * @description String representing the title applied to buttons of type
771 * "split" when the button's menu is visible.
772 * @default "Menu expanded. Press Esc or Ctrl + Shift + M to hide
773 * the menu."
774 * @final
775 * @type String
777 SPLITBUTTON_OPTION_VISIBLE_TITLE:
778 "Menu expanded. Press Esc or Ctrl + Shift + M to hide the menu.",
782 * @property SUBMIT_TITLE
783 * @description String representing the title applied to buttons of
784 * type "submit."
785 * @default "Click to submit form."
786 * @final
787 * @type String
789 SUBMIT_TITLE: "Click to submit form.",
793 // Protected attribute setter methods
797 * @method _setType
798 * @description Sets the value of the button's "type" attribute.
799 * @protected
800 * @param {String} p_sType String indicating the value for the button's
801 * "type" attribute.
803 _setType: function (p_sType) {
805 if (p_sType == "split") {
807 this.on("option", this._onOption);
815 * @method _setLabel
816 * @description Sets the value of the button's "label" attribute.
817 * @protected
818 * @param {String} p_sLabel String indicating the value for the button's
819 * "label" attribute.
821 _setLabel: function (p_sLabel) {
823 this._button.innerHTML = p_sLabel;
829 * @method _setTabIndex
830 * @description Sets the value of the button's "tabindex" attribute.
831 * @protected
832 * @param {Number} p_nTabIndex Number indicating the value for the
833 * button's "tabindex" attribute.
835 _setTabIndex: function (p_nTabIndex) {
837 this._button.tabIndex = p_nTabIndex;
843 * @method _setTitle
844 * @description Sets the value of the button's "title" attribute.
845 * @protected
846 * @param {String} p_nTabIndex Number indicating the value for
847 * the button's "title" attribute.
849 _setTitle: function (p_sTitle) {
851 var sTitle = p_sTitle;
853 if (this.get("type") != "link") {
855 if (!sTitle) {
857 switch (this.get("type")) {
859 case "radio":
861 sTitle = this.RADIO_DEFAULT_TITLE;
863 break;
865 case "checkbox":
867 sTitle = this.CHECKBOX_DEFAULT_TITLE;
869 break;
871 case "menu":
873 sTitle = this.MENUBUTTON_DEFAULT_TITLE;
875 break;
877 case "split":
879 sTitle = this.SPLITBUTTON_DEFAULT_TITLE;
881 break;
883 case "submit":
885 sTitle = this.SUBMIT_TITLE;
887 break;
893 this._button.title = sTitle;
901 * @method _setDisabled
902 * @description Sets the value of the button's "disabled" attribute.
903 * @protected
904 * @param {Boolean} p_bDisabled Boolean indicating the value for
905 * the button's "disabled" attribute.
907 _setDisabled: function (p_bDisabled) {
909 if (this.get("type") != "link") {
911 if (p_bDisabled) {
913 if (this._menu) {
915 this._menu.hide();
919 if (this.hasFocus()) {
921 this.blur();
925 this._button.setAttribute("disabled", "disabled");
927 this.addStateCSSClasses("disabled");
930 else {
932 this._button.removeAttribute("disabled");
934 this.removeStateCSSClasses("disabled");
944 * @method _setHref
945 * @description Sets the value of the button's "href" attribute.
946 * @protected
947 * @param {String} p_sHref String indicating the value for the button's
948 * "href" attribute.
950 _setHref: function (p_sHref) {
952 if (this.get("type") == "link") {
954 this._button.href = p_sHref;
962 * @method _setTarget
963 * @description Sets the value of the button's "target" attribute.
964 * @protected
965 * @param {String} p_sTarget String indicating the value for the button's
966 * "target" attribute.
968 _setTarget: function (p_sTarget) {
970 if (this.get("type") == "link") {
972 this._button.setAttribute("target", p_sTarget);
980 * @method _setChecked
981 * @description Sets the value of the button's "target" attribute.
982 * @protected
983 * @param {Boolean} p_bChecked Boolean indicating the value for
984 * the button's "checked" attribute.
986 _setChecked: function (p_bChecked) {
988 var sType = this.get("type"),
989 sTitle;
991 if (sType == "checkbox" || sType == "radio") {
993 if (p_bChecked) {
995 this.addStateCSSClasses("checked");
997 sTitle = (sType == "radio") ?
998 this.RADIO_CHECKED_TITLE :
999 this.CHECKBOX_CHECKED_TITLE;
1002 else {
1004 this.removeStateCSSClasses("checked");
1006 sTitle = (sType == "radio") ?
1007 this.RADIO_DEFAULT_TITLE :
1008 this.CHECKBOX_DEFAULT_TITLE;
1012 this.set("title", sTitle);
1020 * @method _setMenu
1021 * @description Sets the value of the button's "menu" attribute.
1022 * @protected
1023 * @param {Object} p_oMenu Object indicating the value for the button's
1024 * "menu" attribute.
1026 _setMenu: function (p_oMenu) {
1028 var bLazyLoad = this.get("lazyloadmenu"),
1029 oButtonElement = this.get("element"),
1032 Boolean indicating if the value of p_oMenu is an instance
1033 of YAHOO.widget.Menu or YAHOO.widget.Overlay.
1036 bInstance = false,
1039 oMenu,
1040 oMenuElement,
1041 oSrcElement,
1042 aItems,
1043 nItems,
1044 oItem,
1048 if (!Overlay) {
1050 this.logger.log("YAHOO.widget.Overlay dependency not met.",
1051 "error");
1053 return false;
1058 if (!Menu) {
1060 this.logger.log("YAHOO.widget.Menu dependency not met.",
1061 "error");
1063 return false;
1068 function onAppendTo() {
1070 oMenu.render(oButtonElement.parentNode);
1072 this.removeListener("appendTo", onAppendTo);
1077 function initMenu() {
1079 if (oMenu) {
1081 Dom.addClass(oMenu.element, this.get("menuclassname"));
1082 Dom.addClass(oMenu.element,
1083 "yui-" + this.get("type") + "-button-menu");
1085 oMenu.showEvent.subscribe(this._onMenuShow, null, this);
1086 oMenu.hideEvent.subscribe(this._onMenuHide, null, this);
1087 oMenu.renderEvent.subscribe(this._onMenuRender, null, this);
1090 if (oMenu instanceof Menu) {
1092 oMenu.keyDownEvent.subscribe(this._onMenuKeyDown,
1093 this, true);
1095 oMenu.clickEvent.subscribe(this._onMenuClick,
1096 this, true);
1098 oMenu.itemAddedEvent.subscribe(this._onMenuItemAdded,
1099 this, true);
1101 oSrcElement = oMenu.srcElement;
1103 if (oSrcElement &&
1104 oSrcElement.nodeName.toUpperCase() == "SELECT") {
1106 oSrcElement.style.display = "none";
1107 oSrcElement.parentNode.removeChild(oSrcElement);
1112 else if (oMenu instanceof Overlay) {
1114 if (!m_oOverlayManager) {
1116 m_oOverlayManager =
1117 new YAHOO.widget.OverlayManager();
1121 m_oOverlayManager.register(oMenu);
1126 this._menu = oMenu;
1129 if (!bInstance) {
1131 if (bLazyLoad && !(oMenu instanceof Menu)) {
1134 Mimic Menu's "lazyload" functionality by adding
1135 a "beforeshow" event listener that renders the
1136 Overlay instance before it is made visible by
1137 the button.
1140 oMenu.beforeShowEvent.subscribe(
1141 this._onOverlayBeforeShow, null, this);
1144 else if (!bLazyLoad) {
1146 if (Dom.inDocument(oButtonElement)) {
1148 oMenu.render(oButtonElement.parentNode);
1151 else {
1153 this.on("appendTo", onAppendTo);
1166 if (p_oMenu && (p_oMenu instanceof Menu)) {
1168 oMenu = p_oMenu;
1169 aItems = oMenu.getItems();
1170 nItems = aItems.length;
1171 bInstance = true;
1174 if (nItems > 0) {
1176 i = nItems - 1;
1178 do {
1180 oItem = aItems[i];
1182 if (oItem) {
1184 oItem.cfg.subscribeToConfigEvent("selected",
1185 this._onMenuItemSelected,
1186 oItem,
1187 this);
1192 while (i--);
1196 initMenu.call(this);
1199 else if (p_oMenu && (p_oMenu instanceof Overlay)) {
1201 oMenu = p_oMenu;
1202 bInstance = true;
1204 oMenu.cfg.setProperty("visible", false);
1205 oMenu.cfg.setProperty("context", [oButtonElement, "tl", "bl"]);
1207 initMenu.call(this);
1210 else if (Lang.isArray(p_oMenu)) {
1212 this.on("appendTo", function () {
1214 oMenu = new Menu(Dom.generateId(), { lazyload: bLazyLoad,
1215 itemdata: p_oMenu });
1217 initMenu.call(this);
1222 else if (Lang.isString(p_oMenu)) {
1224 oMenuElement = Dom.get(p_oMenu);
1226 if (oMenuElement) {
1228 if (Dom.hasClass(oMenuElement,
1229 Menu.prototype.CSS_CLASS_NAME) ||
1230 oMenuElement.nodeName == "SELECT") {
1232 oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1234 initMenu.call(this);
1237 else {
1239 oMenu = new Overlay(p_oMenu, { visible: false,
1240 context: [oButtonElement, "tl", "bl"] });
1242 initMenu.call(this);
1249 else if (p_oMenu && p_oMenu.nodeName) {
1251 if (Dom.hasClass(p_oMenu, Menu.prototype.CSS_CLASS_NAME) ||
1252 p_oMenu.nodeName == "SELECT") {
1254 oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1256 initMenu.call(this);
1259 else {
1261 if (!p_oMenu.id) {
1263 Dom.generateId(p_oMenu);
1267 oMenu = new Overlay(p_oMenu, { visible: false,
1268 context: [oButtonElement, "tl", "bl"] });
1270 initMenu.call(this);
1280 * @method _setOnClick
1281 * @description Sets the value of the button's "onclick" attribute.
1282 * @protected
1283 * @param {Object} p_oObject Object indicating the value for the button's
1284 * "onclick" attribute.
1286 _setOnClick: function (p_oObject) {
1289 Remove any existing listeners if a "click" event handler
1290 has already been specified.
1293 if (this._onclickAttributeValue &&
1294 (this._onclickAttributeValue != p_oObject)) {
1296 this.removeListener("click", this._onclickAttributeValue.fn);
1298 this._onclickAttributeValue = null;
1303 if (!this._onclickAttributeValue &&
1304 Lang.isObject(p_oObject) &&
1305 Lang.isFunction(p_oObject.fn)) {
1307 this.on("click", p_oObject.fn, p_oObject.obj, p_oObject.scope);
1309 this._onclickAttributeValue = p_oObject;
1317 * @method _setSelectedMenuItem
1318 * @description Sets the value of the button's
1319 * "selectedMenuItem" attribute.
1320 * @protected
1321 * @param {Number} p_nIndex Number representing the index of the item
1322 * in the button's menu that is currently selected.
1324 _setSelectedMenuItem: function (p_nIndex) {
1326 var oMenu = this._menu,
1327 oMenuItem;
1330 if (oMenu && oMenu instanceof Menu) {
1332 oMenuItem = oMenu.getItem(p_nIndex);
1335 if (oMenuItem && !oMenuItem.cfg.getProperty("selected")) {
1337 oMenuItem.cfg.setProperty("selected", true);
1346 // Protected methods
1351 * @method _isActivationKey
1352 * @description Determines if the specified keycode is one that toggles
1353 * the button's "active" state.
1354 * @protected
1355 * @param {Number} p_nKeyCode Number representing the keycode to
1356 * be evaluated.
1357 * @return {Boolean}
1359 _isActivationKey: function (p_nKeyCode) {
1361 var sType = this.get("type"),
1362 aKeyCodes = (sType == "checkbox" || sType == "radio") ?
1363 this.CHECK_ACTIVATION_KEYS : this.ACTIVATION_KEYS,
1365 nKeyCodes = aKeyCodes.length,
1368 if (nKeyCodes > 0) {
1370 i = nKeyCodes - 1;
1372 do {
1374 if (p_nKeyCode == aKeyCodes[i]) {
1376 return true;
1381 while (i--);
1389 * @method _isSplitButtonOptionKey
1390 * @description Determines if the specified keycode is one that toggles
1391 * the display of the split button's menu.
1392 * @protected
1393 * @param {Event} p_oEvent Object representing the DOM event object
1394 * passed back by the event utility (YAHOO.util.Event).
1395 * @return {Boolean}
1397 _isSplitButtonOptionKey: function (p_oEvent) {
1399 return (p_oEvent.ctrlKey && p_oEvent.shiftKey &&
1400 Event.getCharCode(p_oEvent) == 77);
1406 * @method _addListenersToForm
1407 * @description Adds event handlers to the button's form.
1408 * @protected
1410 _addListenersToForm: function () {
1412 var oForm = this.getForm(),
1413 oSrcElement,
1414 aListeners,
1415 nListeners,
1417 bHasKeyPressListener;
1420 if (oForm) {
1422 Event.on(oForm, "reset", this._onFormReset, null, this);
1423 Event.on(oForm, "submit", this.createHiddenFields, null, this);
1425 oSrcElement = this.get("srcelement");
1428 if (this.get("type") == "submit" ||
1429 (oSrcElement && oSrcElement.type == "submit"))
1432 aListeners = Event.getListeners(oForm, "keypress");
1433 bHasKeyPressListener = false;
1435 if (aListeners) {
1437 nListeners = aListeners.length;
1439 if (nListeners > 0) {
1441 i = nListeners - 1;
1443 do {
1445 if (aListeners[i].fn ==
1446 YAHOO.widget.Button.onFormKeyPress)
1449 bHasKeyPressListener = true;
1450 break;
1455 while (i--);
1462 if (!bHasKeyPressListener) {
1464 Event.on(oForm, "keypress",
1465 YAHOO.widget.Button.onFormKeyPress);
1476 _originalMaxHeight: -1,
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.
1487 _showMenu: function (p_oEvent) {
1489 YAHOO.widget.MenuManager.hideVisible();
1491 if (m_oOverlayManager) {
1493 m_oOverlayManager.hideAll();
1498 var oMenu = this._menu,
1499 nViewportHeight = Dom.getViewportHeight(),
1500 nMenuHeight,
1501 nScrollTop,
1505 if (oMenu && (oMenu instanceof Menu)) {
1507 oMenu.cfg.applyConfig({ context: [this.get("id"), "tl", "bl"],
1508 constraintoviewport: false,
1509 clicktohide: false,
1510 visible: true });
1512 oMenu.cfg.fireQueue();
1514 oMenu.align("tl", "bl");
1517 Stop the propagation of the event so that the MenuManager
1518 doesn't blur the menu after it gets focus.
1521 if (p_oEvent.type == "mousedown") {
1523 Event.stopPropagation(p_oEvent);
1528 if (this.get("focusmenu")) {
1530 this._menu.focus();
1534 nMenuHeight = oMenu.element.offsetHeight;
1537 if ((oMenu.cfg.getProperty("y") + nMenuHeight) >
1538 nViewportHeight) {
1540 this.logger.log("Current menu position will place a " +
1541 "portion, or the entire menu outside the boundary of " +
1542 "the viewport. Repositioning the menu to stay " +
1543 "inside the viewport.");
1545 oMenu.align("bl", "tl");
1547 nY = oMenu.cfg.getProperty("y");
1549 nScrollTop = Dom.getDocumentScrollTop();
1552 if (nScrollTop >= nY) {
1554 if (this._originalMaxHeight == -1) {
1556 this._originalMaxHeight =
1557 oMenu.cfg.getProperty("maxheight");
1561 oMenu.cfg.setProperty("maxheight",
1562 (nMenuHeight - ((nScrollTop - nY) + 20)));
1564 oMenu.align("bl", "tl");
1571 else if (oMenu && (oMenu instanceof Overlay)) {
1573 oMenu.show();
1574 oMenu.align("tl", "bl");
1576 nMenuHeight = oMenu.element.offsetHeight;
1579 if ((oMenu.cfg.getProperty("y") + nMenuHeight) >
1580 nViewportHeight) {
1582 this.logger.log("Current menu position will place a " +
1583 "portion, or the entire menu outside the boundary of " +
1584 "the viewport. Repositioning the menu to stay inside" +
1585 " the viewport.");
1587 oMenu.align("bl", "tl");
1597 * @method _hideMenu
1598 * @description Hides the button's menu.
1599 * @protected
1601 _hideMenu: function () {
1603 var oMenu = this._menu;
1605 if (oMenu) {
1607 oMenu.hide();
1616 // Protected event handlers
1620 * @method _onMouseOver
1621 * @description "mouseover" event handler for the button.
1622 * @protected
1623 * @param {Event} p_oEvent Object representing the DOM event object
1624 * passed back by the event utility (YAHOO.util.Event).
1626 _onMouseOver: function (p_oEvent) {
1628 if (!this._hasMouseEventHandlers) {
1630 this.on("mouseout", this._onMouseOut);
1631 this.on("mousedown", this._onMouseDown);
1632 this.on("mouseup", this._onMouseUp);
1634 this._hasMouseEventHandlers = true;
1638 this.addStateCSSClasses("hover");
1640 if (this._activationButtonPressed) {
1642 this.addStateCSSClasses("active");
1647 if (this._bOptionPressed) {
1649 this.addStateCSSClasses("activeoption");
1657 * @method _onMouseOut
1658 * @description "mouseout" event handler for the button.
1659 * @protected
1660 * @param {Event} p_oEvent Object representing the DOM event object
1661 * passed back by the event utility (YAHOO.util.Event).
1663 _onMouseOut: function (p_oEvent) {
1665 this.removeStateCSSClasses("hover");
1667 if (this.get("type") != "menu") {
1669 this.removeStateCSSClasses("active");
1673 if (this._activationButtonPressed || this._bOptionPressed) {
1675 Event.on(document, "mouseup", this._onDocumentMouseUp,
1676 null, this);
1684 * @method _onDocumentMouseUp
1685 * @description "mouseup" event handler for the button.
1686 * @protected
1687 * @param {Event} p_oEvent Object representing the DOM event object
1688 * passed back by the event utility (YAHOO.util.Event).
1690 _onDocumentMouseUp: function (p_oEvent) {
1692 this._activationButtonPressed = false;
1693 this._bOptionPressed = false;
1695 var sType = this.get("type");
1697 if (sType == "menu" || sType == "split") {
1699 this.removeStateCSSClasses(
1700 (sType == "menu" ? "active" : "activeoption"));
1702 this._hideMenu();
1706 Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
1712 * @method _onMouseDown
1713 * @description "mousedown" event handler for the button.
1714 * @protected
1715 * @param {Event} p_oEvent Object representing the DOM event object
1716 * passed back by the event utility (YAHOO.util.Event).
1718 _onMouseDown: function (p_oEvent) {
1720 var sType,
1721 oElement,
1726 function onMouseUp() {
1728 this._hideMenu();
1729 this.removeListener("mouseup", onMouseUp);
1734 if ((p_oEvent.which || p_oEvent.button) == 1) {
1737 if (!this.hasFocus()) {
1739 this.focus();
1744 sType = this.get("type");
1747 if (sType == "split") {
1749 oElement = this.get("element");
1750 nX = Event.getPageX(p_oEvent) - Dom.getX(oElement);
1752 if ((oElement.offsetWidth - this.OPTION_AREA_WIDTH) < nX) {
1754 this.fireEvent("option", p_oEvent);
1757 else {
1759 this.addStateCSSClasses("active");
1761 this._activationButtonPressed = true;
1766 else if (sType == "menu") {
1768 if (this.isActive()) {
1770 this._hideMenu();
1772 this._activationButtonPressed = false;
1775 else {
1777 this._showMenu(p_oEvent);
1779 this._activationButtonPressed = true;
1784 else {
1786 this.addStateCSSClasses("active");
1788 this._activationButtonPressed = true;
1794 if (sType == "split" || sType == "menu") {
1796 me = this;
1798 this._hideMenuTimerId = window.setTimeout(function () {
1800 me.on("mouseup", onMouseUp);
1802 }, 250);
1812 * @method _onMouseUp
1813 * @description "mouseup" event handler for the button.
1814 * @protected
1815 * @param {Event} p_oEvent Object representing the DOM event object
1816 * passed back by the event utility (YAHOO.util.Event).
1818 _onMouseUp: function (p_oEvent) {
1820 var sType = this.get("type");
1823 if (this._hideMenuTimerId) {
1825 window.clearTimeout(this._hideMenuTimerId);
1830 if (sType == "checkbox" || sType == "radio") {
1832 this.set("checked", !(this.get("checked")));
1837 this._activationButtonPressed = false;
1840 if (this.get("type") != "menu") {
1842 this.removeStateCSSClasses("active");
1850 * @method _onFocus
1851 * @description "focus" event handler for the button.
1852 * @protected
1853 * @param {Event} p_oEvent Object representing the DOM event object
1854 * passed back by the event utility (YAHOO.util.Event).
1856 _onFocus: function (p_oEvent) {
1858 var oElement;
1860 this.addStateCSSClasses("focus");
1862 if (this._activationKeyPressed) {
1864 this.addStateCSSClasses("active");
1868 m_oFocusedButton = this;
1871 if (!this._hasKeyEventHandlers) {
1873 oElement = this._button;
1875 Event.on(oElement, "blur", this._onBlur, null, this);
1876 Event.on(oElement, "keydown", this._onKeyDown, null, this);
1877 Event.on(oElement, "keyup", this._onKeyUp, null, this);
1879 this._hasKeyEventHandlers = true;
1884 this.fireEvent("focus", p_oEvent);
1890 * @method _onBlur
1891 * @description "blur" event handler for the button.
1892 * @protected
1893 * @param {Event} p_oEvent Object representing the DOM event object
1894 * passed back by the event utility (YAHOO.util.Event).
1896 _onBlur: function (p_oEvent) {
1898 this.removeStateCSSClasses("focus");
1900 if (this.get("type") != "menu") {
1902 this.removeStateCSSClasses("active");
1906 if (this._activationKeyPressed) {
1908 Event.on(document, "keyup", this._onDocumentKeyUp, null, this);
1913 m_oFocusedButton = null;
1915 this.fireEvent("blur", p_oEvent);
1921 * @method _onDocumentKeyUp
1922 * @description "keyup" event handler for the document.
1923 * @protected
1924 * @param {Event} p_oEvent Object representing the DOM event object
1925 * passed back by the event utility (YAHOO.util.Event).
1927 _onDocumentKeyUp: function (p_oEvent) {
1929 if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1931 this._activationKeyPressed = false;
1933 Event.removeListener(document, "keyup", this._onDocumentKeyUp);
1941 * @method _onKeyDown
1942 * @description "keydown" event handler for the button.
1943 * @protected
1944 * @param {Event} p_oEvent Object representing the DOM event object
1945 * passed back by the event utility (YAHOO.util.Event).
1947 _onKeyDown: function (p_oEvent) {
1949 var oMenu = this._menu;
1952 if (this.get("type") == "split" &&
1953 this._isSplitButtonOptionKey(p_oEvent)) {
1955 this.fireEvent("option", p_oEvent);
1958 else if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1960 if (this.get("type") == "menu") {
1962 this._showMenu(p_oEvent);
1965 else {
1967 this._activationKeyPressed = true;
1969 this.addStateCSSClasses("active");
1976 if (oMenu && oMenu.cfg.getProperty("visible") &&
1977 Event.getCharCode(p_oEvent) == 27) {
1979 oMenu.hide();
1980 this.focus();
1988 * @method _onKeyUp
1989 * @description "keyup" event handler for the button.
1990 * @protected
1991 * @param {Event} p_oEvent Object representing the DOM event object
1992 * passed back by the event utility (YAHOO.util.Event).
1994 _onKeyUp: function (p_oEvent) {
1996 var sType;
1998 if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
2000 sType = this.get("type");
2002 if (sType == "checkbox" || sType == "radio") {
2004 this.set("checked", !(this.get("checked")));
2008 this._activationKeyPressed = false;
2010 if (this.get("type") != "menu") {
2012 this.removeStateCSSClasses("active");
2022 * @method _onClick
2023 * @description "click" event handler for the button.
2024 * @protected
2025 * @param {Event} p_oEvent Object representing the DOM event object
2026 * passed back by the event utility (YAHOO.util.Event).
2028 _onClick: function (p_oEvent) {
2030 var sType = this.get("type"),
2031 sTitle,
2032 oForm,
2033 oSrcElement,
2034 oElement,
2038 switch (sType) {
2040 case "radio":
2041 case "checkbox":
2043 if (this.get("checked")) {
2045 sTitle = (sType == "radio") ?
2046 this.RADIO_CHECKED_TITLE :
2047 this.CHECKBOX_CHECKED_TITLE;
2050 else {
2052 sTitle = (sType == "radio") ?
2053 this.RADIO_DEFAULT_TITLE :
2054 this.CHECKBOX_DEFAULT_TITLE;
2058 this.set("title", sTitle);
2060 break;
2062 case "submit":
2064 this.submitForm();
2066 break;
2068 case "reset":
2070 oForm = this.getForm();
2072 if (oForm) {
2074 oForm.reset();
2078 break;
2080 case "menu":
2082 sTitle = this._menu.cfg.getProperty("visible") ?
2083 this.MENUBUTTON_MENU_VISIBLE_TITLE :
2084 this.MENUBUTTON_DEFAULT_TITLE;
2086 this.set("title", sTitle);
2088 break;
2090 case "split":
2092 oElement = this.get("element");
2093 nX = Event.getPageX(p_oEvent) - Dom.getX(oElement);
2095 if ((oElement.offsetWidth - this.OPTION_AREA_WIDTH) < nX) {
2097 return false;
2100 else {
2102 this._hideMenu();
2104 oSrcElement = this.get("srcelement");
2106 if (oSrcElement && oSrcElement.type == "submit") {
2108 this.submitForm();
2114 sTitle = this._menu.cfg.getProperty("visible") ?
2115 this.SPLITBUTTON_OPTION_VISIBLE_TITLE :
2116 this.SPLITBUTTON_DEFAULT_TITLE;
2118 this.set("title", sTitle);
2120 break;
2128 * @method _onAppendTo
2129 * @description "appendTo" event handler for the button.
2130 * @protected
2131 * @param {Event} p_oEvent Object representing the DOM event object
2132 * passed back by the event utility (YAHOO.util.Event).
2134 _onAppendTo: function (p_oEvent) {
2137 It is necessary to call "getForm" using "setTimeout" to make
2138 sure that the button's "form" property returns a node
2139 reference. Sometimes, if you try to get the reference
2140 immediately after appending the field, it is null.
2143 var me = this;
2145 window.setTimeout(function () {
2147 me._addListenersToForm();
2149 }, 0);
2155 * @method _onFormReset
2156 * @description "reset" event handler for the button's form.
2157 * @protected
2158 * @param {Event} p_oEvent Object representing the DOM event
2159 * object passed back by the event utility (YAHOO.util.Event).
2161 _onFormReset: function (p_oEvent) {
2163 var sType = this.get("type"),
2164 oMenu = this._menu;
2166 if (sType == "checkbox" || sType == "radio") {
2168 this.resetValue("checked");
2173 if (oMenu && (oMenu instanceof Menu)) {
2175 this.resetValue("selectedMenuItem");
2183 * @method _onDocumentMouseDown
2184 * @description "mousedown" event handler for the document.
2185 * @protected
2186 * @param {Event} p_oEvent Object representing the DOM event object
2187 * passed back by the event utility (YAHOO.util.Event).
2189 _onDocumentMouseDown: function (p_oEvent) {
2191 var oTarget = Event.getTarget(p_oEvent),
2192 oButtonElement = this.get("element"),
2193 oMenuElement = this._menu.element;
2195 if (oTarget != oButtonElement &&
2196 !Dom.isAncestor(oButtonElement, oTarget) &&
2197 oTarget != oMenuElement &&
2198 !Dom.isAncestor(oMenuElement, oTarget)) {
2200 this._hideMenu();
2202 Event.removeListener(document, "mousedown",
2203 this._onDocumentMouseDown);
2211 * @method _onOption
2212 * @description "option" event handler for the button.
2213 * @protected
2214 * @param {Event} p_oEvent Object representing the DOM event object
2215 * passed back by the event utility (YAHOO.util.Event).
2217 _onOption: function (p_oEvent) {
2219 if (this.hasClass("yui-split-button-activeoption")) {
2221 this._hideMenu();
2223 this._bOptionPressed = false;
2226 else {
2228 this._showMenu(p_oEvent);
2230 this._bOptionPressed = true;
2238 * @method _onOverlayBeforeShow
2239 * @description "beforeshow" event handler for the
2240 * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a> instance
2241 * serving as the button's menu.
2242 * @private
2243 * @param {String} p_sType String representing the name of the event
2244 * that was fired.
2246 _onOverlayBeforeShow: function (p_sType) {
2248 var oMenu = this._menu;
2250 oMenu.render(this.get("element").parentNode);
2252 oMenu.beforeShowEvent.unsubscribe(this._onOverlayBeforeShow);
2258 * @method _onMenuShow
2259 * @description "show" event handler for the button's menu.
2260 * @private
2261 * @param {String} p_sType String representing the name of the event
2262 * that was fired.
2264 _onMenuShow: function (p_sType) {
2266 Event.on(document, "mousedown", this._onDocumentMouseDown,
2267 null, this);
2269 var sTitle,
2270 sState;
2272 if (this.get("type") == "split") {
2274 sTitle = this.SPLITBUTTON_OPTION_VISIBLE_TITLE;
2275 sState = "activeoption";
2278 else {
2280 sTitle = this.MENUBUTTON_MENU_VISIBLE_TITLE;
2281 sState = "active";
2285 this.addStateCSSClasses(sState);
2286 this.set("title", sTitle);
2292 * @method _onMenuHide
2293 * @description "hide" event handler for the button's menu.
2294 * @private
2295 * @param {String} p_sType String representing the name of the event
2296 * that was fired.
2298 _onMenuHide: function (p_sType) {
2300 var oMenu = this._menu,
2301 sTitle,
2302 sState;
2304 if (oMenu && (oMenu instanceof Menu) &&
2305 this._originalMaxHeight != -1) {
2307 this._menu.cfg.setProperty("maxheight",
2308 this._originalMaxHeight);
2313 if (this.get("type") == "split") {
2315 sTitle = this.SPLITBUTTON_DEFAULT_TITLE;
2316 sState = "activeoption";
2319 else {
2321 sTitle = this.MENUBUTTON_DEFAULT_TITLE;
2322 sState = "active";
2326 this.removeStateCSSClasses(sState);
2327 this.set("title", sTitle);
2330 if (this.get("type") == "split") {
2332 this._bOptionPressed = false;
2340 * @method _onMenuKeyDown
2341 * @description "keydown" event handler for the button's menu.
2342 * @private
2343 * @param {String} p_sType String representing the name of the event
2344 * that was fired.
2345 * @param {Array} p_aArgs Array of arguments sent when the event
2346 * was fired.
2348 _onMenuKeyDown: function (p_sType, p_aArgs) {
2350 var oEvent = p_aArgs[0];
2352 if (Event.getCharCode(oEvent) == 27) {
2354 this.focus();
2356 if (this.get("type") == "split") {
2358 this._bOptionPressed = false;
2368 * @method _onMenuRender
2369 * @description "render" event handler for the button's menu.
2370 * @private
2371 * @param {String} p_sType String representing the name of the
2372 * event thatwas fired.
2374 _onMenuRender: function (p_sType) {
2376 var oButtonElement = this.get("element"),
2377 oButtonParent = oButtonElement.parentNode,
2378 oMenuElement = this._menu.element;
2381 if (oButtonParent != oMenuElement.parentNode) {
2383 oButtonParent.appendChild(oMenuElement);
2387 this.set("selectedMenuItem", this.get("selectedMenuItem"));
2393 * @method _onMenuItemSelected
2394 * @description "selectedchange" event handler for each item in the
2395 * button's menu.
2396 * @private
2397 * @param {String} p_sType String representing the name of the event
2398 * that was fired.
2399 * @param {Array} p_aArgs Array of arguments sent when the event
2400 * was fired.
2401 * @param {Number} p_nItem Number representing the index of the menu
2402 * item that subscribed to the event.
2404 _onMenuItemSelected: function (p_sType, p_aArgs, p_nItem) {
2406 var bSelected = p_aArgs[0];
2408 if (bSelected) {
2410 this.set("selectedMenuItem", p_nItem);
2418 * @method _onMenuItemAdded
2419 * @description "itemadded" event handler for the button's menu.
2420 * @private
2421 * @param {String} p_sType String representing the name of the event
2422 * that was fired.
2423 * @param {Array} p_aArgs Array of arguments sent when the event
2424 * was fired.
2425 * @param {<a href="YAHOO.widget.MenuItem.html">
2426 * YAHOO.widget.MenuItem</a>} p_oItem Object representing the menu
2427 * item that subscribed to the event.
2429 _onMenuItemAdded: function (p_sType, p_aArgs, p_oItem) {
2431 var oItem = p_aArgs[0];
2433 oItem.cfg.subscribeToConfigEvent("selected",
2434 this._onMenuItemSelected,
2435 oItem.index,
2436 this);
2442 * @method _onMenuClick
2443 * @description "click" event handler for the button's menu.
2444 * @private
2445 * @param {String} p_sType String representing the name of the event
2446 * that was fired.
2447 * @param {Array} p_aArgs Array of arguments sent when the event
2448 * was fired.
2450 _onMenuClick: function (p_sType, p_aArgs) {
2452 var oItem = p_aArgs[1],
2453 oSrcElement;
2455 if (oItem) {
2457 oSrcElement = this.get("srcelement");
2459 if (oSrcElement && oSrcElement.type == "submit") {
2461 this.submitForm();
2465 this._hideMenu();
2473 // Public methods
2477 * @method createButtonElement
2478 * @description Creates the button's HTML elements.
2479 * @param {String} p_sType String indicating the type of element
2480 * to create.
2481 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2482 * level-one-html.html#ID-58190037">HTMLElement</a>}
2484 createButtonElement: function (p_sType) {
2486 var sNodeName = this.NODE_NAME,
2487 oElement = document.createElement(sNodeName);
2489 oElement.innerHTML = "<" + sNodeName + " class=\"first-child\">" +
2490 (p_sType == "link" ? "<a></a>" :
2491 "<button type=\"button\"></button>") + "</" + sNodeName + ">";
2493 return oElement;
2499 * @method addStateCSSClasses
2500 * @description Appends state-specific CSS classes to the button's root
2501 * DOM element.
2503 addStateCSSClasses: function (p_sState) {
2505 var sType = this.get("type");
2507 if (Lang.isString(p_sState)) {
2509 if (p_sState != "activeoption") {
2511 this.addClass(this.CSS_CLASS_NAME + ("-" + p_sState));
2515 this.addClass("yui-" + sType + ("-button-" + p_sState));
2523 * @method removeStateCSSClasses
2524 * @description Removes state-specific CSS classes to the button's root
2525 * DOM element.
2527 removeStateCSSClasses: function (p_sState) {
2529 var sType = this.get("type");
2531 if (Lang.isString(p_sState)) {
2533 this.removeClass(this.CSS_CLASS_NAME + ("-" + p_sState));
2534 this.removeClass("yui-" + sType + ("-button-" + p_sState));
2542 * @method createHiddenFields
2543 * @description Creates the button's hidden form field and appends it
2544 * to its parent form.
2545 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2546 * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
2548 createHiddenFields: function () {
2550 this.removeHiddenFields();
2552 var oForm = this.getForm(),
2553 oButtonField,
2554 sType,
2555 bCheckable,
2556 oMenu,
2557 oMenuItem,
2558 sName,
2559 oValue,
2560 oMenuField;
2563 if (oForm && !this.get("disabled")) {
2565 sType = this.get("type");
2566 bCheckable = (sType == "checkbox" || sType == "radio");
2569 if (bCheckable || (m_oSubmitTrigger == this)) {
2571 this.logger.log("Creating hidden field.");
2573 oButtonField = createInputElement(
2574 (bCheckable ? sType : "hidden"),
2575 this.get("name"),
2576 this.get("value"),
2577 this.get("checked"));
2580 if (oButtonField) {
2582 if (bCheckable) {
2584 oButtonField.style.display = "none";
2588 oForm.appendChild(oButtonField);
2595 oMenu = this._menu;
2598 if (oMenu && (oMenu instanceof Menu)) {
2600 this.logger.log("Creating hidden field for menu.");
2602 oMenuField = oMenu.srcElement;
2603 oMenuItem = oMenu.getItem(this.get("selectedMenuItem"));
2605 if (oMenuField &&
2606 oMenuField.nodeName.toUpperCase() == "SELECT") {
2608 oForm.appendChild(oMenuField);
2609 oMenuField.selectedIndex = oMenuItem.index;
2612 else {
2614 oValue = (oMenuItem.value === null ||
2615 oMenuItem.value === "") ?
2616 oMenuItem.cfg.getProperty("text") :
2617 oMenuItem.value;
2619 sName = this.get("name");
2621 if (oValue && sName) {
2623 oMenuField = createInputElement("hidden",
2624 (sName + "_options"),
2625 oValue);
2627 oForm.appendChild(oMenuField);
2636 if (oButtonField && oMenuField) {
2638 this._hiddenFields = [oButtonField, oMenuField];
2641 else if (!oButtonField && oMenuField) {
2643 this._hiddenFields = oMenuField;
2646 else if (oButtonField && !oMenuField) {
2648 this._hiddenFields = oButtonField;
2653 return this._hiddenFields;
2661 * @method removeHiddenFields
2662 * @description Removes the button's hidden form field(s) from its
2663 * parent form.
2665 removeHiddenFields: function () {
2667 var oField = this._hiddenFields,
2668 nFields,
2671 function removeChild(p_oElement) {
2673 if (Dom.inDocument(p_oElement)) {
2675 p_oElement.parentNode.removeChild(p_oElement);
2682 if (oField) {
2684 if (Lang.isArray(oField)) {
2686 nFields = oField.length;
2688 if (nFields > 0) {
2690 i = nFields - 1;
2692 do {
2694 removeChild(oField[i]);
2697 while (i--);
2702 else {
2704 removeChild(oField);
2708 this._hiddenFields = null;
2716 * @method submitForm
2717 * @description Submits the form to which the button belongs. Returns
2718 * true if the form was submitted successfully, false if the submission
2719 * was cancelled.
2720 * @protected
2721 * @return {Boolean}
2723 submitForm: function () {
2725 var oForm = this.getForm(),
2727 oSrcElement = this.get("srcelement"),
2730 Boolean indicating if the event fired successfully
2731 (was not cancelled by any handlers)
2734 bSubmitForm = false,
2736 oEvent;
2739 if (oForm) {
2741 if (this.get("type") == "submit" ||
2742 (oSrcElement && oSrcElement.type == "submit"))
2745 m_oSubmitTrigger = this;
2750 if (YAHOO.env.ua.ie) {
2752 bSubmitForm = oForm.fireEvent("onsubmit");
2755 else { // Gecko, Opera, and Safari
2757 oEvent = document.createEvent("HTMLEvents");
2758 oEvent.initEvent("submit", true, true);
2760 bSubmitForm = oForm.dispatchEvent(oEvent);
2766 In IE and Safari, dispatching a "submit" event to a form
2767 WILL cause the form's "submit" event to fire, but WILL NOT
2768 submit the form. Therefore, we need to call the "submit"
2769 method as well.
2772 if ((YAHOO.env.ua.ie || YAHOO.env.ua.webkit) && bSubmitForm) {
2774 oForm.submit();
2780 return bSubmitForm;
2786 * @method init
2787 * @description The Button class's initialization method.
2788 * @param {String} p_oElement String specifying the id attribute of the
2789 * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
2790 * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to
2791 * be used to create the button.
2792 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2793 * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://
2794 * www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
2795 * #ID-34812697">HTMLButtonElement</a>|<a href="http://www.w3.org/TR
2796 * /2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-33759296">
2797 * HTMLElement</a>} p_oElement Object reference for the
2798 * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
2799 * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to be
2800 * used to create the button.
2801 * @param {Object} p_oElement Object literal specifying a set of
2802 * configuration attributes used to create the button.
2803 * @param {Object} p_oAttributes Optional. Object literal specifying a
2804 * set of configuration attributes used to create the button.
2806 init: function (p_oElement, p_oAttributes) {
2808 var sNodeName = p_oAttributes.type == "link" ? "A" : "BUTTON",
2809 oSrcElement = p_oAttributes.srcelement,
2810 oButton = p_oElement.getElementsByTagName(sNodeName)[0],
2811 oInput;
2814 if (!oButton) {
2816 oInput = p_oElement.getElementsByTagName("INPUT")[0];
2819 if (oInput) {
2821 oButton = document.createElement("BUTTON");
2822 oButton.setAttribute("type", "button");
2824 oInput.parentNode.replaceChild(oButton, oInput);
2830 this._button = oButton;
2833 YAHOO.widget.Button.superclass.init.call(this, p_oElement,
2834 p_oAttributes);
2837 m_oButtons[this.get("id")] = this;
2840 this.addClass(this.CSS_CLASS_NAME);
2842 this.addClass("yui-" + this.get("type") + "-button");
2844 Event.on(this._button, "focus", this._onFocus, null, this);
2845 this.on("mouseover", this._onMouseOver);
2846 this.on("click", this._onClick);
2847 this.on("appendTo", this._onAppendTo);
2850 var oContainer = this.get("container"),
2851 oElement = this.get("element"),
2852 bElInDoc = Dom.inDocument(oElement),
2853 oParentNode;
2856 if (oContainer) {
2858 if (oSrcElement && oSrcElement != oElement) {
2860 oParentNode = oSrcElement.parentNode;
2862 if (oParentNode) {
2864 oParentNode.removeChild(oSrcElement);
2870 if (Lang.isString(oContainer)) {
2872 Event.onContentReady(oContainer, function () {
2874 this.appendTo(oContainer);
2876 }, null, this);
2879 else {
2881 this.appendTo(oContainer);
2886 else if (!bElInDoc && oSrcElement && oSrcElement != oElement) {
2888 oParentNode = oSrcElement.parentNode;
2890 if (oParentNode) {
2892 this.fireEvent("beforeAppendTo", {
2893 type: "beforeAppendTo",
2894 target: oParentNode
2897 oParentNode.replaceChild(oElement, oSrcElement);
2899 this.fireEvent("appendTo", {
2900 type: "appendTo",
2901 target: oParentNode
2907 else if (this.get("type") != "link" && bElInDoc && oSrcElement &&
2908 oSrcElement == oElement) {
2910 this._addListenersToForm();
2914 this.logger.log("Initialization completed.");
2920 * @method initAttributes
2921 * @description Initializes all of the configuration attributes used to
2922 * create the button.
2923 * @param {Object} p_oAttributes Object literal specifying a set of
2924 * configuration attributes used to create the button.
2926 initAttributes: function (p_oAttributes) {
2928 var oAttributes = p_oAttributes || {};
2930 YAHOO.widget.Button.superclass.initAttributes.call(this,
2931 oAttributes);
2935 * @config type
2936 * @description String specifying the button's type. Possible
2937 * values are: "push," "link," "submit," "reset," "checkbox,"
2938 * "radio," "menu," and "split."
2939 * @default "push"
2940 * @type String
2942 this.setAttributeConfig("type", {
2944 value: (oAttributes.type || "push"),
2945 validator: Lang.isString,
2946 writeOnce: true,
2947 method: this._setType
2953 * @config label
2954 * @description String specifying the button's text label
2955 * or innerHTML.
2956 * @default null
2957 * @type String
2959 this.setAttributeConfig("label", {
2961 value: oAttributes.label,
2962 validator: Lang.isString,
2963 method: this._setLabel
2969 * @config value
2970 * @description Object specifying the value for the button.
2971 * @default null
2972 * @type Object
2974 this.setAttributeConfig("value", {
2976 value: oAttributes.value
2982 * @config name
2983 * @description String specifying the name for the button.
2984 * @default null
2985 * @type String
2987 this.setAttributeConfig("name", {
2989 value: oAttributes.name,
2990 validator: Lang.isString
2996 * @config tabindex
2997 * @description Number specifying the tabindex for the button.
2998 * @default null
2999 * @type Number
3001 this.setAttributeConfig("tabindex", {
3003 value: oAttributes.tabindex,
3004 validator: Lang.isNumber,
3005 method: this._setTabIndex
3011 * @config title
3012 * @description String specifying the title for the button.
3013 * @default null
3014 * @type String
3016 this.configureAttribute("title", {
3018 value: oAttributes.title,
3019 validator: Lang.isString,
3020 method: this._setTitle
3026 * @config disabled
3027 * @description Boolean indicating if the button should be disabled.
3028 * (Disabled buttons are dimmed and will not respond to user input
3029 * or fire events. Does not apply to button's of type "link.")
3030 * @default false
3031 * @type Boolean
3033 this.setAttributeConfig("disabled", {
3035 value: (oAttributes.disabled || false),
3036 validator: Lang.isBoolean,
3037 method: this._setDisabled
3043 * @config href
3044 * @description String specifying the href for the button. Applies
3045 * only to buttons of type "link."
3046 * @type String
3048 this.setAttributeConfig("href", {
3050 value: oAttributes.href,
3051 validator: Lang.isString,
3052 method: this._setHref
3058 * @config target
3059 * @description String specifying the target for the button.
3060 * Applies only to buttons of type "link."
3061 * @type String
3063 this.setAttributeConfig("target", {
3065 value: oAttributes.target,
3066 validator: Lang.isString,
3067 method: this._setTarget
3073 * @config checked
3074 * @description Boolean indicating if the button is checked.
3075 * Applies only to buttons of type "radio" and "checkbox."
3076 * @default false
3077 * @type Boolean
3079 this.setAttributeConfig("checked", {
3081 value: (oAttributes.checked || false),
3082 validator: Lang.isBoolean,
3083 method: this._setChecked
3089 * @config container
3090 * @description HTML element reference or string specifying the id
3091 * attribute of the HTML element that the button's markup should be
3092 * rendered into.
3093 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3094 * level-one-html.html#ID-58190037">HTMLElement</a>|String
3095 * @default null
3097 this.setAttributeConfig("container", {
3099 value: oAttributes.container,
3100 writeOnce: true
3106 * @config srcelement
3107 * @description Object reference to the HTML element (either
3108 * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code>)
3109 * used to create the button.
3110 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3111 * level-one-html.html#ID-58190037">HTMLElement</a>|String
3112 * @default null
3114 this.setAttributeConfig("srcelement", {
3116 value: oAttributes.srcelement,
3117 writeOnce: true
3123 * @config menu
3124 * @description Object specifying the menu for the button.
3125 * The value can be one of the following:
3126 * <ul>
3127 * <li>Object specifying a <a href="YAHOO.widget.Menu.html">
3128 * YAHOO.widget.Menu</a> instance.</li>
3129 * <li>Object specifying a <a href="YAHOO.widget.Overlay.html">
3130 * YAHOO.widget.Overlay</a> instance.</li>
3131 * <li>String specifying the id attribute of the <code>&#60;div&#62;
3132 * </code> element used to create the menu. By default the menu
3133 * will be created as an instance of
3134 * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>.
3135 * If the <a href="YAHOO.widget.Menu.html#CSS_CLASS_NAME">
3136 * default CSS class name for YAHOO.widget.Menu</a> is applied to
3137 * the <code>&#60;div&#62;</code> element, it will be created as an
3138 * instance of <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu
3139 * </a>.</li><li>String specifying the id attribute of the
3140 * <code>&#60;select&#62;</code> element used to create the menu.
3141 * </li><li>Object specifying the <code>&#60;div&#62;</code> element
3142 * used to create the menu.</li>
3143 * <li>Object specifying the <code>&#60;select&#62;</code> element
3144 * used to create the menu.</li>
3145 * <li>Array of object literals, each representing a set of
3146 * <a href="YAHOO.widget.MenuItem.html">YAHOO.widget.MenuItem</a>
3147 * configuration attributes.</li>
3148 * <li>Array of strings representing the text labels for each menu
3149 * item in the menu.</li>
3150 * </ul>
3151 * @type <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>|<a
3152 * href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|<a
3153 * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3154 * one-html.html#ID-58190037">HTMLElement</a>|String|Array
3155 * @default null
3157 this.setAttributeConfig("menu", {
3159 value: null,
3160 method: this._setMenu,
3161 writeOnce: true
3167 * @config lazyloadmenu
3168 * @description Boolean indicating the value to set for the
3169 * <a href="YAHOO.widget.Menu.html#lazyLoad">"lazyload"</a>
3170 * configuration property of the button's menu. Setting
3171 * "lazyloadmenu" to <code>true </code> will defer rendering of
3172 * the button's menu until the first time it is made visible.
3173 * If "lazyloadmenu" is set to <code>false</code>, the button's
3174 * menu will be rendered immediately if the button is in the
3175 * document, or in response to the button's "appendTo" event if
3176 * the button is not yet in the document. In either case, the
3177 * menu is rendered into the button's parent HTML element.
3178 * <em>This attribute does not apply if a
3179 * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a> or
3180 * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>
3181 * instance is passed as the value of the button's "menu"
3182 * configuration attribute. <a href="YAHOO.widget.Menu.html">
3183 * YAHOO.widget.Menu</a> or <a href="YAHOO.widget.Overlay.html">
3184 * YAHOO.widget.Overlay</a> instances should be rendered before
3185 * being set as the value for the "menu" configuration
3186 * attribute.</em>
3187 * @default true
3188 * @type Boolean
3190 this.setAttributeConfig("lazyloadmenu", {
3192 value: (oAttributes.lazyloadmenu === false ? false : true),
3193 validator: Lang.isBoolean,
3194 writeOnce: true
3200 * @config menuclassname
3201 * @description String representing the CSS class name to be
3202 * applied to the root element of the button's menu.
3203 * @type String
3204 * @default "yui-button-menu"
3206 this.setAttributeConfig("menuclassname", {
3208 value: (oAttributes.menuclassname || "yui-button-menu"),
3209 validator: Lang.isString,
3210 method: this._setMenuClassName,
3211 writeOnce: true
3213 });
3217 * @config selectedMenuItem
3218 * @description Number representing the index of the item in the
3219 * button's menu that is currently selected.
3220 * @type Number
3221 * @default null
3223 this.setAttributeConfig("selectedMenuItem", {
3225 value: 0,
3226 validator: Lang.isNumber,
3227 method: this._setSelectedMenuItem
3233 * @config onclick
3234 * @description Object literal representing the code to be executed
3235 * when the button is clicked. Format:<br> <code> {<br>
3236 * <strong>fn:</strong> Function, &#47;&#47; The handler to call
3237 * when the event fires.<br> <strong>obj:</strong> Object,
3238 * &#47;&#47; An object to pass back to the handler.<br>
3239 * <strong>scope:</strong> Object &#47;&#47; The object to use
3240 * for the scope of the handler.<br> } </code>
3241 * @type Object
3242 * @default null
3244 this.setAttributeConfig("onclick", {
3246 value: oAttributes.onclick,
3247 method: this._setOnClick
3253 * @config focusmenu
3254 * @description Boolean indicating whether or not the button's menu
3255 * should be focused when it is made visible.
3256 * @type Boolean
3257 * @default true
3259 this.setAttributeConfig("focusmenu", {
3261 value: (oAttributes.focusmenu === false ? false : true),
3262 validator: Lang.isBoolean
3270 * @method focus
3271 * @description Causes the button to receive the focus and fires the
3272 * button's "focus" event.
3274 focus: function () {
3276 if (!this.get("disabled")) {
3278 this._button.focus();
3286 * @method blur
3287 * @description Causes the button to lose focus and fires the button's
3288 * "blur" event.
3290 blur: function () {
3292 if (!this.get("disabled")) {
3294 this._button.blur();
3302 * @method hasFocus
3303 * @description Returns a boolean indicating whether or not the button
3304 * has focus.
3305 * @return {Boolean}
3307 hasFocus: function () {
3309 return (m_oFocusedButton == this);
3315 * @method isActive
3316 * @description Returns a boolean indicating whether or not the button
3317 * is active.
3318 * @return {Boolean}
3320 isActive: function () {
3322 return this.hasClass(this.CSS_CLASS_NAME + "-active");
3328 * @method getMenu
3329 * @description Returns a reference to the button's menu.
3330 * @return {<a href="YAHOO.widget.Overlay.html">
3331 * YAHOO.widget.Overlay</a>|<a
3332 * href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
3334 getMenu: function () {
3336 return this._menu;
3342 * @method getForm
3343 * @description Returns a reference to the button's parent form.
3344 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-
3345 * 20000929/level-one-html.html#ID-40002357">HTMLFormElement</a>}
3347 getForm: function () {
3349 return this._button.form;
3354 /**
3355 * @method getHiddenFields
3356 * @description Returns an <code>&#60;input&#62;</code> element or
3357 * array of form elements used to represent the button when its parent
3358 * form is submitted.
3359 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3360 * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
3362 getHiddenFields: function () {
3364 return this._hiddenFields;
3370 * @method destroy
3371 * @description Removes the button's element from its parent element and
3372 * removes all event handlers.
3374 destroy: function () {
3376 this.logger.log("Destroying ...");
3378 var oElement = this.get("element"),
3379 oParentNode = oElement.parentNode,
3380 oMenu = this._menu;
3382 if (oMenu) {
3384 this.logger.log("Destroying menu.");
3386 oMenu.destroy();
3390 this.logger.log("Removing DOM event handlers.");
3392 Event.purgeElement(oElement);
3393 Event.purgeElement(this._button);
3394 Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
3395 Event.removeListener(document, "keyup", this._onDocumentKeyUp);
3396 Event.removeListener(document, "mousedown",
3397 this._onDocumentMouseDown);
3400 var oForm = this.getForm();
3402 if (oForm) {
3404 Event.removeListener(oForm, "reset", this._onFormReset);
3405 Event.removeListener(oForm, "submit", this.createHiddenFields);
3410 oParentNode.removeChild(oElement);
3412 this.logger.log("Removing from document.");
3414 delete m_oButtons[this.get("id")];
3416 this.logger.log("Destroyed.");
3421 fireEvent: function (p_sType , p_aArgs) {
3423 // Disabled buttons should not respond to DOM events
3425 if (this.DOM_EVENTS[p_sType] && this.get("disabled")) {
3427 return;
3431 YAHOO.widget.Button.superclass.fireEvent.call(this, p_sType,
3432 p_aArgs);
3438 * @method toString
3439 * @description Returns a string representing the button.
3440 * @return {String}
3442 toString: function () {
3444 return ("Button " + this.get("id"));
3452 * @method YAHOO.widget.Button.onFormKeyPress
3453 * @description "keypress" event handler for the button's form.
3454 * @param {Event} p_oEvent Object representing the DOM event object passed
3455 * back by the event utility (YAHOO.util.Event).
3457 YAHOO.widget.Button.onFormKeyPress = function (p_oEvent) {
3459 var oTarget = Event.getTarget(p_oEvent),
3460 nCharCode = Event.getCharCode(p_oEvent),
3461 sNodeName = oTarget.nodeName && oTarget.nodeName.toUpperCase(),
3462 sType = oTarget.type,
3465 Boolean indicating if the form contains any enabled or
3466 disabled YUI submit buttons
3469 bFormContainsYUIButtons = false,
3471 oButton,
3473 oYUISubmitButton, // The form's first, enabled YUI submit button
3476 The form's first, enabled HTML submit button that precedes any
3477 YUI submit button
3480 oPrecedingSubmitButton,
3484 The form's first, enabled HTML submit button that follows a
3485 YUI button
3488 oFollowingSubmitButton;
3491 function isSubmitButton(p_oElement) {
3493 var sId,
3494 oSrcElement;
3496 switch (p_oElement.nodeName.toUpperCase()) {
3498 case "INPUT":
3499 case "BUTTON":
3501 if (p_oElement.type == "submit" && !p_oElement.disabled) {
3503 if (!bFormContainsYUIButtons &&
3504 !oPrecedingSubmitButton) {
3506 oPrecedingSubmitButton = p_oElement;
3510 if (oYUISubmitButton && !oFollowingSubmitButton) {
3512 oFollowingSubmitButton = p_oElement;
3518 break;
3521 default:
3523 sId = p_oElement.id;
3525 if (sId) {
3527 oButton = m_oButtons[sId];
3529 if (oButton) {
3531 bFormContainsYUIButtons = true;
3533 if (!oButton.get("disabled")) {
3535 oSrcElement = oButton.get("srcelement");
3537 if (!oYUISubmitButton &&
3538 (oButton.get("type") == "submit" ||
3539 (oSrcElement && oSrcElement.type == "submit")))
3542 oYUISubmitButton = oButton;
3552 break;
3559 if (nCharCode == 13 && ((sNodeName == "INPUT" && (sType == "text" ||
3560 sType == "password" || sType == "checkbox" || sType == "radio" ||
3561 sType == "file") ) || sNodeName == "SELECT"))
3564 Dom.getElementsBy(isSubmitButton, "*", this);
3567 if (oPrecedingSubmitButton) {
3570 Need to set focus to the first enabled submit button
3571 to make sure that IE includes its name and value
3572 in the form's data set.
3575 oPrecedingSubmitButton.focus();
3578 else if (!oPrecedingSubmitButton && oYUISubmitButton) {
3580 if (oFollowingSubmitButton) {
3583 Need to call "preventDefault" to ensure that
3584 the name and value of the regular submit button
3585 following the YUI button doesn't get added to the
3586 form's data set when it is submitted.
3589 Event.preventDefault(p_oEvent);
3593 oYUISubmitButton.submitForm();
3603 * @method addHiddenFieldsToForm
3604 * @description Searches the specified form and adds hidden fields for
3605 * instances of YAHOO.widget.Button that are of type "radio," "checkbox,"
3606 * "menu," and "split."
3607 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3608 * one-html.html#ID-40002357">HTMLFormElement</a>} p_oForm Object reference
3609 * for the form to search.
3611 YAHOO.widget.Button.addHiddenFieldsToForm = function (p_oForm) {
3613 var aButtons = Dom.getElementsByClassName(
3614 YAHOO.widget.Button.prototype.CSS_CLASS_NAME,
3615 "*",
3616 p_oForm),
3618 nButtons = aButtons.length,
3619 oButton,
3620 sId,
3623 if (nButtons > 0) {
3625 YAHOO.log("Form contains " + nButtons + " YUI buttons.");
3627 for (i = 0; i < nButtons; i++) {
3629 sId = aButtons[i].id;
3631 if (sId) {
3633 oButton = m_oButtons[sId];
3635 if (oButton) {
3637 oButton.createHiddenFields();
3651 // Events
3655 * @event focus
3656 * @description Fires when the menu item receives focus. Passes back a
3657 * single object representing the original DOM event object passed back by
3658 * the event utility (YAHOO.util.Event) when the event was fired. See
3659 * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
3660 * for more information on listening for this event.
3661 * @type YAHOO.util.CustomEvent
3666 * @event blur
3667 * @description Fires when the menu item loses the input focus. Passes back
3668 * a single object representing the original DOM event object passed back by
3669 * the event utility (YAHOO.util.Event) when the event was fired. See
3670 * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for
3671 * more information on listening for this event.
3672 * @type YAHOO.util.CustomEvent
3677 * @event option
3678 * @description Fires when the user invokes the button's option. Passes
3679 * back a single object representing the original DOM event (either
3680 * "mousedown" or "keydown") that caused the "option" event to fire. See
3681 * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
3682 * for more information on listening for this event.
3683 * @type YAHOO.util.CustomEvent
3686 })();
3687 (function () {
3689 // Shorthard for utilities
3691 var Dom = YAHOO.util.Dom,
3692 Event = YAHOO.util.Event,
3693 Lang = YAHOO.lang,
3694 Button = YAHOO.widget.Button,
3696 // Private collection of radio buttons
3698 m_oButtons = {};
3703 * The ButtonGroup class creates a set of buttons that are mutually
3704 * exclusive; checking one button in the set will uncheck all others in the
3705 * button group.
3706 * @param {String} p_oElement String specifying the id attribute of the
3707 * <code>&#60;div&#62;</code> element of the button group.
3708 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3709 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
3710 * specifying the <code>&#60;div&#62;</code> element of the button group.
3711 * @param {Object} p_oElement Object literal specifying a set of
3712 * configuration attributes used to create the button group.
3713 * @param {Object} p_oAttributes Optional. Object literal specifying a set
3714 * of configuration attributes used to create the button group.
3715 * @namespace YAHOO.widget
3716 * @class ButtonGroup
3717 * @constructor
3718 * @extends YAHOO.util.Element
3720 YAHOO.widget.ButtonGroup = function (p_oElement, p_oAttributes) {
3722 var fnSuperClass = YAHOO.widget.ButtonGroup.superclass.constructor,
3723 sNodeName,
3724 oElement,
3725 sId;
3727 if (arguments.length == 1 && !Lang.isString(p_oElement) &&
3728 !p_oElement.nodeName) {
3730 if (!p_oElement.id) {
3732 sId = Dom.generateId();
3734 p_oElement.id = sId;
3736 YAHOO.log("No value specified for the button group's \"id\"" +
3737 " attribute. Setting button group id to \"" + sId + "\".",
3738 "warn");
3742 this.logger = new YAHOO.widget.LogWriter("ButtonGroup " + sId);
3744 this.logger.log("No source HTML element. Building the button " +
3745 "group using the set of configuration attributes.");
3747 fnSuperClass.call(this, (this._createGroupElement()), p_oElement);
3750 else if (Lang.isString(p_oElement)) {
3752 oElement = Dom.get(p_oElement);
3754 if (oElement) {
3756 if (oElement.nodeName.toUpperCase() == this.NODE_NAME) {
3758 this.logger =
3759 new YAHOO.widget.LogWriter("ButtonGroup " + p_oElement);
3761 fnSuperClass.call(this, oElement, p_oAttributes);
3768 else {
3770 sNodeName = p_oElement.nodeName;
3772 if (sNodeName && sNodeName == this.NODE_NAME) {
3774 if (!p_oElement.id) {
3776 p_oElement.id = Dom.generateId();
3778 YAHOO.log("No value specified for the button group's" +
3779 " \"id\" attribute. Setting button group id " +
3780 "to \"" + p_oElement.id + "\".", "warn");
3784 this.logger =
3785 new YAHOO.widget.LogWriter("ButtonGroup " + p_oElement.id);
3787 fnSuperClass.call(this, p_oElement, p_oAttributes);
3796 YAHOO.extend(YAHOO.widget.ButtonGroup, YAHOO.util.Element, {
3799 // Protected properties
3802 /**
3803 * @property _buttons
3804 * @description Array of buttons in the button group.
3805 * @default null
3806 * @protected
3807 * @type Array
3809 _buttons: null,
3813 // Constants
3817 * @property NODE_NAME
3818 * @description The name of the tag to be used for the button
3819 * group's element.
3820 * @default "DIV"
3821 * @final
3822 * @type String
3824 NODE_NAME: "DIV",
3828 * @property CSS_CLASS_NAME
3829 * @description String representing the CSS class(es) to be applied
3830 * to the button group's element.
3831 * @default "yui-buttongroup"
3832 * @final
3833 * @type String
3835 CSS_CLASS_NAME: "yui-buttongroup",
3839 // Protected methods
3843 * @method _createGroupElement
3844 * @description Creates the button group's element.
3845 * @protected
3846 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3847 * level-one-html.html#ID-22445964">HTMLDivElement</a>}
3849 _createGroupElement: function () {
3851 var oElement = document.createElement(this.NODE_NAME);
3853 return oElement;
3859 // Protected attribute setter methods
3863 * @method _setDisabled
3864 * @description Sets the value of the button groups's
3865 * "disabled" attribute.
3866 * @protected
3867 * @param {Boolean} p_bDisabled Boolean indicating the value for
3868 * the button group's "disabled" attribute.
3870 _setDisabled: function (p_bDisabled) {
3872 var nButtons = this.getCount(),
3875 if (nButtons > 0) {
3877 i = nButtons - 1;
3879 do {
3881 this._buttons[i].set("disabled", p_bDisabled);
3884 while (i--);
3892 // Protected event handlers
3896 * @method _onKeyDown
3897 * @description "keydown" event handler for the button group.
3898 * @protected
3899 * @param {Event} p_oEvent Object representing the DOM event object
3900 * passed back by the event utility (YAHOO.util.Event).
3902 _onKeyDown: function (p_oEvent) {
3904 var oTarget = Event.getTarget(p_oEvent),
3905 nCharCode = Event.getCharCode(p_oEvent),
3906 sId = oTarget.parentNode.parentNode.id,
3907 oButton = m_oButtons[sId],
3908 nIndex = -1;
3911 if (nCharCode == 37 || nCharCode == 38) {
3913 nIndex = (oButton.index === 0) ?
3914 (this._buttons.length - 1) : (oButton.index - 1);
3917 else if (nCharCode == 39 || nCharCode == 40) {
3919 nIndex = (oButton.index === (this._buttons.length - 1)) ?
3920 0 : (oButton.index + 1);
3925 if (nIndex > -1) {
3927 this.check(nIndex);
3928 this.getButton(nIndex).focus();
3936 * @method _onAppendTo
3937 * @description "appendTo" event handler for the button group.
3938 * @protected
3939 * @param {Event} p_oEvent Object representing the event that was fired.
3941 _onAppendTo: function (p_oEvent) {
3943 var aButtons = this._buttons,
3944 nButtons = aButtons.length,
3947 for (i = 0; i < nButtons; i++) {
3949 aButtons[i].appendTo(this.get("element"));
3957 * @method _onButtonCheckedChange
3958 * @description "checkedChange" event handler for each button in the
3959 * button group.
3960 * @protected
3961 * @param {Event} p_oEvent Object representing the event that was fired.
3962 * @param {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
3963 * p_oButton Object representing the button that fired the event.
3965 _onButtonCheckedChange: function (p_oEvent, p_oButton) {
3967 var bChecked = p_oEvent.newValue,
3968 oCheckedButton = this.get("checkedButton");
3970 if (bChecked && oCheckedButton != p_oButton) {
3972 if (oCheckedButton) {
3974 oCheckedButton.set("checked", false, true);
3978 this.set("checkedButton", p_oButton);
3979 this.set("value", p_oButton.get("value"));
3982 else if (oCheckedButton && !oCheckedButton.set("checked")) {
3984 oCheckedButton.set("checked", true, true);
3992 // Public methods
3996 * @method init
3997 * @description The ButtonGroup class's initialization method.
3998 * @param {String} p_oElement String specifying the id attribute of the
3999 * <code>&#60;div&#62;</code> element of the button group.
4000 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4001 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
4002 * specifying the <code>&#60;div&#62;</code> element of the button group.
4003 * @param {Object} p_oElement Object literal specifying a set of
4004 * configuration attributes used to create the button group.
4005 * @param {Object} p_oAttributes Optional. Object literal specifying a
4006 * set of configuration attributes used to create the button group.
4008 init: function (p_oElement, p_oAttributes) {
4010 this._buttons = [];
4012 YAHOO.widget.ButtonGroup.superclass.init.call(this, p_oElement,
4013 p_oAttributes);
4015 this.addClass(this.CSS_CLASS_NAME);
4017 this.logger.log("Searching for child nodes with the class name " +
4018 "\"yui-radio-button\" to add to the button group.");
4020 var aButtons = this.getElementsByClassName("yui-radio-button");
4023 if (aButtons.length > 0) {
4025 this.logger.log("Found " + aButtons.length +
4026 " child nodes with the class name \"yui-radio-button.\"" +
4027 " Attempting to add to button group.");
4029 this.addButtons(aButtons);
4034 this.logger.log("Searching for child nodes with the type of " +
4035 " \"radio\" to add to the button group.");
4037 function isRadioButton(p_oElement) {
4039 return (p_oElement.type == "radio");
4043 aButtons =
4044 Dom.getElementsBy(isRadioButton, "input", this.get("element"));
4047 if (aButtons.length > 0) {
4049 this.logger.log("Found " + aButtons.length + " child nodes" +
4050 " with the type of \"radio.\" Attempting to add to" +
4051 " button group.");
4053 this.addButtons(aButtons);
4057 this.on("keydown", this._onKeyDown);
4058 this.on("appendTo", this._onAppendTo);
4061 var oContainer = this.get("container");
4063 if (oContainer) {
4065 if (Lang.isString(oContainer)) {
4067 Event.onContentReady(oContainer, function () {
4069 this.appendTo(oContainer);
4071 }, null, this);
4074 else {
4076 this.appendTo(oContainer);
4083 this.logger.log("Initialization completed.");
4089 * @method initAttributes
4090 * @description Initializes all of the configuration attributes used to
4091 * create the button group.
4092 * @param {Object} p_oAttributes Object literal specifying a set of
4093 * configuration attributes used to create the button group.
4095 initAttributes: function (p_oAttributes) {
4097 var oAttributes = p_oAttributes || {};
4099 YAHOO.widget.ButtonGroup.superclass.initAttributes.call(
4100 this, oAttributes);
4104 * @config name
4105 * @description String specifying the name for the button group.
4106 * This name will be applied to each button in the button group.
4107 * @default null
4108 * @type String
4110 this.setAttributeConfig("name", {
4112 value: oAttributes.name,
4113 validator: Lang.isString
4119 * @config disabled
4120 * @description Boolean indicating if the button group should be
4121 * disabled. Disabling the button group will disable each button
4122 * in the button group. Disabled buttons are dimmed and will not
4123 * respond to user input or fire events.
4124 * @default false
4125 * @type Boolean
4127 this.setAttributeConfig("disabled", {
4129 value: (oAttributes.disabled || false),
4130 validator: Lang.isBoolean,
4131 method: this._setDisabled
4137 * @config value
4138 * @description Object specifying the value for the button group.
4139 * @default null
4140 * @type Object
4142 this.setAttributeConfig("value", {
4144 value: oAttributes.value
4150 * @config container
4151 * @description HTML element reference or string specifying the id
4152 * attribute of the HTML element that the button group's markup
4153 * should be rendered into.
4154 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4155 * level-one-html.html#ID-58190037">HTMLElement</a>|String
4156 * @default null
4158 this.setAttributeConfig("container", {
4160 value: oAttributes.container,
4161 writeOnce: true
4167 * @config checkedButton
4168 * @description Reference for the button in the button group that
4169 * is checked.
4170 * @type {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4171 * @default null
4173 this.setAttributeConfig("checkedButton", {
4175 value: null
4183 * @method addButton
4184 * @description Adds the button to the button group.
4185 * @param {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4186 * p_oButton Object reference for the <a href="YAHOO.widget.Button.html">
4187 * YAHOO.widget.Button</a> instance to be added to the button group.
4188 * @param {String} p_oButton String specifying the id attribute of the
4189 * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code> element
4190 * to be used to create the button to be added to the button group.
4191 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4192 * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="
4193 * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#
4194 * ID-33759296">HTMLElement</a>} p_oButton Object reference for the
4195 * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code> element
4196 * to be used to create the button to be added to the button group.
4197 * @param {Object} p_oButton Object literal specifying a set of
4198 * <a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>
4199 * configuration attributes used to configure the button to be added to
4200 * the button group.
4201 * @return {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4203 addButton: function (p_oButton) {
4205 var oButton,
4206 oButtonElement,
4207 oGroupElement,
4208 nIndex,
4209 sButtonName,
4210 sGroupName;
4213 if (p_oButton instanceof Button &&
4214 p_oButton.get("type") == "radio") {
4216 oButton = p_oButton;
4219 else if (!Lang.isString(p_oButton) && !p_oButton.nodeName) {
4221 p_oButton.type = "radio";
4223 oButton = new Button(p_oButton);
4226 else {
4228 oButton = new Button(p_oButton, { type: "radio" });
4233 if (oButton) {
4235 nIndex = this._buttons.length;
4236 sButtonName = oButton.get("name");
4237 sGroupName = this.get("name");
4239 oButton.index = nIndex;
4241 this._buttons[nIndex] = oButton;
4242 m_oButtons[oButton.get("id")] = oButton;
4245 if (sButtonName != sGroupName) {
4247 oButton.set("name", sGroupName);
4252 if (this.get("disabled")) {
4254 oButton.set("disabled", true);
4259 if (oButton.get("checked")) {
4261 this.set("checkedButton", oButton);
4266 oButtonElement = oButton.get("element");
4267 oGroupElement = this.get("element");
4269 if (oButtonElement.parentNode != oGroupElement) {
4271 oGroupElement.appendChild(oButtonElement);
4276 oButton.on("checkedChange",
4277 this._onButtonCheckedChange, oButton, this);
4279 this.logger.log("Button " + oButton.get("id") + " added.");
4281 return oButton;
4289 * @method addButtons
4290 * @description Adds the array of buttons to the button group.
4291 * @param {Array} p_aButtons Array of <a href="YAHOO.widget.Button.html">
4292 * YAHOO.widget.Button</a> instances to be added
4293 * to the button group.
4294 * @param {Array} p_aButtons Array of strings specifying the id
4295 * attribute of the <code>&#60;input&#62;</code> or <code>&#60;span&#62;
4296 * </code> elements to be used to create the buttons to be added to the
4297 * button group.
4298 * @param {Array} p_aButtons Array of object references for the
4299 * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code> elements
4300 * to be used to create the buttons to be added to the button group.
4301 * @param {Array} p_aButtons Array of object literals, each containing
4302 * a set of <a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>
4303 * configuration attributes used to configure each button to be added
4304 * to the button group.
4305 * @return {Array}
4307 addButtons: function (p_aButtons) {
4309 var nButtons,
4310 oButton,
4311 aButtons,
4314 if (Lang.isArray(p_aButtons)) {
4316 nButtons = p_aButtons.length;
4317 aButtons = [];
4319 if (nButtons > 0) {
4321 for (i = 0; i < nButtons; i++) {
4323 oButton = this.addButton(p_aButtons[i]);
4325 if (oButton) {
4327 aButtons[aButtons.length] = oButton;
4333 if (aButtons.length > 0) {
4335 this.logger.log(aButtons.length + " buttons added.");
4337 return aButtons;
4349 * @method removeButton
4350 * @description Removes the button at the specified index from the
4351 * button group.
4352 * @param {Number} p_nIndex Number specifying the index of the button
4353 * to be removed from the button group.
4355 removeButton: function (p_nIndex) {
4357 var oButton = this.getButton(p_nIndex),
4358 nButtons,
4361 if (oButton) {
4363 this.logger.log("Removing button " + oButton.get("id") + ".");
4365 this._buttons.splice(p_nIndex, 1);
4366 delete m_oButtons[oButton.get("id")];
4368 oButton.removeListener("checkedChange",
4369 this._onButtonCheckedChange);
4371 oButton.destroy();
4374 nButtons = this._buttons.length;
4376 if (nButtons > 0) {
4378 i = this._buttons.length - 1;
4380 do {
4382 this._buttons[i].index = i;
4385 while (i--);
4389 this.logger.log("Button " + oButton.get("id") + " removed.");
4397 * @method getButton
4398 * @description Returns the button at the specified index.
4399 * @param {Number} p_nIndex The index of the button to retrieve from the
4400 * button group.
4401 * @return {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4403 getButton: function (p_nIndex) {
4405 if (Lang.isNumber(p_nIndex)) {
4407 return this._buttons[p_nIndex];
4415 * @method getButtons
4416 * @description Returns an array of the buttons in the button group.
4417 * @return {Array}
4419 getButtons: function () {
4421 return this._buttons;
4427 * @method getCount
4428 * @description Returns the number of buttons in the button group.
4429 * @return {Number}
4431 getCount: function () {
4433 return this._buttons.length;
4439 * @method focus
4440 * @description Sets focus to the button at the specified index.
4441 * @param {Number} p_nIndex Number indicating the index of the button
4442 * to focus.
4444 focus: function (p_nIndex) {
4446 var oButton,
4447 nButtons,
4450 if (Lang.isNumber(p_nIndex)) {
4452 oButton = this._buttons[p_nIndex];
4454 if (oButton) {
4456 oButton.focus();
4461 else {
4463 nButtons = this.getCount();
4465 for (i = 0; i < nButtons; i++) {
4467 oButton = this._buttons[i];
4469 if (!oButton.get("disabled")) {
4471 oButton.focus();
4472 break;
4484 * @method check
4485 * @description Checks the button at the specified index.
4486 * @param {Number} p_nIndex Number indicating the index of the button
4487 * to check.
4489 check: function (p_nIndex) {
4491 var oButton = this.getButton(p_nIndex);
4493 if (oButton) {
4495 oButton.set("checked", true);
4503 * @method destroy
4504 * @description Removes the button group's element from its parent
4505 * element and removes all event handlers.
4507 destroy: function () {
4509 this.logger.log("Destroying...");
4511 var nButtons = this._buttons.length,
4512 oElement = this.get("element"),
4513 oParentNode = oElement.parentNode,
4516 if (nButtons > 0) {
4518 i = this._buttons.length - 1;
4520 do {
4522 this._buttons[i].destroy();
4525 while (i--);
4529 this.logger.log("Removing DOM event handlers.");
4531 Event.purgeElement(oElement);
4533 this.logger.log("Removing from document.");
4535 oParentNode.removeChild(oElement);
4541 * @method toString
4542 * @description Returns a string representing the button group.
4543 * @return {String}
4545 toString: function () {
4547 return ("ButtonGroup " + this.get("id"));
4553 })();
4554 YAHOO.register("button", YAHOO.widget.Button, {version: "2.3.0", build: "442"});