_ComboBoxMenuMixin.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. define("dijit/form/_ComboBoxMenuMixin", [
  2. "dojo/_base/array", // array.forEach
  3. "dojo/_base/declare", // declare
  4. "dojo/dom-attr", // domAttr.set
  5. "dojo/i18n", // i18n.getLocalization
  6. "dojo/_base/window", // win.doc.createTextNode
  7. "dojo/i18n!./nls/ComboBox"
  8. ], function(array, declare, domAttr, i18n, win){
  9. // module:
  10. // dijit/form/_ComboBoxMenuMixin
  11. // summary:
  12. // Focus-less menu for internal use in `dijit.form.ComboBox`
  13. return declare( "dijit.form._ComboBoxMenuMixin", null, {
  14. // summary:
  15. // Focus-less menu for internal use in `dijit.form.ComboBox`
  16. // tags:
  17. // private
  18. // _messages: Object
  19. // Holds "next" and "previous" text for paging buttons on drop down
  20. _messages: null,
  21. postMixInProperties: function(){
  22. this.inherited(arguments);
  23. this._messages = i18n.getLocalization("dijit.form", "ComboBox", this.lang);
  24. },
  25. buildRendering: function(){
  26. this.inherited(arguments);
  27. // fill in template with i18n messages
  28. this.previousButton.innerHTML = this._messages["previousMessage"];
  29. this.nextButton.innerHTML = this._messages["nextMessage"];
  30. },
  31. _setValueAttr: function(/*Object*/ value){
  32. this.value = value;
  33. this.onChange(value);
  34. },
  35. onClick: function(/*DomNode*/ node){
  36. if(node == this.previousButton){
  37. this._setSelectedAttr(null);
  38. this.onPage(-1);
  39. }else if(node == this.nextButton){
  40. this._setSelectedAttr(null);
  41. this.onPage(1);
  42. }else{
  43. this.onChange(node);
  44. }
  45. },
  46. // stubs
  47. onChange: function(/*Number*/ /*===== direction =====*/){
  48. // summary:
  49. // Notifies ComboBox/FilteringSelect that user selected an option.
  50. // tags:
  51. // callback
  52. },
  53. onPage: function(/*Number*/ /*===== direction =====*/){
  54. // summary:
  55. // Notifies ComboBox/FilteringSelect that user clicked to advance to next/previous page.
  56. // tags:
  57. // callback
  58. },
  59. onClose: function(){
  60. // summary:
  61. // Callback from dijit.popup code to this widget, notifying it that it closed
  62. // tags:
  63. // private
  64. this._setSelectedAttr(null);
  65. },
  66. _createOption: function(/*Object*/ item, labelFunc){
  67. // summary:
  68. // Creates an option to appear on the popup menu subclassed by
  69. // `dijit.form.FilteringSelect`.
  70. var menuitem = this._createMenuItem();
  71. var labelObject = labelFunc(item);
  72. if(labelObject.html){
  73. menuitem.innerHTML = labelObject.label;
  74. }else{
  75. menuitem.appendChild(
  76. win.doc.createTextNode(labelObject.label)
  77. );
  78. }
  79. // #3250: in blank options, assign a normal height
  80. if(menuitem.innerHTML == ""){
  81. menuitem.innerHTML = " "; //  
  82. }
  83. // update menuitem.dir if BidiSupport was required
  84. this.applyTextDir(menuitem, (menuitem.innerText || menuitem.textContent || ""));
  85. menuitem.item=item;
  86. return menuitem;
  87. },
  88. createOptions: function(results, options, labelFunc){
  89. // summary:
  90. // Fills in the items in the drop down list
  91. // results:
  92. // Array of items
  93. // options:
  94. // The options to the query function of the store
  95. //
  96. // labelFunc:
  97. // Function to produce a label in the drop down list from a dojo.data item
  98. this.items = results;
  99. // display "Previous . . ." button
  100. this.previousButton.style.display = (options.start == 0) ? "none" : "";
  101. domAttr.set(this.previousButton, "id", this.id + "_prev");
  102. // create options using _createOption function defined by parent
  103. // ComboBox (or FilteringSelect) class
  104. // #2309:
  105. // iterate over cache nondestructively
  106. array.forEach(results, function(item, i){
  107. var menuitem = this._createOption(item, labelFunc);
  108. menuitem.setAttribute("item", i); // index to this.items; use indirection to avoid mem leak
  109. domAttr.set(menuitem, "id", this.id + i);
  110. this.nextButton.parentNode.insertBefore(menuitem, this.nextButton);
  111. }, this);
  112. // display "Next . . ." button
  113. var displayMore = false;
  114. // Try to determine if we should show 'more'...
  115. if(results.total && !results.total.then && results.total != -1){
  116. if((options.start + options.count) < results.total){
  117. displayMore = true;
  118. }else if((options.start + options.count) > results.total && options.count == results.length){
  119. // Weird return from a data store, where a start + count > maxOptions
  120. // implies maxOptions isn't really valid and we have to go into faking it.
  121. // And more or less assume more if count == results.length
  122. displayMore = true;
  123. }
  124. }else if(options.count == results.length){
  125. //Don't know the size, so we do the best we can based off count alone.
  126. //So, if we have an exact match to count, assume more.
  127. displayMore = true;
  128. }
  129. this.nextButton.style.display = displayMore ? "" : "none";
  130. domAttr.set(this.nextButton,"id", this.id + "_next");
  131. },
  132. clearResultList: function(){
  133. // summary:
  134. // Clears the entries in the drop down list, but of course keeps the previous and next buttons.
  135. var container = this.containerNode;
  136. while(container.childNodes.length > 2){
  137. container.removeChild(container.childNodes[container.childNodes.length-2]);
  138. }
  139. this._setSelectedAttr(null);
  140. },
  141. highlightFirstOption: function(){
  142. // summary:
  143. // Highlight the first real item in the list (not Previous Choices).
  144. this.selectFirstNode();
  145. },
  146. highlightLastOption: function(){
  147. // summary:
  148. // Highlight the last real item in the list (not More Choices).
  149. this.selectLastNode();
  150. },
  151. selectFirstNode: function(){
  152. this.inherited(arguments);
  153. if(this.getHighlightedOption() == this.previousButton){
  154. this.selectNextNode();
  155. }
  156. },
  157. selectLastNode: function(){
  158. this.inherited(arguments);
  159. if(this.getHighlightedOption() == this.nextButton){
  160. this.selectPreviousNode();
  161. }
  162. },
  163. getHighlightedOption: function(){
  164. return this._getSelectedAttr();
  165. }
  166. });
  167. });