支持输入且自动完成的 select

最近在一个项目里面做了一个控件:该控件作为一个带输入的 select ,且支持根据动态输入的内容去后台查询,将结果放在 select 的下拉框里面。效果图如下:

支持输入且自动完成的 select_第1张图片

该控件支持绑定回调函数,支持动态事件等等。另一个比较实用的功能是,可以任意指定该控件的上一级联动控件:比如上面产品名称的上一级联动是系统名称,一旦系统名称选择值了,则产品名称必然是该系统属下的。如下图,联动状态下的自动完成搜索。

支持输入且自动完成的 select_第2张图片

代码参考 js 库的写法,使用完全的面向对象。

库的使用方法很简单,在 html 里面写一个 div,如

,然后在该页面加载后调用这句 js 代码即可:

var config={...} //具体配置后续加上

$('#sys_area').simulation(config);


库的代码如下:

(function($w){
'use strict';       
var __name__ = 'divInputSimulation';
var __version__ = '1.0';
var __author__ = 'edgarlli';
var logger = (typeof console === 'undefined')?{
            log:_noop, debug:_noop, error:_noop, warn:_noop, info:_noop
        }:console;

var divInputSimulation = function(config)
{
	this.divId = config.divId;
	this.inputId = (config.divId+"_input");
	this.expandDivId = (config.divId+"_expand_div");
	this.textKey = config.textKey;
	this.ajaxUrl = config.ajaxUrl;
	this.dataType = config.dataType;
	this.searchName = config.searchName;
	this.dataHandle = config.dataHandle;
	this.optionClickFunc = config.optionClickFunc;
	this.dependencyValuableNodeMap = config.dependencyValuableNodeMap;
	//等待用户不输入 1 秒后再去执行 search
	this. loseInputMillsecs = 1000;
	this.clocker = null;
	this.init();
};




divInputSimulation.prototype=
{
		init : function() {
			this.initDivInputSimulationSelect();
		},

		getInputNode : function()
		{
			return $('#'+this.inputId);
		},
		getexpandDivId : function()
		{
			return $('#'+this.expandDivId);
		},
		initDivInputSimulationSelect:function()
		{
			//add node
			var inputId = (this.divId+"_input");
			var expandDivId = (this.divId+"_expand_div");
			var addHtml = '';
			addHtml += '';
			addHtml += '
'; $('#'+this.divId).html(addHtml); var expandNode = $('#' + expandDivId); var inputNode = $('#' + inputId); $(document).click(function(e) { expandNode.hide(); if(inputNode.val() == "") inputNode.val('全选'); }) $('#'+this.divId).click(function(event){ event=event||window.event; event.stopPropagation(); }) var thisPointer = this; inputNode.focus(function() { if(inputNode.val() == "全选") inputNode.val(''); if(0 != expandNode.find('ul>li').length) expandNode.show(); else { thisPointer.search(thisPointer); } }) var v = this; inputNode.keydown(function(){ v.innerKeydown(); }) }, innerKeydown:function() { var search = this.search; if(null == this.clocker) { this.clocker = setTimeout(this.search,this.loseInputMillsecs,this); } else //再次击键,重新计时 { clearTimeout(this.clocker); this.clocker = setTimeout(this.search,this.loseInputMillsecs,this); } }, //因为 search 不在当前类的执行环境下,所以 search 中的 this 不是指的当前类。故需要将当前类的指针传入其中 search:function(thisPointer) { if(typeof thisPointer === 'undefined' || !thisPointer) thisPointer = this; var searchKey = $('#' + thisPointer.inputId).val(); if(searchKey == '全选') searchKey = ''; var param = {}; var nodeMap = thisPointer.dependencyValuableNodeMap; if(typeof nodeMap != 'undefined') { $.each(nodeMap,function(k,v) { param[k] = (v.val() == '全选' ? '' : v.val()); }) } param[thisPointer.searchName] = searchKey; $.post(thisPointer.ajaxUrl, param, function(result) { }, thisPointer.dataType) .success( function(result) { if(thisPointer.dataHandle) { result = thisPointer.dataHandle(result); } thisPointer.resetInputAttrs(thisPointer); thisPointer.resetExpand(thisPointer); thisPointer.buildDivInputtSimulationSelect(result,thisPointer); if(!!result && 0 != result.length) $('#' + thisPointer.expandDivId).show(); else $('#' + thisPointer.expandDivId).hide(); }).error(function() { console.info("load data error"); }); this.clocker = null; }, resetInputAttrs:function(thisPointer) { if(typeof thisPointer === 'undefined' || !thisPointer) thisPointer = this; var inputNode = $('#' + thisPointer.inputId); var attrs = inputNode[0].attributes; if(typeof attrs != 'undefined' && !!attrs) for(var i =0;i < attrs.length;++ i) { if(attrs[i].name == "style" || attrs[i].name=='id' || attrs[i].name=='class' || attrs[i].name == 'type') //跳过 style,id ,class continue; $(inputNode).attr(attrs[i].name,''); } }, resetExpand:function(thisPointer) { if(typeof thisPointer === 'undefined' || !thisPointer) thisPointer = this; var expandNode = $('#' + thisPointer.expandDivId); expandNode.html(''); }, hideExpand:function(thisPointer) { if(typeof thisPointer === 'undefined' || !thisPointer) thisPointer = this; var expandNode = $('#' + thisPointer.expandDivId); expandNode.hide(); }, /** * 由 div + input 模拟一个可输入的 select keyValues : 键值对数组 thisPointer : 当前类对象的指针 */ buildDivInputtSimulationSelect: function(keyValues,thisPointer) { if(typeof thisPointer === 'undefined' || !thisPointer) thisPointer = this; var addHtml = ''; var length = keyValues.length; addHtml += '
  • '; for(var i = 0;i < length;++ i) { addHtml += '
  • ' + curText + ''; } addHtml += '
'; $('#'+thisPointer.expandDivId + '>ul').remove(); $('#'+thisPointer.expandDivId).html(addHtml); $('#'+thisPointer.expandDivId).children('ul').children('li').hover(function(){ $(this).css("background-color","#428bca"); },function(){ $(this).css("background-color","#FFFFFF"); }) var optionClickFunc_ = thisPointer.optionClickFunc; $('#'+thisPointer.expandDivId).children('ul').children('li').on('click',function() { var attrs = this.attributes; console.info(attrs); var inputNode = $('#'+thisPointer.inputId); for(var i =0;i < attrs.length;++ i) { if(attrs[i].name == "style" || attrs[i].name=='id' || attrs[i].name=='class' || attrs[i].name == 'type') //跳过 style,id ,class continue; inputNode.attr(attrs[i].name,attrs[i].value); if(attrs[i].name == thisPointer.textKey) inputNode.val(attrs[i].value); } $('#'+thisPointer.expandDivId).hide(); if(optionClickFunc_) { optionClickFunc_($(this)); } }); }, } $w[__name__] = divInputSimulation; $.fn.simulation = function(config) { console.info(this); var divId = $(this).attr('id'); config.divId = divId; return new divInputSimulation(config) }; })(window);

你可能感兴趣的:(前端)