[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/2in3/2.9.0/build/yui2-button/ -> yui2-button-debug.js (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1