SelectBox.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * Makes a ComboBox more closely mimic an HTML SELECT. Supports clicking and
  8. * dragging through the list, with item selection occurring when the mouse
  9. * button is released. When used will automatically set {@link #editable} to
  10. * false and call {@link Ext.Element#unselectable} on inner elements.
  11. * Re-enabling editable after calling this will NOT work.
  12. *
  13. * @author Corey Gilmore http://extjs.com/forum/showthread.php?t=6392
  14. *
  15. * @history 2007-07-08 jvs Slight mods for Ext 2.0
  16. */
  17. Ext.ux.SelectBox = function(config) {
  18. this.searchResetDelay = 1000;
  19. config = config || {};
  20. config = Ext.apply(config || {}, {
  21. editable : false,
  22. forceSelection : true,
  23. rowHeight : false,
  24. lastSearchTerm : false,
  25. triggerAction : 'all',
  26. mode : 'local'
  27. });
  28. Ext.ux.SelectBox.superclass.constructor.apply(this, arguments);
  29. this.lastSelectedIndex = this.selectedIndex || 0;
  30. };
  31. Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, {
  32. initEvents : function() {
  33. Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments);
  34. // you need to use keypress to capture upper/lower case and
  35. // shift+key, but it doesn't work in IE
  36. this.el.on('keydown', this.keySearch, this, true);
  37. this.cshTask = new Ext.util.DelayedTask(
  38. this.clearSearchHistory, this);
  39. },
  40. keySearch : function(e, target, options) {
  41. var raw = e.getKey();
  42. var key = String.fromCharCode(raw);
  43. var startIndex = 0;
  44. if (!this.store.getCount()) {
  45. return;
  46. }
  47. switch (raw) {
  48. case Ext.EventObject.HOME :
  49. e.stopEvent();
  50. this.selectFirst();
  51. return;
  52. case Ext.EventObject.END :
  53. e.stopEvent();
  54. this.selectLast();
  55. return;
  56. case Ext.EventObject.PAGEDOWN :
  57. this.selectNextPage();
  58. e.stopEvent();
  59. return;
  60. case Ext.EventObject.PAGEUP :
  61. this.selectPrevPage();
  62. e.stopEvent();
  63. return;
  64. }
  65. // skip special keys other than the shift key
  66. if ((e.hasModifier() && !e.shiftKey) || e.isNavKeyPress()
  67. || e.isSpecialKey()) {
  68. return;
  69. }
  70. if (this.lastSearchTerm == key) {
  71. startIndex = this.lastSelectedIndex;
  72. }
  73. this.search(this.displayField, key, startIndex);
  74. this.cshTask.delay(this.searchResetDelay);
  75. },
  76. onRender : function(ct, position) {
  77. this.store.on('load', this.calcRowsPerPage, this);
  78. Ext.ux.SelectBox.superclass.onRender.apply(this, arguments);
  79. if (this.mode == 'local') {
  80. this.calcRowsPerPage();
  81. }
  82. },
  83. onSelect : function(record, index, skipCollapse) {
  84. if (this.fireEvent('beforeselect', this, record, index) !== false) {
  85. this.setValue(record.data[this.valueField
  86. || this.displayField]);
  87. if (!skipCollapse) {
  88. this.collapse();
  89. }
  90. this.lastSelectedIndex = index + 1;
  91. this.fireEvent('select', this, record, index);
  92. }
  93. },
  94. render : function(ct) {
  95. Ext.ux.SelectBox.superclass.render.apply(this, arguments);
  96. if (Ext.isSafari) {
  97. this.el.swallowEvent('mousedown', true);
  98. }
  99. this.el.unselectable();
  100. this.innerList.unselectable();
  101. this.trigger.unselectable();
  102. this.innerList.on('mouseup', function(e, target, options) {
  103. if (target.id && target.id == this.innerList.id) {
  104. return;
  105. }
  106. this.onViewClick();
  107. }, this);
  108. this.innerList.on('mouseover', function(e, target, options) {
  109. if (target.id && target.id == this.innerList.id) {
  110. return;
  111. }
  112. this.lastSelectedIndex = this.view
  113. .getSelectedIndexes()[0]
  114. + 1;
  115. this.cshTask.delay(this.searchResetDelay);
  116. }, this);
  117. this.trigger.un('click', this.onTriggerClick, this);
  118. this.trigger.on('mousedown', function(e, target, options) {
  119. e.preventDefault();
  120. this.onTriggerClick();
  121. }, this);
  122. this.on('collapse', function(e, target, options) {
  123. Ext.getDoc().un('mouseup', this.collapseIf, this);
  124. }, this, true);
  125. this.on('expand', function(e, target, options) {
  126. Ext.getDoc().on('mouseup', this.collapseIf, this);
  127. }, this, true);
  128. },
  129. clearSearchHistory : function() {
  130. this.lastSelectedIndex = 0;
  131. this.lastSearchTerm = false;
  132. },
  133. selectFirst : function() {
  134. this.focusAndSelect(this.store.data.first());
  135. },
  136. selectLast : function() {
  137. this.focusAndSelect(this.store.data.last());
  138. },
  139. selectPrevPage : function() {
  140. if (!this.rowHeight) {
  141. return;
  142. }
  143. var index = Math.max(this.selectedIndex - this.rowsPerPage, 0);
  144. this.focusAndSelect(this.store.getAt(index));
  145. },
  146. selectNextPage : function() {
  147. if (!this.rowHeight) {
  148. return;
  149. }
  150. var index = Math.min(this.selectedIndex + this.rowsPerPage,
  151. this.store.getCount() - 1);
  152. this.focusAndSelect(this.store.getAt(index));
  153. },
  154. search : function(field, value, startIndex) {
  155. field = field || this.displayField;
  156. this.lastSearchTerm = value;
  157. var index = this.store.find.apply(this.store, arguments);
  158. if (index !== -1) {
  159. this.focusAndSelect(index);
  160. }
  161. },
  162. focusAndSelect : function(record) {
  163. var index = typeof record === 'number' ? record : this.store
  164. .indexOf(record);
  165. this.select(index, this.isExpanded());
  166. this.onSelect(this.store.getAt(record), index, this
  167. .isExpanded());
  168. },
  169. calcRowsPerPage : function() {
  170. if (this.store.getCount()) {
  171. this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight();
  172. this.rowsPerPage = this.maxHeight / this.rowHeight;
  173. } else {
  174. this.rowHeight = false;
  175. }
  176. }
  177. });