⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multicombo.js

📁 Ext JS是一个创建丰富互联网应用程序的跨浏览器的JavaScrip库。它包含:高效率
💻 JS
📖 第 1 页 / 共 2 页
字号:
/*
 * Ext JS Library 3.0 Pre-alpha
 * Copyright(c) 2006-2008, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * http://extjs.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<len;n++) {			value.push(selected[n].data[this.valueField]);		}		this.setValue(value);	},	getCaretPosition : function(raw) {		raw = raw || this.getRawValue();		if(document.selection) {	// <-- IE, ugh:  http://parentnode.org/javascript/working-with-the-cursor-position/        	var range = document.selection.createRange();			//Save the current value. We will need this value later to find out, where the text has been changed			var orig = obj.value.replace(/rn/g, "n");			// replace the text			range.text = text;			// Now get the new content and save it into a temporary variable			var actual = tmp = obj.value.replace(/rn/g, "n");			/* Find the first occurance, where the original differs			   from the actual content. This could be the startposition			   of our text selection, but it has not to be. Think of the			   selection "ab" and replacing it with "ac". The first			   difference would be the "c", while the start position			   is the "a"			*/			for(var diff = 0; diff < orig.length; diff++) {			    if(orig.charAt(diff) != actual.charAt(diff)) break;			}			/* To get the real start position, we iterate through			   the string searching for the whole replacement			   text - "abc", as long as the first difference is not			   reached. If you do not understand that logic - no			   blame to you, just copy & paste it ;)			*/			for(var index = 0, start = 0; tmp.match(text) && (tmp = tmp.replace(text, "")) && index <= diff; index = start + text.length) {			    start = actual.indexOf(text, index);			}	    } else if(this.el.dom.selectionStart) {	// <-- Go the Gecko way			return this.el.dom.selectionStart;	    } else {	        // Fallback for any other browser			return false;	    }	},	onAutoSelect : function() {		if (!this.isExpanded()) {			var vlen = this.getValue().length, slen = this.view.getSelectedRecords().length;			if (vlen != slen || vlen == 0) {				this.selectByValue(this.value, true);			}		}		var raw = this.getRawValue();		this.selectText(raw.length, raw.length);		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 && !this.view.isSelected(idx)) {			var rec = this.store.getAt(idx);			this.select(idx);		}	},	// filters-out already-selected items from type-ahead queries.	// eg: 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<len;n++) {				if (re.test(items[n])) {					add = false;					break;				}			}			return add;		}	},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -