X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..25ef3491bd9ae007ff1fc2b0d7943e6eaaccf775:/docs/source/MultiCombo.html diff --git a/docs/source/MultiCombo.html b/docs/source/MultiCombo.html deleted file mode 100644 index f9b413f4..00000000 --- a/docs/source/MultiCombo.html +++ /dev/null @@ -1,922 +0,0 @@ - - - The source code - - - - -
Ext.ns('Ext.ux');
-
-
/** - * Ext.ux.MultiCombo - */ -Ext.ux.MultiCombo = Ext.extend(Ext.form.ComboBox, { - -
/** - * @cfg {String} overClass [x-grid3-row-over] - */ - overClass : 'x-grid3-row-over', -
/** - * @cfg {Boolean} enableKeyEvents for typeAhead - */ - enableKeyEvents: true, -
/** - * @cfg {String} selectedClass [x-grid3-row-selected] - */ - selectedClass: 'x-grid3-row-selected', -
/** - * @cfg {String} highlightClass The css class applied to rows which are hovered with mouse - * selected via key-nav, or highlighted when a text-query matches a single item. - */ - highlightClass: 'x-grid3-row-over', -
/** - * @cfg {Number} autoSelectKey [44] COMMA Sets the key used to auto-select an auto-suggest - * highlighted query. When pressed, the highlighted text-item will be selected as if the user - * selected the row with a mouse click. - */ - autoSelectKey : 44, -
/** - * @cfg {String} allSelectedText Text to display when all items are selected - */ - allSelectedText : 'All selected', -
/** - * @cfg {Number} maxDisplayRows The maximum number of rows to show before applying vscroll - */ - maxDisplayRows: null, - - mode: 'local', - triggerAction: 'all', - typeAhead: true, - - // private - highlightIndex : null, - highlightIndexPrev : null, - - query : null, - - -
/** - * @cfg {Array} value CheckboxCombo expresses its value as an array. - */ - value: [], - -
/** - * @cfg {Integer} minChars [0] - */ - minChars: 0, - - initComponent : function() { - var cls = 'x-combo-list'; - - // when blurring out of field, ensure that rawValue contains ONLY items contained in Store. - this.on('blur', this.validateSelections.createDelegate(this)); - - // create an auto-select key handler, like *nix-based console [tab] key behaviour - this.on('keypress', function(field, ev) { - if (ev.getKey() == this.autoSelectKey) { // COMMA - this.onAutoSelect(); - } - },this); - - this.addEvents( -
/** - * @event initview Fires when Combo#initView is called. - * gives plugins a chance to interact with DataView - * @author Chris Scott - * @param {Combo} this - * @param {DataView} dv - */ - 'initview', - 'clearall' - ); - - // when list expands, constrain the height with @cfg maxDisplayRows - if (this.maxDisplayRows) { - this.on('expand', function(){ - var cnt = this.store.getCount(); - if (cnt > this.maxDisplayRows) { - var children = this.view.getNodes(); - var h = 0; - for (var n = 0; n < this.maxDisplayRows; n++) { - h += Ext.fly(children[n]).getHeight(); - } - this.maxHeight = h; - } - }, this, { - single: true - }); - } - - this.on('beforequery', this.onQuery, this); - - // Enforce that plugins is an Array. - if (typeof(this.plugins) == 'undefined'){ - this.plugins = []; - } - else if (!Ext.isArray(this.plugins)) { - this.plugins = [this.plugins]; - } - - var tmp = this.value; // for case where transform is set. - Ext.ux.MultiCombo.superclass.initComponent.call(this); - if (this.transform) { - if (typeof(tmp) == 'undefined') { - tmp = []; - } - this.setValue(tmp); - } - }, - - // private - onViewClick : function(dv, index, node, ev){ - var rec = this.store.getAt(index); - this.onSelect(rec, index); - this.el.focus(); - /* - if(doFocus !== false){ - this.el.focus(); - } - */ - }, - - // onTriggerClick, overrides Ext.form.ComboBox#onTriggerClick - onTriggerClick: function() { - if (this.highlightIndex != -1) { - this.clearHighlight(); - } - this.highlightIndex = -1; - - if(this.disabled){ - return; - } - if(this.isExpanded()){ - this.collapse(); - this.el.focus(); - }else { - this.onFocus({}); - if(this.triggerAction == 'all') { - this.doQuery(this.getRawValue(), true); - var vlen = this.getValue().length, slen = this.view.getSelectedRecords().length; - if (vlen != slen || vlen == 0) { - this.selectByValue(this.value, true); - } - } else { - this.expand(); - this.doQuery(this.getRawValue()); - } - - this.highlightIndex = -1 - this.highlightIndexPrev = null; - this.selectNext(); - this.scrollIntoView(); - this.el.focus(); - } - }, - - // onQuery, beforequery listener, @return false - onQuery : function(qe) { - q = qe.query; - forceAll = qe.forceAll; - if(forceAll === true || (q.length >= this.minChars)){ - if(this.lastQuery !== q){ - if (typeof(this.lastQuery) != 'undefined') { - if (q.match(new RegExp('^'+this.allSelectedText))) { - this.query = this.store.data; - } - else if (this.lastQuery.length > q.length) { - var items = q.replace(/\s+/g, '').split(','); - if (items[items.length-1].length == 0) { - items.pop(); - } - this.query = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp('^'+items.join('$|^')+'$', "i"), false, false)); - } - else { - this.query = null; - } - } - this.lastQuery = q; - if(this.mode == 'local'){ - var raw = this.getRawValue(); - if (raw == this.allSelectedText) { - - } - var items = raw.replace(/\s+/g, '').split(','); - var last = items.pop(); - this.matches = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp('^'+last, "i"), false, false)).filterBy(this.createTypeAheadFilterFn(items)); - if (this.matches.getCount() == 0) { - this.clearHighlight(); - } - if (q.length == 0) { - this.view.clearSelections(); - this.updateValue([]); - } - - this.onLoad(); - } else { - this.store.baseParams[this.queryParam] = q; - this.store.load({ - params: this.getParams(q) - }); - this.expand(); - } - }else{ - this.selectedIndex = -1; - this.onLoad(); - } - } - - return false; - }, - - // onLoad, overrides Ext.form.ComboBox#onLoad - onLoad : function(){ - - if(!this.hasFocus){ - return; - } - if(this.store.getCount() > 0){ - if (!this.isExpanded()) { - this.expand(); - this.restrictHeight(); - } - if(this.lastQuery == this.allQuery){ - if(this.editable){ - this.el.dom.select(); - } - }else{ - if (this.query != null) { - var values = [], indexes = []; - this.query.each(function(r){ - values.push(r.data[this.valueField]); - indexes.push(this.store.indexOf(r)); - }, this); - this.view.clearSelections(); - this.updateValue(values, this.getRawValue()); - this.view.select(indexes); - } - if (this.matches != null) { - if (this.matches.getCount() == 1) { - this.highlight(this.store.indexOf(this.matches.first())); - this.scrollIntoView(); - } - } - else { - // @HACK: If store was configured with a proxy, set its mode to local now that its populated with data. - // Re-execute the query now. - this.mode = 'local'; - this.lastQuery = undefined; - this.doQuery(this.getRawValue(), true); - } - if(this.typeAhead && this.lastKey != Ext.EventObject.DOWN && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){ - this.taTask.delay(this.typeAheadDelay); - } - } - }else{ - this.onEmptyResults(); - } - }, - - onSelect : function(record, index) { - if (index == -1) { - throw new Error('MultiCombo#onSelect did not receive a valid index'); - } - - // select only when user clicks [apply] button - if (this.selectOnApply == true) { - return; - } - - if (this.fireEvent('beforeselect', this, record, index) !== false) { - var text = []; - var value = []; - var rs = this.view.getSelectedRecords(); - for (var n = 0, len = rs.length; n < len; n++) { - text.push(rs[n].data[this.displayField]); - value.push(rs[n].data[this.valueField]); - } - this.updateValue(value, (value.length != this.store.getCount()) ? text.join(', ') : this.allSelectedText); - var node = this.view.getNode(index); - this.innerList.scrollChildIntoView(node, false); - this.fireEvent('select', this, record, index); - } - }, - - // private - onViewOver : function(ev, node){ - var t = ev.getTarget(this.view.itemSelector); - if (t == null) { - return; - } - this.highlightIndex = this.store.indexOf(this.view.getRecord(t)); - this.clearHighlight(); - this.highlight(this.highlightIndex); - if(this.inKeyMode){ // prevent key nav and mouse over conflicts - return;null - } - return; - }, - - // private - onTypeAhead : function(){ - if(this.store.getCount() > 0){ - this.inKeyMode = false; - var raw = this.getRawValue(); - var pos = this.getCaretPosition(raw); - var items = []; - var query = ''; - if (pos !== false && pos < raw.length) { - items = raw.substr(0, pos).replace(/\s+/g, '').split(','); - query = items.pop(); - } else { - items = raw.replace(/\s+/g, '').split(','); - query = items.pop(); - } - var rs = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp(query, "i"), false, false)).filterBy(this.createTypeAheadFilterFn(items)); - - if (rs.getCount() == 1) { - var r = rs.first(); - var rindex = this.store.indexOf(r) - if (!this.view.isSelected(rindex)) { - this.typeAheadSelected = true; - var selStart = raw.length; - var len = items.join(',').length; - var selEnd = null; - var newValue = r.data[this.displayField]; - if (pos !== false && pos < raw.length) { - var insertIdx = items.length; - var selStart = pos; - items = raw.replace(/\s+/g, '').split(','); - items.splice(insertIdx, 1, newValue); - selEnd = items.slice(0, insertIdx+1).join(', ').length; - this.highlight(rindex); - this.scrollIntoView(); - - } - else { - items.push(newValue); - } - var len = items.join(',').length; - if(selStart != len){ - var lastWord = raw.split(',').pop(); - if (items.length >1 && lastWord.match(/^\s+/) == null) { - selStart++; - } - this.setRawValue(items.join(', ')); - this.selectText(selStart, (selEnd!=null) ? selEnd : this.getRawValue().length); - } - } - } - } - }, - - apply : function() { - var selected = this.view.getSelectedRecords(); - var value = []; - for (var n=0,len=selected.length;n -1 && !this.view.isSelected(idx)) { - var rec = this.store.getAt(idx); - this.select(idx); - } - }, - // filters-out already-selected items from type-ahead queries. - // e.g.: if store contains: "betty, barney, bart" and betty is already selected, - // when user types "b", only "bart" and "barney" should be returned as possible matches, - // since betty is *already* selected - createTypeAheadFilterFn : function(items) { - var key = this.displayField; - return function(rec) { - var re = new RegExp(rec.data[key], "i"); - var add = true; - for (var n=0,len=items.length;n/** - * setValue - * Accepts a comma-separated list of ids or an array. if given a string, will conver to Array. - * @param {Array, String} v - */ - setValue : function(v) { - var text = []; - var value = []; - - if (typeof(v) == 'string') { // <-- "1,2,3" - value = v.match(/\d+/g); // <-- strip multiple spaces and split on "," - if(value){ - for (var n=0,len=value.length;n/** - * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire. - * The store must be loaded and the list expanded for this function to work, otherwise use setValue. - * @param {Number} index The zero-based index of the list item to select - * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the - * selected item if it is not currently in view (defaults to true) - */ - select : function(index, scrollIntoView){ - if (!typeof(index) == 'number') { - throw new Error('MultiCombo#select expected @param {Number} index but got: ' + typeof(index)); - } - this.view.isSelected(index) ? this.view.deselect(index, true) : this.view.select(index, true); - this.onSelect(this.store.getAt(index), index); - - this.matches = null; - if(scrollIntoView !== false){ - var el = this.view.getNode(index); - if(el){ - this.innerList.scrollChildIntoView(el, false); - } - } - - }, - - getLastValue : function() { - return Ext.util.Format.trim(this.getRawValue().split(',').pop()); - }, - -
/** - * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire. - * The store must be loaded and the list expanded for this function to work, otherwise use setValue. - * @param {String} value The data value of the item to select - * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the - * selected item if it is not currently in view (defaults to true) - * @return {Boolean} True if the value matched an item in the list, else false - */ - selectByValue : function(v, scrollIntoView){ - if (v.length) { - var indexes = []; - var rs = this.store.data.filterBy(this.store.createFilterFn(this.valueField, new RegExp(v.join('|'), "i"))).each(function(r){ - indexes.push(this.store.indexOf(r)); - }, this); - if (indexes.length) { - this.view.select(indexes); - return true; - } - } - else { - this.view.clearSelections(); - this.setRawValue(''); - return false; - } - }, - - // private - initEvents : function(){ - Ext.form.ComboBox.superclass.initEvents.call(this); - this.keyNav = new Ext.KeyNav(this.el, { - "up" : function(e){ - this.lastKey = Ext.EventObject.UP; - this.inKeyMode = true; - this.selectPrev(); - this.scrollIntoView(); - }, - - "down" : function(e){ - this.inKeyMode = true; - if(!this.isExpanded()){ - this.lastKey = Ext.EventObject.DOWN; - this.onTriggerClick(); - }else{ - this.selectNext(); - this.scrollIntoView(); - } - - }, - - "enter" : function(e){ - var idx = this.highlightIndex; - if (this.inKeyMode === true) { - if (this.plugins.length && (idx <= -1)) { - if (this.plugins[idx + 1]) { - this.plugins[idx + 1].onEnter(this); - } - } - else - if (this.plugins.length && this.highlightIndex == 0 && this.highlightIndexPrev == -1) { - if (this.plugins[idx]) { - this.plugins[idx].onEnter(this); - } - } - else { - var idx = this.getHighlightedIndex() || 0; - if (this.highlightIndex != null && idx != null) { - this.select(idx, true); - //this.delayedCheck = true; - //this.unsetDelayCheck.defer(10, this); - - } - } - } - else { - var v = this.getLastValue(); - var raw = this.getRawValue(); - -
/** this block should be moved to method getCurrentWord - * - */ - var pos = this.getCaretPosition(raw); - var word = ''; - if (pos !== false && pos < raw.length) { - word = Ext.util.Format.trim(raw.substr(0, pos).split(',').pop()); - } else { - word = Ext.util.Format.trim(raw.split(',').pop()); - } -
/*******************************************************/ - - var idx = this.store.find(this.displayField, word); - if (idx != -1) { - var rec = this.store.getAt(idx); - this.select(idx, true); - } - raw = this.getRawValue(); - this.selectText(raw.length, raw.length); - this.collapse(); - } - }, - - "esc" : function(e){ - this.collapse(); - }, - - "tab" : function(e){ - if (this.matches != null && this.matches.getCount() == 1) { - var idx = this.store.indexOf(this.matches.first()); - if (!this.view.isSelected(idx)) { - this.select(this.store.indexOf(this.matches.first()), true); - } - } - else if (this.value.length == 0 && this.getRawValue().length > 0) { - this.setRawValue(''); - } - this.collapse(); - return true; - }, - - scope : this, - - doRelay : function(foo, bar, hname){ - if(hname == 'down' || this.scope.isExpanded()){ - return Ext.KeyNav.prototype.doRelay.apply(this, arguments); - } - return true; - }, - - forceKeyDown : true - }); - this.queryDelay = Math.max(this.queryDelay || 10, - this.mode == 'local' ? 10 : 250); - this.dqTask = new Ext.util.DelayedTask(this.initQuery, this); - if(this.typeAhead){ - this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this); - } - if(this.editable !== false){ - this.el.on("keyup", this.onKeyUp, this); - } - if(this.forceSelection){ - this.on('blur', this.doForce, this); - } - }, - - // private, blur-handler to ensure that rawValue contains only values from selections, in the same order as selected - validateSelections : function(field) { - var v = this.getValue(); - var text = []; - for (var i=0,len=v.length;i=0) { - text.push(this.store.getAt(idx).data[this.displayField]); - } - } - this.setRawValue(text.join(', ')); - }, - - scrollIntoView : function() { - var el = this.getHighlightedNode(); - if (el) { - this.innerList.scrollChildIntoView(el); - } - }, - - // private - selectNext : function(){ - this.clearHighlight(); - if (this.highlightIndex == null) { - this.highlightIndex = -1; - } - if (this.highlightIndex <= -1 && this.highlightIndexPrev != -1) { - if (this.plugins.length > 0) { - var idx = Math.abs(this.highlightIndex)-1; - if (this.plugins.length >= Math.abs(this.highlightIndex)) { - this.plugins[idx].selectNext(this); - this.highlightIndexPrev = this.highlightIndex; - this.highlightIndex++; - return false; - } - } - } - if (this.highlightIndexPrev == -1 && this.highlightIndex == 0) { - this.highlightIndex = -1; - } - var ct = this.store.getCount(); - if(ct > 0){ - if (this.highlightIndex == -1 || this.highlightIndex+1 < ct) { - if (this.highlightIndex == -1) { - this.highlightIndexPrev = 0; - } - else { - this.highlightIndexPrev = this.highlightIndex -1; - } - this.highlight(++this.highlightIndex); - - } - else { - this.highlight(ct-1); - } - } - }, - - // private - selectPrev : function(){ - this.clearHighlight(); - if (this.highlightIndex <= 0) { - var idx = Math.abs(this.highlightIndex); - if (this.plugins.length >= idx+1 && this.highlightIndexPrev >= 0) { - this.clearHighlight(); - this.plugins[idx].selectPrev(this); - this.highlightIndexPrev = this.highlightIndex; - this.highlightIndex--; - if (this.highlightIndex == -1) { - this.highlightIndexPrev = -1; - } - return false; - } - else { - this.highlightIndex = -1; - this.highlightIndexPrev = -1; - this.collapse(); - return; - } - } - - this.highlightIndexPrev = this.highlightIndex; - var ct = this.store.getCount(); - if(ct > 0){ - if (this.highlighIndex == -1) { - this.highlightIndex = 0; - } - else if (this.highlightIndex != 0) { - this.highlightIndex--; - } - else if (this.highlightIndex == 0) { - this.collapse(); - } - this.highlight(this.highlightIndex); - } - }, - - collapse : function() { - if (this.isExpanded()) { - this.highlightIndex = null; - this.highlightIndexPrev = null; - } - Ext.ux.MultiCombo.superclass.collapse.call(this); - }, - - highlight : function(index) { - this.view.el.select('.'+this.highlightClass).removeClass(this.highlightClass); - var node = Ext.fly(this.view.getNode(index)); - if (node) { - node.addClass(this.highlightClass); - } - }, - - getHighlightedIndex : function() { - var node = this.view.el.child('.' + this.highlightClass, true); - return (node) ? this.store.indexOf(this.view.getRecord(node)) : this.highlightIndex; - }, - getHighlightedNode : function() { - return this.view.el.child('.'+this.highlightClass, true); - }, - - clearHighlight : function() { - if (typeof(this.view) != 'object') { return false; } - var el = this.view.el.select('.'+this.highlightClass); - if (el) { - el.removeClass(this.highlightClass); - } - }, - - // private - initList : function(){ - if(!this.list){ - var cls = 'x-combo-list'; - - this.list = new Ext.Layer({ - shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false - }); - - var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth); - this.list.setWidth(lw); - this.list.swallowEvent('mousewheel'); - this.assetHeight = 0; - if(this.syncFont !== false){ - this.list.setStyle('font-size', this.el.getStyle('font-size')); - } - if(this.title){ - this.header = this.list.createChild({cls:cls+'-hd', html: this.title}); - this.assetHeight += this.header.getHeight(); - } - - this.innerList = this.list.createChild({cls:cls+'-inner'}); - this.innerList.on('mouseover', this.onViewOver, this); - this.innerList.on('mousemove', this.onViewMove, this); - this.innerList.setWidth(lw - this.list.getFrameWidth('lr')); - - if(this.pageSize){ - this.footer = this.list.createChild({cls:cls+'-ft'}); - this.pageTb = new Ext.PagingToolbar({ - store:this.store, - pageSize: this.pageSize, - renderTo:this.footer - }); - this.assetHeight += this.footer.getHeight(); - } - - if(!this.tpl){ -
/** - * @cfg {String/Ext.XTemplate} tpl The template string, or {@link Ext.XTemplate} - * instance to use to display each item in the dropdown list. Use - * this to create custom UI layouts for items in the list. - *

- * If you wish to preserve the default visual look of list items, add the CSS - * class name

x-combo-list-item
to the template's container element. - *

- * The template must contain one or more substitution parameters using field - * names from the Combo's {@link #store Store}. An example of a custom template - * would be adding an

ext:qtip
attribute which might display other fields - * from the Store. - *

- * The dropdown list is displayed in a DataView. See {@link Ext.DataView} for details. - */ - this.tpl = '

{' + this.displayField + '}
'; -
/** - * @cfg {String} itemSelector - * This setting is required if a custom XTemplate has been specified in {@link #tpl} - * which assigns a class other than
'x-combo-list-item'
to dropdown list items
. - * A simple CSS selector (e.g. div.some-class or span:first-child) that will be - * used to determine what nodes the DataView which handles the dropdown display will - * be working with. - */ - } - -
/** - * The {@link Ext.DataView DataView} used to display the ComboBox's options. - * @type Ext.DataView - */ - this.view = new Ext.DataView({ - applyTo: this.innerList, - tpl: this.tpl, - simpleSelect: true, - multiSelect: true, - overClass: this.overClass, - selectedClass: this.selectedClass, - itemSelector: this.itemSelector || '.' + cls + '-item' - }); - this.view.on('click', this.onViewClick, this); - this.fireEvent('initview', this, this.view); - this.bindStore(this.store, true); - - if(this.resizable){ - this.resizer = new Ext.Resizable(this.list, { - pinned:true, handles:'se' - }); - this.resizer.on('resize', function(r, w, h){ - this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight; - this.listWidth = w; - this.innerList.setWidth(w - this.list.getFrameWidth('lr')); - this.restrictHeight(); - }, this); - this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px'); - } - } - } -}); - - -Ext.reg('multicombo', Ext.ux.MultiCombo);
- - \ No newline at end of file