自动完成源码

if (!pf.Autocompleter) {
	pf.Autocompleter = Class.create(Autocompleter.Local, {
		/**
		 * @param element 展示的控件
		 * @param update  具体展示内容的div
		 * @param comple  具体隐藏值的控件
		 * @param options 控件的配置参数
		 */
		baseInitialize : function(element, update, comple, options) {
			element = $(element);
			this.element = element;
			this.update = $(update);
			this.comple = $(comple);
			this.lastValue = '';
			this.hasFocus = false;
			this.changed = false;
			this.active = false;
			this.lastCompleValue = '';
			this.lastElementValue = '';
			this.index = 0;
			this.entryCount = 0;
			this.oldElementValue = this.element.value;
			if (this.setOptions)
				this.setOptions(options);
			else
				this.options = options || {};

			this.options.paramName = this.options.paramName
					|| this.element.name;
			this.options.tokens = this.options.tokens || [];
			this.options.frequency = this.options.frequency || 0.4;
			this.options.minChars = this.options.minChars || 1;
			this.options.onShow = this.options.onShow
					|| function(element, update) {
						if (!update.style.position
								|| update.style.position == 'absolute') {
							update.style.position = 'absolute';
							Position.clone(element, update, {
										setHeight : false,
										offsetTop : element.offsetHeight
									});
						}
						Effect.Appear(update, {
									duration : 0.15
								});
					};
			this.options.onHide = this.options.onHide
					|| function(element, update) {
						new Effect.Fade(update, {
									duration : 0.15
								})
					};

			if (typeof(this.options.tokens) == 'string')
				this.options.tokens = new Array(this.options.tokens);
			// Force carriage returns as token delimiters anyway
			if (!this.options.tokens.include('\n'))
				this.options.tokens.push('\n');

			this.observer = null;

			this.element.setAttribute('autocomplete', 'off');

			Element.hide(this.update);

			Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
			Event.observe(this.element, 'keydown', this.onKeyPress	.bindAsEventListener(this));
		},
		
		/**
		 * 对外的构造函数
		 * @param element 展示的控件
		 * @param update  具体展示内容的div
		 * @param comple  具体隐藏值的控件
		 * @param array   具体的数组/json对象
		 * @param options 控件的配置参数
		 */
		initialize : function(element, update, comple, array, options) {
			this.baseInitialize(element, update, comple, options);
			this.options.array = array;
		},
		
		onKeyPress : function(event) {

			if (event.keyCode == 8 || event.keyCode == 46) {//可能要增加支持delete删除(event.keyCode == 46)
				this.lastValue = '';
				if (this.comple.value.split(',').length == this.element.value
						.split(',').length)
					this.comple.value = this.comple.value.substr(0,
							this.comple.value.lastIndexOf(','));
				return;
			}
			if (this.active) {
				switch (event.keyCode) {
					case Event.KEY_TAB :
					case Event.KEY_RETURN :
						this.selectEntry();
						Event.stop(event);
					case Event.KEY_ESC :
						this.hide();
						this.active = false;
						Event.stop(event);
						return;
					case Event.KEY_LEFT :
					case Event.KEY_RIGHT :
						return;
					case Event.KEY_UP :
						this.markPrevious();
						this.render();
						Event.stop(event);
						return;
					case Event.KEY_DOWN :
						this.markNext();
						this.render();
						Event.stop(event);
						return;
				}
			} else if (event.keyCode == Event.KEY_TAB
					|| event.keyCode == Event.KEY_RETURN
					|| (Prototype.Browser.WebKit > 0 && event.keyCode == 0))
				return;
			this.changed = true;
			this.hasFocus = true;
			if (this.observer)
				clearTimeout(this.observer);
			this.observer = setTimeout(this.onObserverEvent.bind(this),
					this.options.frequency * 100);
		},
		
		/**
		 * 更改默认实现,bind改为_checkCompleteValue。
		 */
		onBlur : function(event) {
		    // needed to make click events working
			if(!this.options['ignoreCheck']) {//检查参数是否包含ignoreCheck
		    	setTimeout(this._checkCompleteValue.bind(this), 250);
			}
		    this.hasFocus = false;
		    this.active = false;

		},
		/**
		 * 隐藏update区域,然后检查完成的值是否为空,如果为空那么将展示的内容清空。
		 */
		_checkCompleteValue : function() {
			this.hide();
			if(!this.comple.value) {
				this.element.value = '';
			}
		},
		
		updateElement : function(selectedElement) {
			if (this.options.updateElement) {
				this.options.updateElement(selectedElement);
				return;
			}
			var value = '';
			if (this.options.select) {
				var nodes = $(selectedElement)
						.select('.' + this.options.select)
						|| [];
				if (nodes.length > 0)
					value = Element.collectTextNodes(nodes[0],
							this.options.select);
			} else
				value = Element.collectTextNodesIgnoreClass(selectedElement,
						'informal');
			var tempObj, finalObj;
			for (var a in this.options.array) {
				tempObj = this.options.array[a];
				if(tempObj.indexOf('=') > 0) {
					finalObj = tempObj.split('=')[1];
				} else {
					finalObj = tempObj;
				}
				if (this.ignoreSpaces(finalObj) == this.ignoreSpaces(value)) {
					if((this.element.value.lastIndexOf(',') == -1)) {
						this.comple.value = a;
					} else {
						this.comple.value = this.comple.value + ',' + a;
					}
					break;
				}
			}
			var bounds = this.getTokenBounds();
			if (bounds[0] != -1) {
				var newValue = this.element.value.substr(0, bounds[0]);
				var whitespace = this.element.value.substr(bounds[0])
						.match(/^\s+/);
				if (whitespace)
					newValue += whitespace[0];
				if (this.element.value.lastIndexOf(',') == -1) {
					this.element.value = newValue + value
							+ this.element.value.substr(bounds[1]);
				} else {
					this.element.value = newValue
							+ this.element.value.substr(0, this.element.value
											.lastIndexOf(',')
											+ 1) + value;
				}

			} else {
				this.element.value = value;
			}
			this.oldElementValue = this.element.value;
			this.element.focus();
			if (this.options.afterUpdateElement)
				this.options.afterUpdateElement(this.element, selectedElement);
		},
		
		setOptions : function(options) {
			this.options = Object.extend({
				updateLocation : '',
				choices : 10,
				partialSearch : true,
				partialChars : 1,
				ignoreCase : true,
				fullSearch : false,
				selector : function(instance) {
					var ret = []; // Beginning matches
					var partial = []; // Inside matches
					var entry = instance.getToken();
					var count = 0;
					//中间支持多个选择,以,分割。
					if (entry.lastIndexOf(',') != -1) {
						entry = entry.substr(entry.lastIndexOf(',') + 1,
								(entry.length - entry.lastIndexOf(',') - 1))
					}
					var count = 0;
					for (var a in instance.options.array) {
						var elem = instance.options.array[a];// value
						var elemH = a;// key
						var foundPos = instance.options.ignoreCase
								? elem.toLowerCase().indexOf(entry
										.toLowerCase())
								: elem.indexOf(entry);
						if (entry == '')
							foundPos = -1;
						var eqPos = -1; //等号的位置
						if(foundPos != -1) {
							count = count + 1;
							eqPos = elem.indexOf('=');
							ret.push("<li title ='"+elem+"'>");
							if(eqPos> 0) {
								if (foundPos >= eqPos) {
									if(foundPos > eqPos) {//如果找到的数据大于=开始的位置,那么仅加粗中间部分
										ret.push(elem.substring(eqPos + 1, foundPos));
									}
									ret.push("<strong>" + elem.substring(foundPos, foundPos + entry.length) + "</strong>");
									ret.push(elem.substring(foundPos+entry.length));
								} else {
									//如果查找到的是小于eqPos的部分,那么就不做任何加粗
									ret.push(elem.substring(eqPos + 1));
								}
							} else {
								if(foundPos > 0) {//仅加粗中间部分
									ret.push(elem.substring(0, foundPos));
								}
								ret.push("<strong>" + elem.substring(foundPos, foundPos + entry.length) + "</strong>");
								ret.push(elem.substring(foundPos+entry.length));
				            }
				            ret.push("</li>");
						}
						//如果找到的数据多余20个,那么跳出循环
						if(count > 10) {
							break;
						}
					}
					return "<ul>" + ret.join('') + "</ul>";
				}
			}, options || {});
		},
		ignoreSpaces : function(str){
			var resultStr = "";
            var temp=str.split(" ");//双引号之间是一个空格  
            for(i = 0; i < temp.length; i++){   
                resultStr +=temp[i];   
            }
            return resultStr;   
		}
	})
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值