/* * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com * * http://extjs.com/license */ /** * Makes a ComboBox more closely mimic an HTML SELECT. Supports clicking and * dragging through the list, with item selection occurring when the mouse * button is released. When used will automatically set {@link #editable} to * false and call {@link Ext.Element#unselectable} on inner elements. * Re-enabling editable after calling this will NOT work. * * @author Corey Gilmore http://extjs.com/forum/showthread.php?t=6392 * * @history 2007-07-08 jvs Slight mods for Ext 2.0 */ Ext.ux.SelectBox = function(config) { this.searchResetDelay = 1000; config = config || {}; config = Ext.apply(config || {}, { editable : false, forceSelection : true, rowHeight : false, lastSearchTerm : false, triggerAction : 'all', mode : 'local' }); Ext.ux.SelectBox.superclass.constructor.apply(this, arguments); this.lastSelectedIndex = this.selectedIndex || 0; }; Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, { initEvents : function() { Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments); // you need to use keypress to capture upper/lower case and // shift+key, but it doesn't work in IE this.el.on('keydown', this.keySearch, this, true); this.cshTask = new Ext.util.DelayedTask( this.clearSearchHistory, this); }, keySearch : function(e, target, options) { var raw = e.getKey(); var key = String.fromCharCode(raw); var startIndex = 0; if (!this.store.getCount()) { return; } switch (raw) { case Ext.EventObject.HOME : e.stopEvent(); this.selectFirst(); return; case Ext.EventObject.END : e.stopEvent(); this.selectLast(); return; case Ext.EventObject.PAGEDOWN : this.selectNextPage(); e.stopEvent(); return; case Ext.EventObject.PAGEUP : this.selectPrevPage(); e.stopEvent(); return; } // skip special keys other than the shift key if ((e.hasModifier() && !e.shiftKey) || e.isNavKeyPress() || e.isSpecialKey()) { return; } if (this.lastSearchTerm == key) { startIndex = this.lastSelectedIndex; } this.search(this.displayField, key, startIndex); this.cshTask.delay(this.searchResetDelay); }, onRender : function(ct, position) { this.store.on('load', this.calcRowsPerPage, this); Ext.ux.SelectBox.superclass.onRender.apply(this, arguments); if (this.mode == 'local') { this.calcRowsPerPage(); } }, onSelect : function(record, index, skipCollapse) { if (this.fireEvent('beforeselect', this, record, index) !== false) { this.setValue(record.data[this.valueField || this.displayField]); if (!skipCollapse) { this.collapse(); } this.lastSelectedIndex = index + 1; this.fireEvent('select', this, record, index); } }, render : function(ct) { Ext.ux.SelectBox.superclass.render.apply(this, arguments); if (Ext.isSafari) { this.el.swallowEvent('mousedown', true); } this.el.unselectable(); this.innerList.unselectable(); this.trigger.unselectable(); this.innerList.on('mouseup', function(e, target, options) { if (target.id && target.id == this.innerList.id) { return; } this.onViewClick(); }, this); this.innerList.on('mouseover', function(e, target, options) { if (target.id && target.id == this.innerList.id) { return; } this.lastSelectedIndex = this.view .getSelectedIndexes()[0] + 1; this.cshTask.delay(this.searchResetDelay); }, this); this.trigger.un('click', this.onTriggerClick, this); this.trigger.on('mousedown', function(e, target, options) { e.preventDefault(); this.onTriggerClick(); }, this); this.on('collapse', function(e, target, options) { Ext.getDoc().un('mouseup', this.collapseIf, this); }, this, true); this.on('expand', function(e, target, options) { Ext.getDoc().on('mouseup', this.collapseIf, this); }, this, true); }, clearSearchHistory : function() { this.lastSelectedIndex = 0; this.lastSearchTerm = false; }, selectFirst : function() { this.focusAndSelect(this.store.data.first()); }, selectLast : function() { this.focusAndSelect(this.store.data.last()); }, selectPrevPage : function() { if (!this.rowHeight) { return; } var index = Math.max(this.selectedIndex - this.rowsPerPage, 0); this.focusAndSelect(this.store.getAt(index)); }, selectNextPage : function() { if (!this.rowHeight) { return; } var index = Math.min(this.selectedIndex + this.rowsPerPage, this.store.getCount() - 1); this.focusAndSelect(this.store.getAt(index)); }, search : function(field, value, startIndex) { field = field || this.displayField; this.lastSearchTerm = value; var index = this.store.find.apply(this.store, arguments); if (index !== -1) { this.focusAndSelect(index); } }, focusAndSelect : function(record) { var index = typeof record === 'number' ? record : this.store .indexOf(record); this.select(index, this.isExpanded()); this.onSelect(this.store.getAt(record), index, this .isExpanded()); }, calcRowsPerPage : function() { if (this.store.getCount()) { this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight(); this.rowsPerPage = this.maxHeight / this.rowHeight; } else { this.rowHeight = false; } } });