/public/javascripts/dojo/release/dojo/dojox/form/DropDownSelect.js

http://enginey.googlecode.com/ · JavaScript · 234 lines · 145 code · 36 blank · 53 comment · 27 complexity · d577e80214e4b6b3f965368110880fec MD5 · raw file

  1. /*
  2. Copyright (c) 2004-2008, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.form.DropDownSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.form.DropDownSelect"] = true;
  8. dojo.provide("dojox.form.DropDownSelect");
  9. dojo.require("dojox.form._FormSelectWidget");
  10. dojo.require("dojox.form._HasDropDown");
  11. dojo.require("dijit.Menu");
  12. dojo.requireLocalization("dijit.form", "validate", null, "ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,ROOT,zh,zh-tw");
  13. dojo.declare("dojox.form.DropDownSelect", [dojox.form._FormSelectWidget, dojox.form._HasDropDown], {
  14. // summary:
  15. // This is a "Styleable" select box - it is basically a DropDownButton which
  16. // can take as its input a <select>.
  17. baseClass: "dojoxDropDownSelect",
  18. templateString:"<span class=\"dijit dijitReset dijitLeft dijitInline\"\r\n\tdojoAttachPoint=\"dropDownNode\"\r\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"\r\n\t><span class='dijitReset dijitRight dijitInline'\r\n\t\t><span class='dijitReset dijitInline dijitButtonNode'\r\n\t\t\t><table class=\"dojoxDropDownSelectTable\" dojoAttachPoint=\"tableNode\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tbody><tr\r\n\t\t\t\t><td class=\"dojoxDropDownSelectTableContent\" \r\n\t\t\t\t\t><span class=\"dijitReset dijitInline dijitButtonText\" dojoAttachPoint=\"containerNode,popupStateNode\" id=\"${id}_label\"></span\r\n\t\t\t\t></td><td class=\"dojoxDropDownSelectTableButton\" \r\n\t\t\t\t\t><button class=\"dijitReset dijitStretch dijitButtonContents\" type=\"button\" name=\"${name}\"\r\n\t\t\t\t\t\tdojoAttachPoint=\"focusNode,titleNode\" waiRole=\"button\" waiState=\"haspopup-true,labelledby-${id}_label\"\r\n\t\t\t\t\t\t><span class=\"dijitReset dijitInline dijitArrowButtonInner\">&thinsp;</span\r\n\t\t\t\t\t\t><span class=\"dijitReset dijitInline dijitArrowButtonChar\" waiRole=\"presentation\">&#9660;</span\r\n\t\t\t\t\t></button\r\n\t\t\t\t></td\r\n\t\t\t></tr></tbody></table\r\n\t\t></span\r\n\t></span\r\n></span>\r\n",
  19. // attributeMap: Object
  20. // Add in our style to be applied to the focus node
  21. attributeMap: dojo.mixin(dojo.clone(dojox.form._FormSelectWidget.prototype.attributeMap),{style:"tableNode"}),
  22. // required: Boolean
  23. // Can be true or false, default is false.
  24. required: false,
  25. // state: String
  26. // Shows current state (ie, validation result) of input (Normal, Warning, or Error)
  27. state: "",
  28. // tooltipPosition: String[]
  29. // See description of dijit.Tooltip.defaultPosition for details on this parameter.
  30. tooltipPosition: [],
  31. // emptyLabel: string
  32. // What to display in an "empty" dropdown
  33. emptyLabel: "",
  34. // _isLoaded: boolean
  35. // Whether or not we have been loaded
  36. _isLoaded: false,
  37. // _childrenLoaded: boolean
  38. // Whether or not our children have been loaded
  39. _childrenLoaded: false,
  40. _fillContent: function(){
  41. // summary:
  42. // Set the value to be the first, or the selected index
  43. this.inherited(arguments);
  44. if(this.options.length && !this.value){
  45. var si = this.srcNodeRef.selectedIndex;
  46. this.value = this.options[si != -1 ? si : 0].value;
  47. }
  48. // Create the dropDown widget
  49. this.dropDown = new dijit.Menu();
  50. dojo.addClass(this.dropDown.domNode, this.baseClass + "Menu");
  51. },
  52. _getMenuItemForOption: function(/* dojox.form.__SelectOption */ option){
  53. // summary:
  54. // For the given option, return the menu item that should be
  55. // used to display it. This can be overridden as needed
  56. if(!option.value){
  57. // We are a separator (no label set for it)
  58. return new dijit.MenuSeparator();
  59. }else{
  60. // Just a regular menu option
  61. var click = dojo.hitch(this, "_setValueAttr", option);
  62. return new dijit.MenuItem({
  63. option: option,
  64. label: option.label,
  65. onClick: click,
  66. disabled: option.disabled || false
  67. });
  68. }
  69. },
  70. _addOptionItem: function(/* dojox.form.__SelectOption */ option){
  71. // summary:
  72. // For the given option, add a option to our dropdown
  73. // If the option doesn't have a value, then a separator is added
  74. // in that place.
  75. this.dropDown.addChild(this._getMenuItemForOption(option));
  76. },
  77. _getChildren: function(){ return this.dropDown.getChildren(); },
  78. _loadChildren: function(){
  79. // summary:
  80. // Resets the menu and the length attribute of the button - and
  81. // ensures that the label is appropriately set.
  82. this.inherited(arguments);
  83. var len = this.options.length;
  84. this._isLoaded = false;
  85. this._childrenLoaded = true;
  86. // Set our length attribute and our value
  87. if(!this._iReadOnly){
  88. this.attr("readOnly", (len === 1));
  89. delete this._iReadOnly;
  90. }
  91. if(!this._iDisabled){
  92. this.attr("disabled", (len === 0));
  93. delete this._iDisabled;
  94. }
  95. this._setValueAttr(this.value);
  96. },
  97. _setDisplay: function(/*String*/ newDisplay){
  98. // summary: sets the display for the given value (or values)
  99. this.containerNode.innerHTML = '<span class=" ' + this.baseClass + 'Label">' +
  100. (newDisplay || this.emptyLabel || "&nbsp;") +
  101. '</span>';
  102. this._layoutHack();
  103. },
  104. validate: function(/*Boolean*/ isFocused){
  105. // summary:
  106. // Called by oninit, onblur, and onkeypress.
  107. // description:
  108. // Show missing or invalid messages if appropriate, and highlight textbox field.
  109. var isValid = this.isValid(isFocused);
  110. this.state = isValid ? "" : "Error";
  111. this._setStateClass();
  112. dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
  113. var message = isValid ? "" : this._missingMsg;
  114. if(this._message !== message){
  115. this._message = message;
  116. dijit.hideTooltip(this.domNode);
  117. if(message){
  118. dijit.showTooltip(message, this.domNode, this.tooltipPosition);
  119. }
  120. }
  121. return isValid;
  122. },
  123. isValid: function(/*Boolean*/ isFocused){
  124. // summary: Whether or not this is a valid value
  125. return (!this.required || !(/^\s*$/.test(this.value)));
  126. },
  127. reset: function(){
  128. // summary: Overridden so that the state will be cleared.
  129. this.inherited(arguments);
  130. dijit.hideTooltip(this.domNode);
  131. this.state = "";
  132. this._setStateClass();
  133. delete this._message;
  134. },
  135. postMixInProperties: function(){
  136. // summary: set the missing message
  137. this.inherited(arguments);
  138. this._missingMsg = dojo.i18n.getLocalization("dijit.form", "validate",
  139. this.lang).missingMessage;
  140. },
  141. postCreate: function(){
  142. this.inherited(arguments);
  143. if(dojo.attr(this.srcNodeRef, "disabled")){
  144. this.attr("disabled", true);
  145. }
  146. },
  147. startup: function(){
  148. if(this._started){ return; }
  149. // the child widget from srcNodeRef is the dropdown widget. Insert it in the page DOM,
  150. // make it invisible, and store a reference to pass to the popup code.
  151. if(!this.dropDown){
  152. var dropDownNode = dojo.query("[widgetId]", this.dropDownContainer)[0];
  153. this.dropDown = dijit.byNode(dropDownNode);
  154. delete this.dropDownContainer;
  155. }
  156. this.inherited(arguments);
  157. },
  158. _onMenuMouseup: function(e){
  159. // override this to actually "pretend" to do a click on our menu - it will
  160. // call onExecute - so it will close our popup for us. For non-menu
  161. // popups, it will not execute.
  162. var dropDown = this.dropDown, t = e.target;
  163. if(dropDown.onItemClick){
  164. var menuItem;
  165. while(t && !(menuItem = dijit.byNode(t))){
  166. t = t.parentNode;
  167. }
  168. if(menuItem && menuItem.onClick && menuItem.getParent){
  169. menuItem.getParent().onItemClick(menuItem, e);
  170. }
  171. }
  172. // TODO: how to handle non-menu popups?
  173. },
  174. isLoaded: function(){
  175. return this._isLoaded;
  176. },
  177. loadDropDown: function(/* Function */ loadCallback){
  178. // summary: populates the menu
  179. this._loadChildren();
  180. this._isLoaded = true;
  181. loadCallback();
  182. },
  183. _setReadOnlyAttr: function(value){
  184. this._iReadOnly = value;
  185. if(!value && this._childrenLoaded && this.options.length === 1){
  186. return;
  187. }
  188. this.readOnly = value;
  189. },
  190. _setDisabledAttr: function(value){
  191. this._iDisabled = value;
  192. if(!value && this._childrenLoaded && this.options.length === 0){
  193. return;
  194. }
  195. this.inherited(arguments);
  196. }
  197. });
  198. }