2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
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>
21 * <dd>Basic push button that can execute a user-specified command when
24 * <dd>Navigates to a specified url when pressed.</dd>
26 * <dd>Submits the parent form when pressed.</dd>
28 * <dd>Resets the parent form when pressed.</dd>
30 * <dd>Maintains a "checked" state that can be toggled on and off.</dd>
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
37 * <dd>When pressed will show/hide a menu.</dd>
39 * <dd>Can execute a user-specified command or display a menu when pressed.</dd>
42 * @namespace YAHOO.widget
43 * @requires yahoo, dom, element, event
44 * @optional container, menu
53 * The Button class creates a rich, graphical button.
54 * @param {String} p_oElement String specifying the id attribute of the
55 * <code><input></code>, <code><button></code>,
56 * <code><a></code>, or <code><span></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><input></code>, <code><button></code>,
65 * <code><a></code>, or <code><span></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
74 * @extends YAHOO.util.Element
79 // Shorthard for utilities
81 var Dom = YAHOO.util.Dom,
82 Event = YAHOO.util.Event,
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
102 * @method createInputElement
103 * @description Creates an <code><input></code> element of the
106 * @param {String} p_sType String specifying the type of
107 * <code><input></code> element to create.
108 * @param {String} p_sName String specifying the name of
109 * <code><input></code> element to create.
110 * @param {String} p_sValue String specifying the value of
111 * <code><input></code> element to create.
112 * @param {String} p_bChecked Boolean specifying if the
113 * <code><input></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) {
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
132 sInput = "<input type=\"" + p_sType + "\" name=\"" +
137 sInput += " checked";
143 oInput = document.createElement(sInput);
148 oInput = document.createElement("input");
149 oInput.name = p_sName;
150 oInput.type = p_sType;
154 oInput.checked = true;
160 oInput.value = p_sValue;
170 * @method setAttributesFromSrcElement
171 * @description Gets the values for all the attributes of the source element
172 * (either <code><input></code> or <code><a></code>) that
173 * map to Button configuration attributes and sets them into a collection
174 * that is passed to the Button constructor.
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><input></code> or <code><span>
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(),
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
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><button></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)) {
220 p_oAttributes[p_sAttribute] = oAttribute.value;
230 * @method setFormElementProperties
231 * @description Gets the value of the attributes from the form element
232 * and sets them into the collection of configuration attributes used to
233 * configure the button.
236 function setFormElementProperties() {
238 setAttributeFromDOMAttribute("type");
240 if (p_oAttributes.type == "button") {
242 p_oAttributes.type = "push";
246 if ( !("disabled" in p_oAttributes) ) {
248 p_oAttributes.disabled = p_oElement.disabled;
252 setAttributeFromDOMAttribute("name");
253 setAttributeFromDOMAttribute("value");
254 setAttributeFromDOMAttribute("title");
259 switch (sSrcElementNodeName) {
263 p_oAttributes.type = "link";
265 setAttributeFromDOMAttribute("href");
266 setAttributeFromDOMAttribute("target");
272 setFormElementProperties();
274 if ( !("checked" in p_oAttributes) ) {
276 p_oAttributes.checked = p_oElement.checked;
284 setFormElementProperties();
286 oRootNode = p_oElement.parentNode.parentNode;
288 if (Dom.hasClass(oRootNode, this.CSS_CLASS_NAME + "-checked")) {
290 p_oAttributes.checked = true;
294 if (Dom.hasClass(oRootNode, this.CSS_CLASS_NAME + "-disabled")) {
296 p_oAttributes.disabled = true;
300 p_oElement.removeAttribute("value");
302 p_oElement.setAttribute("type", "button");
308 p_oElement.removeAttribute("id");
309 p_oElement.removeAttribute("name");
311 if ( !("tabindex" in p_oAttributes) ) {
313 p_oAttributes.tabindex = p_oElement.tabIndex;
317 if ( !("label" in p_oAttributes) ) {
319 // Set the "label" property
321 sText = sSrcElementNodeName == "INPUT" ?
322 p_oElement.value : p_oElement.innerHTML;
325 if (sText && sText.length > 0) {
327 p_oAttributes.label = sText;
338 * @description Initializes the set of configuration attributes that are
339 * used to instantiate the button.
341 * @param {Object} Object representing the button's set of
342 * configuration attributes.
344 function initConfig(p_oConfig) {
346 var oAttributes = p_oConfig.attributes,
347 oSrcElement = oAttributes.srcelement,
348 sSrcElementNodeName = oSrcElement.nodeName.toUpperCase(),
352 if (sSrcElementNodeName == this.NODE_NAME) {
354 p_oConfig.element = oSrcElement;
355 p_oConfig.id = oSrcElement.id;
357 Dom.getElementsBy(function (p_oElement) {
359 switch (p_oElement.nodeName.toUpperCase()) {
365 setAttributesFromSrcElement.call(me, p_oElement,
372 }, "*", oSrcElement);
377 switch (sSrcElementNodeName) {
383 setAttributesFromSrcElement.call(this, oSrcElement,
398 YAHOO.widget.Button = function (p_oElement, p_oAttributes) {
400 var fnSuperClass = YAHOO.widget.Button.superclass.constructor,
404 if (arguments.length == 1 && !Lang.isString(p_oElement) &&
405 !p_oElement.nodeName) {
407 if (!p_oElement.id) {
409 p_oElement.id = Dom.generateId();
416 fnSuperClass.call(this,
417 (this.createButtonElement(p_oElement.type)),
423 oConfig = { element: null, attributes: (p_oAttributes || {}) };
426 if (Lang.isString(p_oElement)) {
428 oElement = Dom.get(p_oElement);
432 if (!oConfig.attributes.id) {
434 oConfig.attributes.id = p_oElement;
441 oConfig.attributes.srcelement = oElement;
443 initConfig.call(this, oConfig);
446 if (!oConfig.element) {
450 this.createButtonElement(oConfig.attributes.type);
454 fnSuperClass.call(this, oConfig.element,
460 else if (p_oElement.nodeName) {
462 if (!oConfig.attributes.id) {
466 oConfig.attributes.id = p_oElement.id;
471 oConfig.attributes.id = Dom.generateId();
482 oConfig.attributes.srcelement = p_oElement;
484 initConfig.call(this, oConfig);
487 if (!oConfig.element) {
491 this.createButtonElement(oConfig.attributes.type);
495 fnSuperClass.call(this, oConfig.element, oConfig.attributes);
505 YAHOO.extend(YAHOO.widget.Button, YAHOO.util.Element, {
508 // Protected properties
513 * @description Object reference to the button's internal
514 * <code><a></code> or <code><button></code> element.
517 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
518 * level-one-html.html#ID-48250443">HTMLAnchorElement</a>|<a href="
519 * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
520 * #ID-34812697">HTMLButtonElement</a>
527 * @description Object reference to the button's menu.
530 * @type {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|
531 * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
537 * @property _hiddenFields
538 * @description Object reference to the <code><input></code>
539 * element, or array of HTML form elements used to represent the button
540 * when its parent form is submitted.
543 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
544 * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array
550 * @property _onclickAttributeValue
551 * @description Object reference to the button's current value for the
552 * "onclick" configuration attribute.
557 _onclickAttributeValue: null,
561 * @property _activationKeyPressed
562 * @description Boolean indicating if the key(s) that toggle the button's
563 * "active" state have been pressed.
568 _activationKeyPressed: false,
572 * @property _activationButtonPressed
573 * @description Boolean indicating if the mouse button that toggles
574 * the button's "active" state has been pressed.
579 _activationButtonPressed: false,
583 * @property _hasKeyEventHandlers
584 * @description Boolean indicating if the button's "blur", "keydown" and
585 * "keyup" event handlers are assigned
590 _hasKeyEventHandlers: false,
594 * @property _hasMouseEventHandlers
595 * @description Boolean indicating if the button's "mouseout,"
596 * "mousedown," and "mouseup" event handlers are assigned
601 _hasMouseEventHandlers: false,
609 * @property NODE_NAME
610 * @description The name of the node to be used for the button's
620 * @property CHECK_ACTIVATION_KEYS
621 * @description Array of numbers representing keys that (when pressed)
622 * toggle the button's "checked" attribute.
627 CHECK_ACTIVATION_KEYS: [32],
631 * @property ACTIVATION_KEYS
632 * @description Array of numbers representing keys that (when presed)
633 * toggle the button's "active" state.
638 ACTIVATION_KEYS: [13, 32],
642 * @property OPTION_AREA_WIDTH
643 * @description Width (in pixels) of the area of a split button that
644 * when pressed will display a menu.
649 OPTION_AREA_WIDTH: 20,
653 * @property CSS_CLASS_NAME
654 * @description String representing the CSS class(es) to be applied to
655 * the button's root element.
656 * @default "yui-button"
660 CSS_CLASS_NAME: "yui-button",
664 * @property RADIO_DEFAULT_TITLE
665 * @description String representing the default title applied to buttons
667 * @default "Unchecked. Click to check."
671 RADIO_DEFAULT_TITLE: "Unchecked. Click to check.",
675 * @property RADIO_CHECKED_TITLE
676 * @description String representing the title applied to buttons of
677 * type "radio" when checked.
678 * @default "Checked. Click to uncheck."
682 RADIO_CHECKED_TITLE: "Checked. Click to uncheck.",
686 * @property CHECKBOX_DEFAULT_TITLE
687 * @description String representing the default title applied to
688 * buttons of type "checkbox."
689 * @default "Unchecked. Click to check."
693 CHECKBOX_DEFAULT_TITLE: "Unchecked. Click to check.",
697 * @property CHECKBOX_CHECKED_TITLE
698 * @description String representing the title applied to buttons of type
699 * "checkbox" when checked.
700 * @default "Checked. Click to uncheck."
704 CHECKBOX_CHECKED_TITLE: "Checked. Click to uncheck.",
708 * @property MENUBUTTON_DEFAULT_TITLE
709 * @description String representing the default title applied to
710 * buttons of type "menu."
711 * @default "Menu collapsed. Click to expand."
715 MENUBUTTON_DEFAULT_TITLE: "Menu collapsed. Click to expand.",
719 * @property MENUBUTTON_MENU_VISIBLE_TITLE
720 * @description String representing the title applied to buttons of type
721 * "menu" when the button's menu is visible.
722 * @default "Menu expanded. Click or press Esc to collapse."
726 MENUBUTTON_MENU_VISIBLE_TITLE:
727 "Menu expanded. Click or press Esc to collapse.",
731 * @property SPLITBUTTON_DEFAULT_TITLE
732 * @description String representing the default title applied to
733 * buttons of type "split."
734 * @default "Menu collapsed. Click inside option region or press
735 * Ctrl + Shift + M to show the menu."
739 SPLITBUTTON_DEFAULT_TITLE: ("Menu collapsed. Click inside option " +
740 "region or press Ctrl + Shift + M to show the menu."),
744 * @property SPLITBUTTON_OPTION_VISIBLE_TITLE
745 * @description String representing the title applied to buttons of type
746 * "split" when the button's menu is visible.
747 * @default "Menu expanded. Press Esc or Ctrl + Shift + M to hide
752 SPLITBUTTON_OPTION_VISIBLE_TITLE:
753 "Menu expanded. Press Esc or Ctrl + Shift + M to hide the menu.",
757 * @property SUBMIT_TITLE
758 * @description String representing the title applied to buttons of
760 * @default "Click to submit form."
764 SUBMIT_TITLE: "Click to submit form.",
768 // Protected attribute setter methods
773 * @description Sets the value of the button's "type" attribute.
775 * @param {String} p_sType String indicating the value for the button's
778 _setType: function (p_sType) {
780 if (p_sType == "split") {
782 this.on("option", this._onOption);
791 * @description Sets the value of the button's "label" attribute.
793 * @param {String} p_sLabel String indicating the value for the button's
796 _setLabel: function (p_sLabel) {
798 this._button.innerHTML = p_sLabel;
804 * @method _setTabIndex
805 * @description Sets the value of the button's "tabindex" attribute.
807 * @param {Number} p_nTabIndex Number indicating the value for the
808 * button's "tabindex" attribute.
810 _setTabIndex: function (p_nTabIndex) {
812 this._button.tabIndex = p_nTabIndex;
819 * @description Sets the value of the button's "title" attribute.
821 * @param {String} p_nTabIndex Number indicating the value for
822 * the button's "title" attribute.
824 _setTitle: function (p_sTitle) {
826 var sTitle = p_sTitle;
828 if (this.get("type") != "link") {
832 switch (this.get("type")) {
836 sTitle = this.RADIO_DEFAULT_TITLE;
842 sTitle = this.CHECKBOX_DEFAULT_TITLE;
848 sTitle = this.MENUBUTTON_DEFAULT_TITLE;
854 sTitle = this.SPLITBUTTON_DEFAULT_TITLE;
860 sTitle = this.SUBMIT_TITLE;
868 this._button.title = sTitle;
876 * @method _setDisabled
877 * @description Sets the value of the button's "disabled" attribute.
879 * @param {Boolean} p_bDisabled Boolean indicating the value for
880 * the button's "disabled" attribute.
882 _setDisabled: function (p_bDisabled) {
884 if (this.get("type") != "link") {
894 if (this.hasFocus()) {
900 this._button.setAttribute("disabled", "disabled");
902 this.addStateCSSClasses("disabled");
907 this._button.removeAttribute("disabled");
909 this.removeStateCSSClasses("disabled");
920 * @description Sets the value of the button's "href" attribute.
922 * @param {String} p_sHref String indicating the value for the button's
925 _setHref: function (p_sHref) {
927 if (this.get("type") == "link") {
929 this._button.href = p_sHref;
938 * @description Sets the value of the button's "target" attribute.
940 * @param {String} p_sTarget String indicating the value for the button's
941 * "target" attribute.
943 _setTarget: function (p_sTarget) {
945 if (this.get("type") == "link") {
947 this._button.setAttribute("target", p_sTarget);
955 * @method _setChecked
956 * @description Sets the value of the button's "target" attribute.
958 * @param {Boolean} p_bChecked Boolean indicating the value for
959 * the button's "checked" attribute.
961 _setChecked: function (p_bChecked) {
963 var sType = this.get("type"),
966 if (sType == "checkbox" || sType == "radio") {
970 this.addStateCSSClasses("checked");
972 sTitle = (sType == "radio") ?
973 this.RADIO_CHECKED_TITLE :
974 this.CHECKBOX_CHECKED_TITLE;
979 this.removeStateCSSClasses("checked");
981 sTitle = (sType == "radio") ?
982 this.RADIO_DEFAULT_TITLE :
983 this.CHECKBOX_DEFAULT_TITLE;
987 this.set("title", sTitle);
996 * @description Sets the value of the button's "menu" attribute.
998 * @param {Object} p_oMenu Object indicating the value for the button's
1001 _setMenu: function (p_oMenu) {
1003 var bLazyLoad = this.get("lazyloadmenu"),
1004 oButtonElement = this.get("element"),
1007 Boolean indicating if the value of p_oMenu is an instance
1008 of YAHOO.widget.Menu or YAHOO.widget.Overlay.
1039 function onAppendTo() {
1041 oMenu.render(oButtonElement.parentNode);
1043 this.removeListener("appendTo", onAppendTo);
1048 function initMenu() {
1052 Dom.addClass(oMenu.element, this.get("menuclassname"));
1053 Dom.addClass(oMenu.element,
1054 "yui-" + this.get("type") + "-button-menu");
1056 oMenu.showEvent.subscribe(this._onMenuShow, null, this);
1057 oMenu.hideEvent.subscribe(this._onMenuHide, null, this);
1058 oMenu.renderEvent.subscribe(this._onMenuRender, null, this);
1061 if (oMenu instanceof Menu) {
1063 oMenu.keyDownEvent.subscribe(this._onMenuKeyDown,
1066 oMenu.clickEvent.subscribe(this._onMenuClick,
1069 oMenu.itemAddedEvent.subscribe(this._onMenuItemAdded,
1072 oSrcElement = oMenu.srcElement;
1075 oSrcElement.nodeName.toUpperCase() == "SELECT") {
1077 oSrcElement.style.display = "none";
1078 oSrcElement.parentNode.removeChild(oSrcElement);
1083 else if (oMenu instanceof Overlay) {
1085 if (!m_oOverlayManager) {
1088 new YAHOO.widget.OverlayManager();
1092 m_oOverlayManager.register(oMenu);
1102 if (bLazyLoad && !(oMenu instanceof Menu)) {
1105 Mimic Menu's "lazyload" functionality by adding
1106 a "beforeshow" event listener that renders the
1107 Overlay instance before it is made visible by
1111 oMenu.beforeShowEvent.subscribe(
1112 this._onOverlayBeforeShow, null, this);
1115 else if (!bLazyLoad) {
1117 if (Dom.inDocument(oButtonElement)) {
1119 oMenu.render(oButtonElement.parentNode);
1124 this.on("appendTo", onAppendTo);
1137 if (p_oMenu && (p_oMenu instanceof Menu)) {
1140 aItems = oMenu.getItems();
1141 nItems = aItems.length;
1155 oItem.cfg.subscribeToConfigEvent("selected",
1156 this._onMenuItemSelected,
1167 initMenu.call(this);
1170 else if (p_oMenu && (p_oMenu instanceof Overlay)) {
1175 oMenu.cfg.setProperty("visible", false);
1176 oMenu.cfg.setProperty("context", [oButtonElement, "tl", "bl"]);
1178 initMenu.call(this);
1181 else if (Lang.isArray(p_oMenu)) {
1183 this.on("appendTo", function () {
1185 oMenu = new Menu(Dom.generateId(), { lazyload: bLazyLoad,
1186 itemdata: p_oMenu });
1188 initMenu.call(this);
1193 else if (Lang.isString(p_oMenu)) {
1195 oMenuElement = Dom.get(p_oMenu);
1199 if (Dom.hasClass(oMenuElement,
1200 Menu.prototype.CSS_CLASS_NAME) ||
1201 oMenuElement.nodeName == "SELECT") {
1203 oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1205 initMenu.call(this);
1210 oMenu = new Overlay(p_oMenu, { visible: false,
1211 context: [oButtonElement, "tl", "bl"] });
1213 initMenu.call(this);
1220 else if (p_oMenu && p_oMenu.nodeName) {
1222 if (Dom.hasClass(p_oMenu, Menu.prototype.CSS_CLASS_NAME) ||
1223 p_oMenu.nodeName == "SELECT") {
1225 oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1227 initMenu.call(this);
1234 Dom.generateId(p_oMenu);
1238 oMenu = new Overlay(p_oMenu, { visible: false,
1239 context: [oButtonElement, "tl", "bl"] });
1241 initMenu.call(this);
1251 * @method _setOnClick
1252 * @description Sets the value of the button's "onclick" attribute.
1254 * @param {Object} p_oObject Object indicating the value for the button's
1255 * "onclick" attribute.
1257 _setOnClick: function (p_oObject) {
1260 Remove any existing listeners if a "click" event handler
1261 has already been specified.
1264 if (this._onclickAttributeValue &&
1265 (this._onclickAttributeValue != p_oObject)) {
1267 this.removeListener("click", this._onclickAttributeValue.fn);
1269 this._onclickAttributeValue = null;
1274 if (!this._onclickAttributeValue &&
1275 Lang.isObject(p_oObject) &&
1276 Lang.isFunction(p_oObject.fn)) {
1278 this.on("click", p_oObject.fn, p_oObject.obj, p_oObject.scope);
1280 this._onclickAttributeValue = p_oObject;
1288 * @method _setSelectedMenuItem
1289 * @description Sets the value of the button's
1290 * "selectedMenuItem" attribute.
1292 * @param {Number} p_nIndex Number representing the index of the item
1293 * in the button's menu that is currently selected.
1295 _setSelectedMenuItem: function (p_nIndex) {
1297 var oMenu = this._menu,
1301 if (oMenu && oMenu instanceof Menu) {
1303 oMenuItem = oMenu.getItem(p_nIndex);
1306 if (oMenuItem && !oMenuItem.cfg.getProperty("selected")) {
1308 oMenuItem.cfg.setProperty("selected", true);
1317 // Protected methods
1322 * @method _isActivationKey
1323 * @description Determines if the specified keycode is one that toggles
1324 * the button's "active" state.
1326 * @param {Number} p_nKeyCode Number representing the keycode to
1330 _isActivationKey: function (p_nKeyCode) {
1332 var sType = this.get("type"),
1333 aKeyCodes = (sType == "checkbox" || sType == "radio") ?
1334 this.CHECK_ACTIVATION_KEYS : this.ACTIVATION_KEYS,
1336 nKeyCodes = aKeyCodes.length,
1339 if (nKeyCodes > 0) {
1345 if (p_nKeyCode == aKeyCodes[i]) {
1360 * @method _isSplitButtonOptionKey
1361 * @description Determines if the specified keycode is one that toggles
1362 * the display of the split button's menu.
1364 * @param {Event} p_oEvent Object representing the DOM event object
1365 * passed back by the event utility (YAHOO.util.Event).
1368 _isSplitButtonOptionKey: function (p_oEvent) {
1370 return (p_oEvent.ctrlKey && p_oEvent.shiftKey &&
1371 Event.getCharCode(p_oEvent) == 77);
1377 * @method _addListenersToForm
1378 * @description Adds event handlers to the button's form.
1381 _addListenersToForm: function () {
1383 var oForm = this.getForm(),
1388 bHasKeyPressListener;
1393 Event.on(oForm, "reset", this._onFormReset, null, this);
1394 Event.on(oForm, "submit", this.createHiddenFields, null, this);
1396 oSrcElement = this.get("srcelement");
1399 if (this.get("type") == "submit" ||
1400 (oSrcElement && oSrcElement.type == "submit"))
1403 aListeners = Event.getListeners(oForm, "keypress");
1404 bHasKeyPressListener = false;
1408 nListeners = aListeners.length;
1410 if (nListeners > 0) {
1416 if (aListeners[i].fn ==
1417 YAHOO.widget.Button.onFormKeyPress)
1420 bHasKeyPressListener = true;
1433 if (!bHasKeyPressListener) {
1435 Event.on(oForm, "keypress",
1436 YAHOO.widget.Button.onFormKeyPress);
1447 _originalMaxHeight: -1,
1452 * @description Shows the button's menu.
1454 * @param {Event} p_oEvent Object representing the DOM event object
1455 * passed back by the event utility (YAHOO.util.Event) that triggered
1456 * the display of the menu.
1458 _showMenu: function (p_oEvent) {
1460 YAHOO.widget.MenuManager.hideVisible();
1462 if (m_oOverlayManager) {
1464 m_oOverlayManager.hideAll();
1469 var oMenu = this._menu,
1470 nViewportHeight = Dom.getViewportHeight(),
1476 if (oMenu && (oMenu instanceof Menu)) {
1478 oMenu.cfg.applyConfig({ context: [this.get("id"), "tl", "bl"],
1479 constraintoviewport: false,
1483 oMenu.cfg.fireQueue();
1485 oMenu.align("tl", "bl");
1488 Stop the propagation of the event so that the MenuManager
1489 doesn't blur the menu after it gets focus.
1492 if (p_oEvent.type == "mousedown") {
1494 Event.stopPropagation(p_oEvent);
1499 if (this.get("focusmenu")) {
1505 nMenuHeight = oMenu.element.offsetHeight;
1508 if ((oMenu.cfg.getProperty("y") + nMenuHeight) >
1512 oMenu.align("bl", "tl");
1514 nY = oMenu.cfg.getProperty("y");
1516 nScrollTop = Dom.getDocumentScrollTop();
1519 if (nScrollTop >= nY) {
1521 if (this._originalMaxHeight == -1) {
1523 this._originalMaxHeight =
1524 oMenu.cfg.getProperty("maxheight");
1528 oMenu.cfg.setProperty("maxheight",
1529 (nMenuHeight - ((nScrollTop - nY) + 20)));
1531 oMenu.align("bl", "tl");
1538 else if (oMenu && (oMenu instanceof Overlay)) {
1541 oMenu.align("tl", "bl");
1543 nMenuHeight = oMenu.element.offsetHeight;
1546 if ((oMenu.cfg.getProperty("y") + nMenuHeight) >
1550 oMenu.align("bl", "tl");
1561 * @description Hides the button's menu.
1564 _hideMenu: function () {
1566 var oMenu = this._menu;
1579 // Protected event handlers
1583 * @method _onMouseOver
1584 * @description "mouseover" event handler for the button.
1586 * @param {Event} p_oEvent Object representing the DOM event object
1587 * passed back by the event utility (YAHOO.util.Event).
1589 _onMouseOver: function (p_oEvent) {
1591 if (!this._hasMouseEventHandlers) {
1593 this.on("mouseout", this._onMouseOut);
1594 this.on("mousedown", this._onMouseDown);
1595 this.on("mouseup", this._onMouseUp);
1597 this._hasMouseEventHandlers = true;
1601 this.addStateCSSClasses("hover");
1603 if (this._activationButtonPressed) {
1605 this.addStateCSSClasses("active");
1610 if (this._bOptionPressed) {
1612 this.addStateCSSClasses("activeoption");
1620 * @method _onMouseOut
1621 * @description "mouseout" event handler for the button.
1623 * @param {Event} p_oEvent Object representing the DOM event object
1624 * passed back by the event utility (YAHOO.util.Event).
1626 _onMouseOut: function (p_oEvent) {
1628 this.removeStateCSSClasses("hover");
1630 if (this.get("type") != "menu") {
1632 this.removeStateCSSClasses("active");
1636 if (this._activationButtonPressed || this._bOptionPressed) {
1638 Event.on(document, "mouseup", this._onDocumentMouseUp,
1647 * @method _onDocumentMouseUp
1648 * @description "mouseup" event handler for the button.
1650 * @param {Event} p_oEvent Object representing the DOM event object
1651 * passed back by the event utility (YAHOO.util.Event).
1653 _onDocumentMouseUp: function (p_oEvent) {
1655 this._activationButtonPressed = false;
1656 this._bOptionPressed = false;
1658 var sType = this.get("type");
1660 if (sType == "menu" || sType == "split") {
1662 this.removeStateCSSClasses(
1663 (sType == "menu" ? "active" : "activeoption"));
1669 Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
1675 * @method _onMouseDown
1676 * @description "mousedown" event handler for the button.
1678 * @param {Event} p_oEvent Object representing the DOM event object
1679 * passed back by the event utility (YAHOO.util.Event).
1681 _onMouseDown: function (p_oEvent) {
1689 function onMouseUp() {
1692 this.removeListener("mouseup", onMouseUp);
1697 if ((p_oEvent.which || p_oEvent.button) == 1) {
1700 if (!this.hasFocus()) {
1707 sType = this.get("type");
1710 if (sType == "split") {
1712 oElement = this.get("element");
1713 nX = Event.getPageX(p_oEvent) - Dom.getX(oElement);
1715 if ((oElement.offsetWidth - this.OPTION_AREA_WIDTH) < nX) {
1717 this.fireEvent("option", p_oEvent);
1722 this.addStateCSSClasses("active");
1724 this._activationButtonPressed = true;
1729 else if (sType == "menu") {
1731 if (this.isActive()) {
1735 this._activationButtonPressed = false;
1740 this._showMenu(p_oEvent);
1742 this._activationButtonPressed = true;
1749 this.addStateCSSClasses("active");
1751 this._activationButtonPressed = true;
1757 if (sType == "split" || sType == "menu") {
1761 this._hideMenuTimerId = window.setTimeout(function () {
1763 me.on("mouseup", onMouseUp);
1775 * @method _onMouseUp
1776 * @description "mouseup" event handler for the button.
1778 * @param {Event} p_oEvent Object representing the DOM event object
1779 * passed back by the event utility (YAHOO.util.Event).
1781 _onMouseUp: function (p_oEvent) {
1783 var sType = this.get("type");
1786 if (this._hideMenuTimerId) {
1788 window.clearTimeout(this._hideMenuTimerId);
1793 if (sType == "checkbox" || sType == "radio") {
1795 this.set("checked", !(this.get("checked")));
1800 this._activationButtonPressed = false;
1803 if (this.get("type") != "menu") {
1805 this.removeStateCSSClasses("active");
1814 * @description "focus" event handler for the button.
1816 * @param {Event} p_oEvent Object representing the DOM event object
1817 * passed back by the event utility (YAHOO.util.Event).
1819 _onFocus: function (p_oEvent) {
1823 this.addStateCSSClasses("focus");
1825 if (this._activationKeyPressed) {
1827 this.addStateCSSClasses("active");
1831 m_oFocusedButton = this;
1834 if (!this._hasKeyEventHandlers) {
1836 oElement = this._button;
1838 Event.on(oElement, "blur", this._onBlur, null, this);
1839 Event.on(oElement, "keydown", this._onKeyDown, null, this);
1840 Event.on(oElement, "keyup", this._onKeyUp, null, this);
1842 this._hasKeyEventHandlers = true;
1847 this.fireEvent("focus", p_oEvent);
1854 * @description "blur" event handler for the button.
1856 * @param {Event} p_oEvent Object representing the DOM event object
1857 * passed back by the event utility (YAHOO.util.Event).
1859 _onBlur: function (p_oEvent) {
1861 this.removeStateCSSClasses("focus");
1863 if (this.get("type") != "menu") {
1865 this.removeStateCSSClasses("active");
1869 if (this._activationKeyPressed) {
1871 Event.on(document, "keyup", this._onDocumentKeyUp, null, this);
1876 m_oFocusedButton = null;
1878 this.fireEvent("blur", p_oEvent);
1884 * @method _onDocumentKeyUp
1885 * @description "keyup" event handler for the document.
1887 * @param {Event} p_oEvent Object representing the DOM event object
1888 * passed back by the event utility (YAHOO.util.Event).
1890 _onDocumentKeyUp: function (p_oEvent) {
1892 if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1894 this._activationKeyPressed = false;
1896 Event.removeListener(document, "keyup", this._onDocumentKeyUp);
1904 * @method _onKeyDown
1905 * @description "keydown" event handler for the button.
1907 * @param {Event} p_oEvent Object representing the DOM event object
1908 * passed back by the event utility (YAHOO.util.Event).
1910 _onKeyDown: function (p_oEvent) {
1912 var oMenu = this._menu;
1915 if (this.get("type") == "split" &&
1916 this._isSplitButtonOptionKey(p_oEvent)) {
1918 this.fireEvent("option", p_oEvent);
1921 else if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1923 if (this.get("type") == "menu") {
1925 this._showMenu(p_oEvent);
1930 this._activationKeyPressed = true;
1932 this.addStateCSSClasses("active");
1939 if (oMenu && oMenu.cfg.getProperty("visible") &&
1940 Event.getCharCode(p_oEvent) == 27) {
1952 * @description "keyup" event handler for the button.
1954 * @param {Event} p_oEvent Object representing the DOM event object
1955 * passed back by the event utility (YAHOO.util.Event).
1957 _onKeyUp: function (p_oEvent) {
1961 if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1963 sType = this.get("type");
1965 if (sType == "checkbox" || sType == "radio") {
1967 this.set("checked", !(this.get("checked")));
1971 this._activationKeyPressed = false;
1973 if (this.get("type") != "menu") {
1975 this.removeStateCSSClasses("active");
1986 * @description "click" event handler for the button.
1988 * @param {Event} p_oEvent Object representing the DOM event object
1989 * passed back by the event utility (YAHOO.util.Event).
1991 _onClick: function (p_oEvent) {
1993 var sType = this.get("type"),
2006 if (this.get("checked")) {
2008 sTitle = (sType == "radio") ?
2009 this.RADIO_CHECKED_TITLE :
2010 this.CHECKBOX_CHECKED_TITLE;
2015 sTitle = (sType == "radio") ?
2016 this.RADIO_DEFAULT_TITLE :
2017 this.CHECKBOX_DEFAULT_TITLE;
2021 this.set("title", sTitle);
2033 oForm = this.getForm();
2045 sTitle = this._menu.cfg.getProperty("visible") ?
2046 this.MENUBUTTON_MENU_VISIBLE_TITLE :
2047 this.MENUBUTTON_DEFAULT_TITLE;
2049 this.set("title", sTitle);
2055 oElement = this.get("element");
2056 nX = Event.getPageX(p_oEvent) - Dom.getX(oElement);
2058 if ((oElement.offsetWidth - this.OPTION_AREA_WIDTH) < nX) {
2067 oSrcElement = this.get("srcelement");
2069 if (oSrcElement && oSrcElement.type == "submit") {
2077 sTitle = this._menu.cfg.getProperty("visible") ?
2078 this.SPLITBUTTON_OPTION_VISIBLE_TITLE :
2079 this.SPLITBUTTON_DEFAULT_TITLE;
2081 this.set("title", sTitle);
2091 * @method _onAppendTo
2092 * @description "appendTo" event handler for the button.
2094 * @param {Event} p_oEvent Object representing the DOM event object
2095 * passed back by the event utility (YAHOO.util.Event).
2097 _onAppendTo: function (p_oEvent) {
2100 It is necessary to call "getForm" using "setTimeout" to make
2101 sure that the button's "form" property returns a node
2102 reference. Sometimes, if you try to get the reference
2103 immediately after appending the field, it is null.
2108 window.setTimeout(function () {
2110 me._addListenersToForm();
2118 * @method _onFormReset
2119 * @description "reset" event handler for the button's form.
2121 * @param {Event} p_oEvent Object representing the DOM event
2122 * object passed back by the event utility (YAHOO.util.Event).
2124 _onFormReset: function (p_oEvent) {
2126 var sType = this.get("type"),
2129 if (sType == "checkbox" || sType == "radio") {
2131 this.resetValue("checked");
2136 if (oMenu && (oMenu instanceof Menu)) {
2138 this.resetValue("selectedMenuItem");
2146 * @method _onDocumentMouseDown
2147 * @description "mousedown" event handler for the document.
2149 * @param {Event} p_oEvent Object representing the DOM event object
2150 * passed back by the event utility (YAHOO.util.Event).
2152 _onDocumentMouseDown: function (p_oEvent) {
2154 var oTarget = Event.getTarget(p_oEvent),
2155 oButtonElement = this.get("element"),
2156 oMenuElement = this._menu.element;
2158 if (oTarget != oButtonElement &&
2159 !Dom.isAncestor(oButtonElement, oTarget) &&
2160 oTarget != oMenuElement &&
2161 !Dom.isAncestor(oMenuElement, oTarget)) {
2165 Event.removeListener(document, "mousedown",
2166 this._onDocumentMouseDown);
2175 * @description "option" event handler for the button.
2177 * @param {Event} p_oEvent Object representing the DOM event object
2178 * passed back by the event utility (YAHOO.util.Event).
2180 _onOption: function (p_oEvent) {
2182 if (this.hasClass("yui-split-button-activeoption")) {
2186 this._bOptionPressed = false;
2191 this._showMenu(p_oEvent);
2193 this._bOptionPressed = true;
2201 * @method _onOverlayBeforeShow
2202 * @description "beforeshow" event handler for the
2203 * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a> instance
2204 * serving as the button's menu.
2206 * @param {String} p_sType String representing the name of the event
2209 _onOverlayBeforeShow: function (p_sType) {
2211 var oMenu = this._menu;
2213 oMenu.render(this.get("element").parentNode);
2215 oMenu.beforeShowEvent.unsubscribe(this._onOverlayBeforeShow);
2221 * @method _onMenuShow
2222 * @description "show" event handler for the button's menu.
2224 * @param {String} p_sType String representing the name of the event
2227 _onMenuShow: function (p_sType) {
2229 Event.on(document, "mousedown", this._onDocumentMouseDown,
2235 if (this.get("type") == "split") {
2237 sTitle = this.SPLITBUTTON_OPTION_VISIBLE_TITLE;
2238 sState = "activeoption";
2243 sTitle = this.MENUBUTTON_MENU_VISIBLE_TITLE;
2248 this.addStateCSSClasses(sState);
2249 this.set("title", sTitle);
2255 * @method _onMenuHide
2256 * @description "hide" event handler for the button's menu.
2258 * @param {String} p_sType String representing the name of the event
2261 _onMenuHide: function (p_sType) {
2263 var oMenu = this._menu,
2267 if (oMenu && (oMenu instanceof Menu) &&
2268 this._originalMaxHeight != -1) {
2270 this._menu.cfg.setProperty("maxheight",
2271 this._originalMaxHeight);
2276 if (this.get("type") == "split") {
2278 sTitle = this.SPLITBUTTON_DEFAULT_TITLE;
2279 sState = "activeoption";
2284 sTitle = this.MENUBUTTON_DEFAULT_TITLE;
2289 this.removeStateCSSClasses(sState);
2290 this.set("title", sTitle);
2293 if (this.get("type") == "split") {
2295 this._bOptionPressed = false;
2303 * @method _onMenuKeyDown
2304 * @description "keydown" event handler for the button's menu.
2306 * @param {String} p_sType String representing the name of the event
2308 * @param {Array} p_aArgs Array of arguments sent when the event
2311 _onMenuKeyDown: function (p_sType, p_aArgs) {
2313 var oEvent = p_aArgs[0];
2315 if (Event.getCharCode(oEvent) == 27) {
2319 if (this.get("type") == "split") {
2321 this._bOptionPressed = false;
2331 * @method _onMenuRender
2332 * @description "render" event handler for the button's menu.
2334 * @param {String} p_sType String representing the name of the
2335 * event thatwas fired.
2337 _onMenuRender: function (p_sType) {
2339 var oButtonElement = this.get("element"),
2340 oButtonParent = oButtonElement.parentNode,
2341 oMenuElement = this._menu.element;
2344 if (oButtonParent != oMenuElement.parentNode) {
2346 oButtonParent.appendChild(oMenuElement);
2350 this.set("selectedMenuItem", this.get("selectedMenuItem"));
2356 * @method _onMenuItemSelected
2357 * @description "selectedchange" event handler for each item in the
2360 * @param {String} p_sType String representing the name of the event
2362 * @param {Array} p_aArgs Array of arguments sent when the event
2364 * @param {Number} p_nItem Number representing the index of the menu
2365 * item that subscribed to the event.
2367 _onMenuItemSelected: function (p_sType, p_aArgs, p_nItem) {
2369 var bSelected = p_aArgs[0];
2373 this.set("selectedMenuItem", p_nItem);
2381 * @method _onMenuItemAdded
2382 * @description "itemadded" event handler for the button's menu.
2384 * @param {String} p_sType String representing the name of the event
2386 * @param {Array} p_aArgs Array of arguments sent when the event
2388 * @param {<a href="YAHOO.widget.MenuItem.html">
2389 * YAHOO.widget.MenuItem</a>} p_oItem Object representing the menu
2390 * item that subscribed to the event.
2392 _onMenuItemAdded: function (p_sType, p_aArgs, p_oItem) {
2394 var oItem = p_aArgs[0];
2396 oItem.cfg.subscribeToConfigEvent("selected",
2397 this._onMenuItemSelected,
2405 * @method _onMenuClick
2406 * @description "click" event handler for the button's menu.
2408 * @param {String} p_sType String representing the name of the event
2410 * @param {Array} p_aArgs Array of arguments sent when the event
2413 _onMenuClick: function (p_sType, p_aArgs) {
2415 var oItem = p_aArgs[1],
2420 oSrcElement = this.get("srcelement");
2422 if (oSrcElement && oSrcElement.type == "submit") {
2440 * @method createButtonElement
2441 * @description Creates the button's HTML elements.
2442 * @param {String} p_sType String indicating the type of element
2444 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2445 * level-one-html.html#ID-58190037">HTMLElement</a>}
2447 createButtonElement: function (p_sType) {
2449 var sNodeName = this.NODE_NAME,
2450 oElement = document.createElement(sNodeName);
2452 oElement.innerHTML = "<" + sNodeName + " class=\"first-child\">" +
2453 (p_sType == "link" ? "<a></a>" :
2454 "<button type=\"button\"></button>") + "</" + sNodeName + ">";
2462 * @method addStateCSSClasses
2463 * @description Appends state-specific CSS classes to the button's root
2466 addStateCSSClasses: function (p_sState) {
2468 var sType = this.get("type");
2470 if (Lang.isString(p_sState)) {
2472 if (p_sState != "activeoption") {
2474 this.addClass(this.CSS_CLASS_NAME + ("-" + p_sState));
2478 this.addClass("yui-" + sType + ("-button-" + p_sState));
2486 * @method removeStateCSSClasses
2487 * @description Removes state-specific CSS classes to the button's root
2490 removeStateCSSClasses: function (p_sState) {
2492 var sType = this.get("type");
2494 if (Lang.isString(p_sState)) {
2496 this.removeClass(this.CSS_CLASS_NAME + ("-" + p_sState));
2497 this.removeClass("yui-" + sType + ("-button-" + p_sState));
2505 * @method createHiddenFields
2506 * @description Creates the button's hidden form field and appends it
2507 * to its parent form.
2508 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2509 * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
2511 createHiddenFields: function () {
2513 this.removeHiddenFields();
2515 var oForm = this.getForm(),
2526 if (oForm && !this.get("disabled")) {
2528 sType = this.get("type");
2529 bCheckable = (sType == "checkbox" || sType == "radio");
2532 if (bCheckable || (m_oSubmitTrigger == this)) {
2535 oButtonField = createInputElement(
2536 (bCheckable ? sType : "hidden"),
2539 this.get("checked"));
2546 oButtonField.style.display = "none";
2550 oForm.appendChild(oButtonField);
2560 if (oMenu && (oMenu instanceof Menu)) {
2563 oMenuField = oMenu.srcElement;
2564 oMenuItem = oMenu.getItem(this.get("selectedMenuItem"));
2567 oMenuField.nodeName.toUpperCase() == "SELECT") {
2569 oForm.appendChild(oMenuField);
2570 oMenuField.selectedIndex = oMenuItem.index;
2575 oValue = (oMenuItem.value === null ||
2576 oMenuItem.value === "") ?
2577 oMenuItem.cfg.getProperty("text") :
2580 sName = this.get("name");
2582 if (oValue && sName) {
2584 oMenuField = createInputElement("hidden",
2585 (sName + "_options"),
2588 oForm.appendChild(oMenuField);
2597 if (oButtonField && oMenuField) {
2599 this._hiddenFields = [oButtonField, oMenuField];
2602 else if (!oButtonField && oMenuField) {
2604 this._hiddenFields = oMenuField;
2607 else if (oButtonField && !oMenuField) {
2609 this._hiddenFields = oButtonField;
2614 return this._hiddenFields;
2622 * @method removeHiddenFields
2623 * @description Removes the button's hidden form field(s) from its
2626 removeHiddenFields: function () {
2628 var oField = this._hiddenFields,
2632 function removeChild(p_oElement) {
2634 if (Dom.inDocument(p_oElement)) {
2636 p_oElement.parentNode.removeChild(p_oElement);
2645 if (Lang.isArray(oField)) {
2647 nFields = oField.length;
2655 removeChild(oField[i]);
2665 removeChild(oField);
2669 this._hiddenFields = null;
2677 * @method submitForm
2678 * @description Submits the form to which the button belongs. Returns
2679 * true if the form was submitted successfully, false if the submission
2684 submitForm: function () {
2686 var oForm = this.getForm(),
2688 oSrcElement = this.get("srcelement"),
2691 Boolean indicating if the event fired successfully
2692 (was not cancelled by any handlers)
2695 bSubmitForm = false,
2702 if (this.get("type") == "submit" ||
2703 (oSrcElement && oSrcElement.type == "submit"))
2706 m_oSubmitTrigger = this;
2711 if (YAHOO.env.ua.ie) {
2713 bSubmitForm = oForm.fireEvent("onsubmit");
2716 else { // Gecko, Opera, and Safari
2718 oEvent = document.createEvent("HTMLEvents");
2719 oEvent.initEvent("submit", true, true);
2721 bSubmitForm = oForm.dispatchEvent(oEvent);
2727 In IE and Safari, dispatching a "submit" event to a form
2728 WILL cause the form's "submit" event to fire, but WILL NOT
2729 submit the form. Therefore, we need to call the "submit"
2733 if ((YAHOO.env.ua.ie || YAHOO.env.ua.webkit) && bSubmitForm) {
2748 * @description The Button class's initialization method.
2749 * @param {String} p_oElement String specifying the id attribute of the
2750 * <code><input></code>, <code><button></code>,
2751 * <code><a></code>, or <code><span></code> element to
2752 * be used to create the button.
2753 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2754 * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://
2755 * www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
2756 * #ID-34812697">HTMLButtonElement</a>|<a href="http://www.w3.org/TR
2757 * /2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-33759296">
2758 * HTMLElement</a>} p_oElement Object reference for the
2759 * <code><input></code>, <code><button></code>,
2760 * <code><a></code>, or <code><span></code> element to be
2761 * used to create the button.
2762 * @param {Object} p_oElement Object literal specifying a set of
2763 * configuration attributes used to create the button.
2764 * @param {Object} p_oAttributes Optional. Object literal specifying a
2765 * set of configuration attributes used to create the button.
2767 init: function (p_oElement, p_oAttributes) {
2769 var sNodeName = p_oAttributes.type == "link" ? "A" : "BUTTON",
2770 oSrcElement = p_oAttributes.srcelement,
2771 oButton = p_oElement.getElementsByTagName(sNodeName)[0],
2777 oInput = p_oElement.getElementsByTagName("INPUT")[0];
2782 oButton = document.createElement("BUTTON");
2783 oButton.setAttribute("type", "button");
2785 oInput.parentNode.replaceChild(oButton, oInput);
2791 this._button = oButton;
2794 YAHOO.widget.Button.superclass.init.call(this, p_oElement,
2798 m_oButtons[this.get("id")] = this;
2801 this.addClass(this.CSS_CLASS_NAME);
2803 this.addClass("yui-" + this.get("type") + "-button");
2805 Event.on(this._button, "focus", this._onFocus, null, this);
2806 this.on("mouseover", this._onMouseOver);
2807 this.on("click", this._onClick);
2808 this.on("appendTo", this._onAppendTo);
2811 var oContainer = this.get("container"),
2812 oElement = this.get("element"),
2813 bElInDoc = Dom.inDocument(oElement),
2819 if (oSrcElement && oSrcElement != oElement) {
2821 oParentNode = oSrcElement.parentNode;
2825 oParentNode.removeChild(oSrcElement);
2831 if (Lang.isString(oContainer)) {
2833 Event.onContentReady(oContainer, function () {
2835 this.appendTo(oContainer);
2842 this.appendTo(oContainer);
2847 else if (!bElInDoc && oSrcElement && oSrcElement != oElement) {
2849 oParentNode = oSrcElement.parentNode;
2853 this.fireEvent("beforeAppendTo", {
2854 type: "beforeAppendTo",
2858 oParentNode.replaceChild(oElement, oSrcElement);
2860 this.fireEvent("appendTo", {
2868 else if (this.get("type") != "link" && bElInDoc && oSrcElement &&
2869 oSrcElement == oElement) {
2871 this._addListenersToForm();
2880 * @method initAttributes
2881 * @description Initializes all of the configuration attributes used to
2882 * create the button.
2883 * @param {Object} p_oAttributes Object literal specifying a set of
2884 * configuration attributes used to create the button.
2886 initAttributes: function (p_oAttributes) {
2888 var oAttributes = p_oAttributes || {};
2890 YAHOO.widget.Button.superclass.initAttributes.call(this,
2896 * @description String specifying the button's type. Possible
2897 * values are: "push," "link," "submit," "reset," "checkbox,"
2898 * "radio," "menu," and "split."
2902 this.setAttributeConfig("type", {
2904 value: (oAttributes.type || "push"),
2905 validator: Lang.isString,
2907 method: this._setType
2914 * @description String specifying the button's text label
2919 this.setAttributeConfig("label", {
2921 value: oAttributes.label,
2922 validator: Lang.isString,
2923 method: this._setLabel
2930 * @description Object specifying the value for the button.
2934 this.setAttributeConfig("value", {
2936 value: oAttributes.value
2943 * @description String specifying the name for the button.
2947 this.setAttributeConfig("name", {
2949 value: oAttributes.name,
2950 validator: Lang.isString
2957 * @description Number specifying the tabindex for the button.
2961 this.setAttributeConfig("tabindex", {
2963 value: oAttributes.tabindex,
2964 validator: Lang.isNumber,
2965 method: this._setTabIndex
2972 * @description String specifying the title for the button.
2976 this.configureAttribute("title", {
2978 value: oAttributes.title,
2979 validator: Lang.isString,
2980 method: this._setTitle
2987 * @description Boolean indicating if the button should be disabled.
2988 * (Disabled buttons are dimmed and will not respond to user input
2989 * or fire events. Does not apply to button's of type "link.")
2993 this.setAttributeConfig("disabled", {
2995 value: (oAttributes.disabled || false),
2996 validator: Lang.isBoolean,
2997 method: this._setDisabled
3004 * @description String specifying the href for the button. Applies
3005 * only to buttons of type "link."
3008 this.setAttributeConfig("href", {
3010 value: oAttributes.href,
3011 validator: Lang.isString,
3012 method: this._setHref
3019 * @description String specifying the target for the button.
3020 * Applies only to buttons of type "link."
3023 this.setAttributeConfig("target", {
3025 value: oAttributes.target,
3026 validator: Lang.isString,
3027 method: this._setTarget
3034 * @description Boolean indicating if the button is checked.
3035 * Applies only to buttons of type "radio" and "checkbox."
3039 this.setAttributeConfig("checked", {
3041 value: (oAttributes.checked || false),
3042 validator: Lang.isBoolean,
3043 method: this._setChecked
3050 * @description HTML element reference or string specifying the id
3051 * attribute of the HTML element that the button's markup should be
3053 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3054 * level-one-html.html#ID-58190037">HTMLElement</a>|String
3057 this.setAttributeConfig("container", {
3059 value: oAttributes.container,
3066 * @config srcelement
3067 * @description Object reference to the HTML element (either
3068 * <code><input></code> or <code><span></code>)
3069 * used to create the button.
3070 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3071 * level-one-html.html#ID-58190037">HTMLElement</a>|String
3074 this.setAttributeConfig("srcelement", {
3076 value: oAttributes.srcelement,
3084 * @description Object specifying the menu for the button.
3085 * The value can be one of the following:
3087 * <li>Object specifying a <a href="YAHOO.widget.Menu.html">
3088 * YAHOO.widget.Menu</a> instance.</li>
3089 * <li>Object specifying a <a href="YAHOO.widget.Overlay.html">
3090 * YAHOO.widget.Overlay</a> instance.</li>
3091 * <li>String specifying the id attribute of the <code><div>
3092 * </code> element used to create the menu. By default the menu
3093 * will be created as an instance of
3094 * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>.
3095 * If the <a href="YAHOO.widget.Menu.html#CSS_CLASS_NAME">
3096 * default CSS class name for YAHOO.widget.Menu</a> is applied to
3097 * the <code><div></code> element, it will be created as an
3098 * instance of <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu
3099 * </a>.</li><li>String specifying the id attribute of the
3100 * <code><select></code> element used to create the menu.
3101 * </li><li>Object specifying the <code><div></code> element
3102 * used to create the menu.</li>
3103 * <li>Object specifying the <code><select></code> element
3104 * used to create the menu.</li>
3105 * <li>Array of object literals, each representing a set of
3106 * <a href="YAHOO.widget.MenuItem.html">YAHOO.widget.MenuItem</a>
3107 * configuration attributes.</li>
3108 * <li>Array of strings representing the text labels for each menu
3109 * item in the menu.</li>
3111 * @type <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>|<a
3112 * href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|<a
3113 * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3114 * one-html.html#ID-58190037">HTMLElement</a>|String|Array
3117 this.setAttributeConfig("menu", {
3120 method: this._setMenu,
3127 * @config lazyloadmenu
3128 * @description Boolean indicating the value to set for the
3129 * <a href="YAHOO.widget.Menu.html#lazyLoad">"lazyload"</a>
3130 * configuration property of the button's menu. Setting
3131 * "lazyloadmenu" to <code>true </code> will defer rendering of
3132 * the button's menu until the first time it is made visible.
3133 * If "lazyloadmenu" is set to <code>false</code>, the button's
3134 * menu will be rendered immediately if the button is in the
3135 * document, or in response to the button's "appendTo" event if
3136 * the button is not yet in the document. In either case, the
3137 * menu is rendered into the button's parent HTML element.
3138 * <em>This attribute does not apply if a
3139 * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a> or
3140 * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>
3141 * instance is passed as the value of the button's "menu"
3142 * configuration attribute. <a href="YAHOO.widget.Menu.html">
3143 * YAHOO.widget.Menu</a> or <a href="YAHOO.widget.Overlay.html">
3144 * YAHOO.widget.Overlay</a> instances should be rendered before
3145 * being set as the value for the "menu" configuration
3150 this.setAttributeConfig("lazyloadmenu", {
3152 value: (oAttributes.lazyloadmenu === false ? false : true),
3153 validator: Lang.isBoolean,
3160 * @config menuclassname
3161 * @description String representing the CSS class name to be
3162 * applied to the root element of the button's menu.
3164 * @default "yui-button-menu"
3166 this.setAttributeConfig("menuclassname", {
3168 value: (oAttributes.menuclassname || "yui-button-menu"),
3169 validator: Lang.isString,
3170 method: this._setMenuClassName,
3177 * @config selectedMenuItem
3178 * @description Number representing the index of the item in the
3179 * button's menu that is currently selected.
3183 this.setAttributeConfig("selectedMenuItem", {
3186 validator: Lang.isNumber,
3187 method: this._setSelectedMenuItem
3194 * @description Object literal representing the code to be executed
3195 * when the button is clicked. Format:<br> <code> {<br>
3196 * <strong>fn:</strong> Function, // The handler to call
3197 * when the event fires.<br> <strong>obj:</strong> Object,
3198 * // An object to pass back to the handler.<br>
3199 * <strong>scope:</strong> Object // The object to use
3200 * for the scope of the handler.<br> } </code>
3204 this.setAttributeConfig("onclick", {
3206 value: oAttributes.onclick,
3207 method: this._setOnClick
3214 * @description Boolean indicating whether or not the button's menu
3215 * should be focused when it is made visible.
3219 this.setAttributeConfig("focusmenu", {
3221 value: (oAttributes.focusmenu === false ? false : true),
3222 validator: Lang.isBoolean
3231 * @description Causes the button to receive the focus and fires the
3232 * button's "focus" event.
3234 focus: function () {
3236 if (!this.get("disabled")) {
3238 this._button.focus();
3247 * @description Causes the button to lose focus and fires the button's
3252 if (!this.get("disabled")) {
3254 this._button.blur();
3263 * @description Returns a boolean indicating whether or not the button
3267 hasFocus: function () {
3269 return (m_oFocusedButton == this);
3276 * @description Returns a boolean indicating whether or not the button
3280 isActive: function () {
3282 return this.hasClass(this.CSS_CLASS_NAME + "-active");
3289 * @description Returns a reference to the button's menu.
3290 * @return {<a href="YAHOO.widget.Overlay.html">
3291 * YAHOO.widget.Overlay</a>|<a
3292 * href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
3294 getMenu: function () {
3303 * @description Returns a reference to the button's parent form.
3304 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-
3305 * 20000929/level-one-html.html#ID-40002357">HTMLFormElement</a>}
3307 getForm: function () {
3309 return this._button.form;
3315 * @method getHiddenFields
3316 * @description Returns an <code><input></code> element or
3317 * array of form elements used to represent the button when its parent
3318 * form is submitted.
3319 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3320 * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
3322 getHiddenFields: function () {
3324 return this._hiddenFields;
3331 * @description Removes the button's element from its parent element and
3332 * removes all event handlers.
3334 destroy: function () {
3337 var oElement = this.get("element"),
3338 oParentNode = oElement.parentNode,
3349 Event.purgeElement(oElement);
3350 Event.purgeElement(this._button);
3351 Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
3352 Event.removeListener(document, "keyup", this._onDocumentKeyUp);
3353 Event.removeListener(document, "mousedown",
3354 this._onDocumentMouseDown);
3357 var oForm = this.getForm();
3361 Event.removeListener(oForm, "reset", this._onFormReset);
3362 Event.removeListener(oForm, "submit", this.createHiddenFields);
3367 oParentNode.removeChild(oElement);
3370 delete m_oButtons[this.get("id")];
3376 fireEvent: function (p_sType , p_aArgs) {
3378 // Disabled buttons should not respond to DOM events
3380 if (this.DOM_EVENTS[p_sType] && this.get("disabled")) {
3386 YAHOO.widget.Button.superclass.fireEvent.call(this, p_sType,
3394 * @description Returns a string representing the button.
3397 toString: function () {
3399 return ("Button " + this.get("id"));
3407 * @method YAHOO.widget.Button.onFormKeyPress
3408 * @description "keypress" event handler for the button's form.
3409 * @param {Event} p_oEvent Object representing the DOM event object passed
3410 * back by the event utility (YAHOO.util.Event).
3412 YAHOO.widget.Button.onFormKeyPress = function (p_oEvent) {
3414 var oTarget = Event.getTarget(p_oEvent),
3415 nCharCode = Event.getCharCode(p_oEvent),
3416 sNodeName = oTarget.nodeName && oTarget.nodeName.toUpperCase(),
3417 sType = oTarget.type,
3420 Boolean indicating if the form contains any enabled or
3421 disabled YUI submit buttons
3424 bFormContainsYUIButtons = false,
3428 oYUISubmitButton, // The form's first, enabled YUI submit button
3431 The form's first, enabled HTML submit button that precedes any
3435 oPrecedingSubmitButton,
3439 The form's first, enabled HTML submit button that follows a
3443 oFollowingSubmitButton;
3446 function isSubmitButton(p_oElement) {
3451 switch (p_oElement.nodeName.toUpperCase()) {
3456 if (p_oElement.type == "submit" && !p_oElement.disabled) {
3458 if (!bFormContainsYUIButtons &&
3459 !oPrecedingSubmitButton) {
3461 oPrecedingSubmitButton = p_oElement;
3465 if (oYUISubmitButton && !oFollowingSubmitButton) {
3467 oFollowingSubmitButton = p_oElement;
3478 sId = p_oElement.id;
3482 oButton = m_oButtons[sId];
3486 bFormContainsYUIButtons = true;
3488 if (!oButton.get("disabled")) {
3490 oSrcElement = oButton.get("srcelement");
3492 if (!oYUISubmitButton &&
3493 (oButton.get("type") == "submit" ||
3494 (oSrcElement && oSrcElement.type == "submit")))
3497 oYUISubmitButton = oButton;
3514 if (nCharCode == 13 && ((sNodeName == "INPUT" && (sType == "text" ||
3515 sType == "password" || sType == "checkbox" || sType == "radio" ||
3516 sType == "file") ) || sNodeName == "SELECT"))
3519 Dom.getElementsBy(isSubmitButton, "*", this);
3522 if (oPrecedingSubmitButton) {
3525 Need to set focus to the first enabled submit button
3526 to make sure that IE includes its name and value
3527 in the form's data set.
3530 oPrecedingSubmitButton.focus();
3533 else if (!oPrecedingSubmitButton && oYUISubmitButton) {
3535 if (oFollowingSubmitButton) {
3538 Need to call "preventDefault" to ensure that
3539 the name and value of the regular submit button
3540 following the YUI button doesn't get added to the
3541 form's data set when it is submitted.
3544 Event.preventDefault(p_oEvent);
3548 oYUISubmitButton.submitForm();
3558 * @method addHiddenFieldsToForm
3559 * @description Searches the specified form and adds hidden fields for
3560 * instances of YAHOO.widget.Button that are of type "radio," "checkbox,"
3561 * "menu," and "split."
3562 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3563 * one-html.html#ID-40002357">HTMLFormElement</a>} p_oForm Object reference
3564 * for the form to search.
3566 YAHOO.widget.Button.addHiddenFieldsToForm = function (p_oForm) {
3568 var aButtons = Dom.getElementsByClassName(
3569 YAHOO.widget.Button.prototype.CSS_CLASS_NAME,
3573 nButtons = aButtons.length,
3581 for (i = 0; i < nButtons; i++) {
3583 sId = aButtons[i].id;
3587 oButton = m_oButtons[sId];
3591 oButton.createHiddenFields();
3610 * @description Fires when the menu item receives focus. Passes back a
3611 * single object representing the original DOM event object passed back by
3612 * the event utility (YAHOO.util.Event) when the event was fired. See
3613 * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
3614 * for more information on listening for this event.
3615 * @type YAHOO.util.CustomEvent
3621 * @description Fires when the menu item loses the input focus. Passes back
3622 * a single object representing the original DOM event object passed back by
3623 * the event utility (YAHOO.util.Event) when the event was fired. See
3624 * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for
3625 * more information on listening for this event.
3626 * @type YAHOO.util.CustomEvent
3632 * @description Fires when the user invokes the button's option. Passes
3633 * back a single object representing the original DOM event (either
3634 * "mousedown" or "keydown") that caused the "option" event to fire. See
3635 * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
3636 * for more information on listening for this event.
3637 * @type YAHOO.util.CustomEvent
3643 // Shorthard for utilities
3645 var Dom = YAHOO.util.Dom,
3646 Event = YAHOO.util.Event,
3648 Button = YAHOO.widget.Button,
3650 // Private collection of radio buttons
3657 * The ButtonGroup class creates a set of buttons that are mutually
3658 * exclusive; checking one button in the set will uncheck all others in the
3660 * @param {String} p_oElement String specifying the id attribute of the
3661 * <code><div></code> element of the button group.
3662 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3663 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
3664 * specifying the <code><div></code> element of the button group.
3665 * @param {Object} p_oElement Object literal specifying a set of
3666 * configuration attributes used to create the button group.
3667 * @param {Object} p_oAttributes Optional. Object literal specifying a set
3668 * of configuration attributes used to create the button group.
3669 * @namespace YAHOO.widget
3670 * @class ButtonGroup
3672 * @extends YAHOO.util.Element
3674 YAHOO.widget.ButtonGroup = function (p_oElement, p_oAttributes) {
3676 var fnSuperClass = YAHOO.widget.ButtonGroup.superclass.constructor,
3681 if (arguments.length == 1 && !Lang.isString(p_oElement) &&
3682 !p_oElement.nodeName) {
3684 if (!p_oElement.id) {
3686 sId = Dom.generateId();
3688 p_oElement.id = sId;
3695 fnSuperClass.call(this, (this._createGroupElement()), p_oElement);
3698 else if (Lang.isString(p_oElement)) {
3700 oElement = Dom.get(p_oElement);
3704 if (oElement.nodeName.toUpperCase() == this.NODE_NAME) {
3707 fnSuperClass.call(this, oElement, p_oAttributes);
3716 sNodeName = p_oElement.nodeName;
3718 if (sNodeName && sNodeName == this.NODE_NAME) {
3720 if (!p_oElement.id) {
3722 p_oElement.id = Dom.generateId();
3728 fnSuperClass.call(this, p_oElement, p_oAttributes);
3737 YAHOO.extend(YAHOO.widget.ButtonGroup, YAHOO.util.Element, {
3740 // Protected properties
3744 * @property _buttons
3745 * @description Array of buttons in the button group.
3758 * @property NODE_NAME
3759 * @description The name of the tag to be used for the button
3769 * @property CSS_CLASS_NAME
3770 * @description String representing the CSS class(es) to be applied
3771 * to the button group's element.
3772 * @default "yui-buttongroup"
3776 CSS_CLASS_NAME: "yui-buttongroup",
3780 // Protected methods
3784 * @method _createGroupElement
3785 * @description Creates the button group's element.
3787 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3788 * level-one-html.html#ID-22445964">HTMLDivElement</a>}
3790 _createGroupElement: function () {
3792 var oElement = document.createElement(this.NODE_NAME);
3800 // Protected attribute setter methods
3804 * @method _setDisabled
3805 * @description Sets the value of the button groups's
3806 * "disabled" attribute.
3808 * @param {Boolean} p_bDisabled Boolean indicating the value for
3809 * the button group's "disabled" attribute.
3811 _setDisabled: function (p_bDisabled) {
3813 var nButtons = this.getCount(),
3822 this._buttons[i].set("disabled", p_bDisabled);
3833 // Protected event handlers
3837 * @method _onKeyDown
3838 * @description "keydown" event handler for the button group.
3840 * @param {Event} p_oEvent Object representing the DOM event object
3841 * passed back by the event utility (YAHOO.util.Event).
3843 _onKeyDown: function (p_oEvent) {
3845 var oTarget = Event.getTarget(p_oEvent),
3846 nCharCode = Event.getCharCode(p_oEvent),
3847 sId = oTarget.parentNode.parentNode.id,
3848 oButton = m_oButtons[sId],
3852 if (nCharCode == 37 || nCharCode == 38) {
3854 nIndex = (oButton.index === 0) ?
3855 (this._buttons.length - 1) : (oButton.index - 1);
3858 else if (nCharCode == 39 || nCharCode == 40) {
3860 nIndex = (oButton.index === (this._buttons.length - 1)) ?
3861 0 : (oButton.index + 1);
3869 this.getButton(nIndex).focus();
3877 * @method _onAppendTo
3878 * @description "appendTo" event handler for the button group.
3880 * @param {Event} p_oEvent Object representing the event that was fired.
3882 _onAppendTo: function (p_oEvent) {
3884 var aButtons = this._buttons,
3885 nButtons = aButtons.length,
3888 for (i = 0; i < nButtons; i++) {
3890 aButtons[i].appendTo(this.get("element"));
3898 * @method _onButtonCheckedChange
3899 * @description "checkedChange" event handler for each button in the
3902 * @param {Event} p_oEvent Object representing the event that was fired.
3903 * @param {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
3904 * p_oButton Object representing the button that fired the event.
3906 _onButtonCheckedChange: function (p_oEvent, p_oButton) {
3908 var bChecked = p_oEvent.newValue,
3909 oCheckedButton = this.get("checkedButton");
3911 if (bChecked && oCheckedButton != p_oButton) {
3913 if (oCheckedButton) {
3915 oCheckedButton.set("checked", false, true);
3919 this.set("checkedButton", p_oButton);
3920 this.set("value", p_oButton.get("value"));
3923 else if (oCheckedButton && !oCheckedButton.set("checked")) {
3925 oCheckedButton.set("checked", true, true);
3938 * @description The ButtonGroup class's initialization method.
3939 * @param {String} p_oElement String specifying the id attribute of the
3940 * <code><div></code> element of the button group.
3941 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3942 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
3943 * specifying the <code><div></code> element of the button group.
3944 * @param {Object} p_oElement Object literal specifying a set of
3945 * configuration attributes used to create the button group.
3946 * @param {Object} p_oAttributes Optional. Object literal specifying a
3947 * set of configuration attributes used to create the button group.
3949 init: function (p_oElement, p_oAttributes) {
3953 YAHOO.widget.ButtonGroup.superclass.init.call(this, p_oElement,
3956 this.addClass(this.CSS_CLASS_NAME);
3959 var aButtons = this.getElementsByClassName("yui-radio-button");
3962 if (aButtons.length > 0) {
3965 this.addButtons(aButtons);
3971 function isRadioButton(p_oElement) {
3973 return (p_oElement.type == "radio");
3978 Dom.getElementsBy(isRadioButton, "input", this.get("element"));
3981 if (aButtons.length > 0) {
3984 this.addButtons(aButtons);
3988 this.on("keydown", this._onKeyDown);
3989 this.on("appendTo", this._onAppendTo);
3992 var oContainer = this.get("container");
3996 if (Lang.isString(oContainer)) {
3998 Event.onContentReady(oContainer, function () {
4000 this.appendTo(oContainer);
4007 this.appendTo(oContainer);
4019 * @method initAttributes
4020 * @description Initializes all of the configuration attributes used to
4021 * create the button group.
4022 * @param {Object} p_oAttributes Object literal specifying a set of
4023 * configuration attributes used to create the button group.
4025 initAttributes: function (p_oAttributes) {
4027 var oAttributes = p_oAttributes || {};
4029 YAHOO.widget.ButtonGroup.superclass.initAttributes.call(
4035 * @description String specifying the name for the button group.
4036 * This name will be applied to each button in the button group.
4040 this.setAttributeConfig("name", {
4042 value: oAttributes.name,
4043 validator: Lang.isString
4050 * @description Boolean indicating if the button group should be
4051 * disabled. Disabling the button group will disable each button
4052 * in the button group. Disabled buttons are dimmed and will not
4053 * respond to user input or fire events.
4057 this.setAttributeConfig("disabled", {
4059 value: (oAttributes.disabled || false),
4060 validator: Lang.isBoolean,
4061 method: this._setDisabled
4068 * @description Object specifying the value for the button group.
4072 this.setAttributeConfig("value", {
4074 value: oAttributes.value
4081 * @description HTML element reference or string specifying the id
4082 * attribute of the HTML element that the button group's markup
4083 * should be rendered into.
4084 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4085 * level-one-html.html#ID-58190037">HTMLElement</a>|String
4088 this.setAttributeConfig("container", {
4090 value: oAttributes.container,
4097 * @config checkedButton
4098 * @description Reference for the button in the button group that
4100 * @type {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4103 this.setAttributeConfig("checkedButton", {
4114 * @description Adds the button to the button group.
4115 * @param {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4116 * p_oButton Object reference for the <a href="YAHOO.widget.Button.html">
4117 * YAHOO.widget.Button</a> instance to be added to the button group.
4118 * @param {String} p_oButton String specifying the id attribute of the
4119 * <code><input></code> or <code><span></code> element
4120 * to be used to create the button to be added to the button group.
4121 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4122 * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="
4123 * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#
4124 * ID-33759296">HTMLElement</a>} p_oButton Object reference for the
4125 * <code><input></code> or <code><span></code> element
4126 * to be used to create the button to be added to the button group.
4127 * @param {Object} p_oButton Object literal specifying a set of
4128 * <a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>
4129 * configuration attributes used to configure the button to be added to
4131 * @return {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4133 addButton: function (p_oButton) {
4143 if (p_oButton instanceof Button &&
4144 p_oButton.get("type") == "radio") {
4146 oButton = p_oButton;
4149 else if (!Lang.isString(p_oButton) && !p_oButton.nodeName) {
4151 p_oButton.type = "radio";
4153 oButton = new Button(p_oButton);
4158 oButton = new Button(p_oButton, { type: "radio" });
4165 nIndex = this._buttons.length;
4166 sButtonName = oButton.get("name");
4167 sGroupName = this.get("name");
4169 oButton.index = nIndex;
4171 this._buttons[nIndex] = oButton;
4172 m_oButtons[oButton.get("id")] = oButton;
4175 if (sButtonName != sGroupName) {
4177 oButton.set("name", sGroupName);
4182 if (this.get("disabled")) {
4184 oButton.set("disabled", true);
4189 if (oButton.get("checked")) {
4191 this.set("checkedButton", oButton);
4196 oButtonElement = oButton.get("element");
4197 oGroupElement = this.get("element");
4199 if (oButtonElement.parentNode != oGroupElement) {
4201 oGroupElement.appendChild(oButtonElement);
4206 oButton.on("checkedChange",
4207 this._onButtonCheckedChange, oButton, this);
4218 * @method addButtons
4219 * @description Adds the array of buttons to the button group.
4220 * @param {Array} p_aButtons Array of <a href="YAHOO.widget.Button.html">
4221 * YAHOO.widget.Button</a> instances to be added
4222 * to the button group.
4223 * @param {Array} p_aButtons Array of strings specifying the id
4224 * attribute of the <code><input></code> or <code><span>
4225 * </code> elements to be used to create the buttons to be added to the
4227 * @param {Array} p_aButtons Array of object references for the
4228 * <code><input></code> or <code><span></code> elements
4229 * to be used to create the buttons to be added to the button group.
4230 * @param {Array} p_aButtons Array of object literals, each containing
4231 * a set of <a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>
4232 * configuration attributes used to configure each button to be added
4233 * to the button group.
4236 addButtons: function (p_aButtons) {
4243 if (Lang.isArray(p_aButtons)) {
4245 nButtons = p_aButtons.length;
4250 for (i = 0; i < nButtons; i++) {
4252 oButton = this.addButton(p_aButtons[i]);
4256 aButtons[aButtons.length] = oButton;
4262 if (aButtons.length > 0) {
4277 * @method removeButton
4278 * @description Removes the button at the specified index from the
4280 * @param {Number} p_nIndex Number specifying the index of the button
4281 * to be removed from the button group.
4283 removeButton: function (p_nIndex) {
4285 var oButton = this.getButton(p_nIndex),
4292 this._buttons.splice(p_nIndex, 1);
4293 delete m_oButtons[oButton.get("id")];
4295 oButton.removeListener("checkedChange",
4296 this._onButtonCheckedChange);
4301 nButtons = this._buttons.length;
4305 i = this._buttons.length - 1;
4309 this._buttons[i].index = i;
4324 * @description Returns the button at the specified index.
4325 * @param {Number} p_nIndex The index of the button to retrieve from the
4327 * @return {<a href="YAHOO.widget.Button.html">YAHOO.widget.Button</a>}
4329 getButton: function (p_nIndex) {
4331 if (Lang.isNumber(p_nIndex)) {
4333 return this._buttons[p_nIndex];
4341 * @method getButtons
4342 * @description Returns an array of the buttons in the button group.
4345 getButtons: function () {
4347 return this._buttons;
4354 * @description Returns the number of buttons in the button group.
4357 getCount: function () {
4359 return this._buttons.length;
4366 * @description Sets focus to the button at the specified index.
4367 * @param {Number} p_nIndex Number indicating the index of the button
4370 focus: function (p_nIndex) {
4376 if (Lang.isNumber(p_nIndex)) {
4378 oButton = this._buttons[p_nIndex];
4389 nButtons = this.getCount();
4391 for (i = 0; i < nButtons; i++) {
4393 oButton = this._buttons[i];
4395 if (!oButton.get("disabled")) {
4411 * @description Checks the button at the specified index.
4412 * @param {Number} p_nIndex Number indicating the index of the button
4415 check: function (p_nIndex) {
4417 var oButton = this.getButton(p_nIndex);
4421 oButton.set("checked", true);
4430 * @description Removes the button group's element from its parent
4431 * element and removes all event handlers.
4433 destroy: function () {
4436 var nButtons = this._buttons.length,
4437 oElement = this.get("element"),
4438 oParentNode = oElement.parentNode,
4443 i = this._buttons.length - 1;
4447 this._buttons[i].destroy();
4455 Event.purgeElement(oElement);
4458 oParentNode.removeChild(oElement);
4465 * @description Returns a string representing the button group.
4468 toString: function () {
4470 return ("ButtonGroup " + this.get("id"));
4477 YAHOO.register("button", YAHOO.widget.Button, {version: "2.3.0", build: "442"});