X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/examples/image-organizer/imgorg/MultiCombo.js?ds=sidebyside diff --git a/examples/image-organizer/imgorg/MultiCombo.js b/examples/image-organizer/imgorg/MultiCombo.js deleted file mode 100644 index 153faae6..00000000 --- a/examples/image-organizer/imgorg/MultiCombo.js +++ /dev/null @@ -1,919 +0,0 @@ -/*! - * Ext JS Library 3.3.1 - * Copyright(c) 2006-2010 Sencha Inc. - * licensing@sencha.com - * http://www.sencha.com/license - */ -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 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