1. Add dynamically loaded css files. There is no need to introduce css. All css is dynamically generated in JS.
2. No additional tags are needed, only an input input box is required, and a class name is specified by default as "inputElem". Of course, you can also configure the parameters yourself. You also need a current parent container to add a default class name parentCls (you can also add it yourself Configuration), because the input box needs a hidden field after matching the value, so you need to add a class "hiddenCls" to the hidden field. Of course, you can also configure your own parameters.
The following code:
="text" class="inputElem" style="width:200px;height:26px;line-height:26px;"/>
="hiddenCls"/>
4. Supports mouse clicks and keyboard up and down key operations, similar to Baidu input box.
All tags on the page are dynamically generated, no additional tags are required. For example, the above only requires input tags. Other div tags do not depend on it. You only need to add class "parentCls" to the parent element (of course you can configure the class name yourself), and add a class to the hidden field input box to be passed to the background developer. "hiddenCls" can of course also configure parameters automatically.
My fuzzy query matching requirements are as follows: 1. Every time you click on the keyup or move the keyboard up or down, the input box is filled with the user name/employee number. The hidden field is filled with the employee number. Send a request to the server to return the data and render it. . Of course, the value of the hidden field filled with the employee number is when the form is submitted. The background needs to get the submitted employee number, so such a hidden field is needed.
2. When the user directly enters a value in the input box and does not move the keyboard up or down or clicks on an item in the drop-down box, when the mouse loses focus (blur), the current input box value is empty and the hidden field value is empty, so The purpose is to prevent the data after the last form submission from still being saved in the hidden field. When the user re-enters and the user does not move the keyboard up or down or click and then clicks the submit button (loses focus), the value is The empty hidden field value is empty to prevent the search from finding something other than what the user entered.
4. The interface that allows multiple selections in input boxes has been left behind. Currently, the operation of multiple selections in input boxes has not been perfected.
5. Disable ctrl v or right-click paste operations.
The following HTML code is as follows:
Copy code
JS代码如下:
function AutoComplete (options) {
this.config = {
targetCls : '.inputElem', // 输入框目标元素
parentCls : '.parentCls', // 父级类
hiddenCls : '.hiddenCls', // 隐藏域input
searchForm :'.jqtransformdone', //form表单
hoverBg : 'hoverBg', // 鼠标移上去的背景
outBg : 'outBg', // 鼠标移下拉的背景
isSelectHide : true, // 点击下拉框 是否隐藏
url : '', // url接口
height : 0, // 默认为0 不设置的话 那么高度自适应
manySelect : false, // 输入框是否多选 默认false 单选
renderHTMLCallback : null, // keyup时 渲染数据后的回调函数
callback : null, // 点击某一项 提供回调
closedCallback : null // 点击输入框某一项x按钮时 回调函数
};
this.cache = {
currentIndex : -1,
oldIndex : -1,
inputArrs : [] // 多选时候 输入框值放到数组里面去
};
this.init(options);
}
AutoComplete.prototype = {
constructor: AutoComplete,
init: function(options) {
this.config = $.extend(this.config, options || {});
var self = this,
_config = self.config,
_cache = self.cache;
// 鼠标点击输入框时候
$(_config.targetCls).each(function(index,item) {
/*
* 禁止 ctrl+v 和 黏贴事件
*/
$(item).unbind('paste');
$(item).bind('paste',function(e){
e.preventDefault();
var target = e.target,
targetParent = $(target).closest(_config.parentCls);
$(this).val('');
$(_config.hiddenCls,targetParent) && $(_config.hiddenCls,targetParent).val('');
});
$(item).keyup(function(e){
_cache.inputArrs = [];
var targetVal = $.trim($(this).val()),
keyCode = e.keyCode,
elemHeight = $(this).outerHeight(),
elemWidth = $(this).outerWidth();
// 如果输入框值为空的话 那么隐藏域的value清空掉
if(targetVal == '') {
var curParents = $(this).closest(_config.parentCls);
$(_config.hiddenCls,curParents).val('');
}
var targetParent = $(this).parent();
$(targetParent).css({'position':'relative'});
if($('.auto-tips',targetParent).length == 0) {
// 初始化时候 动态创建下拉框容器
$(targetParent).append($('
// 阻止form表单默认enter键提交
$(_config.searchForm).each(function(index,item) {
$(item).keydown(function(e){
var keyCode = e.keyCode;
if(keyCode == 13) {
return false;
}
});
});
// 点击文档
$(document).click(function(e){
e.stopPropagation();
var target = e.target,
tagParent = $(target).parent(),
attr = $(target,tagParent).closest('.auto-tips');
var tagCls = _config.targetCls.replace(/^\./,'');
if(attr.length > 0 || $(target,tagParent).hasClass(tagCls)) {
return;
}else {
$('.auto-tips').each(function(index,item){
!$(item,tagParent).hasClass('hidden') && $(item,tagParent).addClass('hidden');
});
}
});
var stylesheet = '.auto-tips { margin: 0 1px; list-style: none;height:auto !important;padding: 0px;position:absolute; border:1px solid #ccc; top:27px; left:0; z-index:999; width:100%;background:#fff !important;}' +
'.auto-tips p {overflow: hidden;margin: 1px 0;padding: 5px 5px;border-bottom: 1px solid #e7e7e7;color: #666;text-decoration: none;line-height: 23px;white-space: nowrap;cursor: pointer;zoom: 1;}' +
'.auto-tips p img{ vertical-align:middle;float:left;}' +
'.create-input{line-height:26px,padding-left:3px;}' +
'.create-input span{margin-top:1px;height:24px;float:left;}' +
'.create-input span i,.auto-tips span a{font-style:normal;float:left;cursor:default;}' +
'.create-input span a{padding:0 8px 0 3px;cursor:pointer;}' +
'.auto-tips p.hoverBg {background-color: #669cb6;color: #fff;cursor: pointer;}' +
'.hidden {display:none;}';
this._addStyleSheet(stylesheet);
},
/**
* 键盘上下键操作
*/
_keyUpAndDown: function(targetVal,e,targetParent) {
var self = this,
_cache = self.cache,
_config = self.config;
// 如果请求成功后 返回了数据(根据元素的长度来判断) 执行以下操作
if($('.auto-tips p',targetParent) && $('.auto-tips p',targetParent).length > 0) {
var plen = $('.auto-tips p',targetParent).length,
keyCode = e.keyCode;
_cache.oldIndex = _cache.currentIndex;
// 上移操作
if(keyCode == 38) {
if(_cache.currentIndex == -1) {
_cache.currentIndex = plen - 1;
}else {
_cache.currentIndex = _cache.currentIndex - 1;
if(_cache.currentIndex < 0) {
_cache.currentIndex = plen - 1;
}
}
if(_cache.currentIndex !== -1) {
!$('.auto-tips .p-index'+_cache.currentIndex,targetParent).hasClass(_config.hoverBg) &&
$('.auto-tips .p-index'+_cache.currentIndex,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
var curAttr = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('data-html'),
embId = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('embId');
// 判断是否是多选操作 多选操作 暂留接口
if(_config.manySelect) {
_cache.inputArrs.push(curAttr);
_cache.inputArrs = self._unique(_cache.inputArrs);
self._manySelect(targetParent);
}else {
$(_config.targetCls,targetParent).val(curAttr);
// 上移操作增加一个属性 当失去焦点时候 判断有没有这个属性
if(!$(_config.targetCls,targetParent).attr('up')){
$(_config.targetCls,targetParent).attr('up','true');
}
var pCls = $(_config.targetCls,targetParent).closest(_config.parentCls);
$(_config.hiddenCls,pCls).val(embId);
self._createDiv(targetParent,curAttr);
self._closed(targetParent);
// hover
self._hover(targetParent);
}
}
}else if(keyCode == 40) { //下移操作
if(_cache.currentIndex == plen - 1) {
_cache.currentIndex = 0;
}else {
_cache.currentIndex++;
if(_cache.currentIndex > plen - 1) {
_cache.currentIndex = 0;
}
}
if(_cache.currentIndex !== -1) {
!$('.auto-tips .p-index'+_cache.currentIndex,targetParent).hasClass(_config.hoverBg) &&
$('.auto-tips .p-index'+_cache.currentIndex,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
var curAttr = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('data-html'),
embId = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('embId');
// 判断是否是多选操作 多选操作 暂留接口
if(_config.manySelect) {
_cache.inputArrs.push(curAttr);
_cache.inputArrs = self._unique(_cache.inputArrs);
self._manySelect(targetParent);
}else {
$(_config.targetCls,targetParent).val(curAttr);
// 下移操作增加一个属性 当失去焦点时候 判断有没有这个属性
if(!$(_config.targetCls,targetParent).attr('down')){
$(_config.targetCls,targetParent).attr('down','true');
}
var pCls = $(_config.targetCls,targetParent).closest(_config.parentCls);
$(_config.hiddenCls,pCls).val(embId);
self._createDiv(targetParent,curAttr);
self._closed(targetParent);
// hover
self._hover(targetParent);
}
}
}else if(keyCode == 13) { //回车操作
var curVal = $('.auto-tips .p-index'+_cache.oldIndex,targetParent).attr('data-html');
$(_config.targetCls,targetParent).val(curVal);
if(_config.isSelectHide) {
!$(".auto-tips",targetParent).hasClass('hidden') && $(".auto-tips",targetParent).addClass('hidden');
}
_cache.currentIndex = -1;
_cache.oldIndex = -1;
}
}
},
// 键码判断
_keyCode: function(code) {
var arrs = ['17','18','38','40','37','39','33','34','35','46','36','13','45','44','145','19','20','9'];
for(var i = 0, ilen = arrs.length; i < ilen; i++) {
if(code == arrs[i]) {
return i;
}
}
return -1;
},
_doPostAction: function(targetVal,targetParent) {
var self = this,
_cache = self.cache,
_config = self.config,
url = _config.url;
// 假如返回的数据如下:
var results = [{lastName:'tugenhua',emplId:'E0987',image:''},{lastName:'tugenhua',emplId:'E0988',image:''},{lastName:'tugenhua',emplId:'E0989',image:''}];
self._renderHTML(results,targetParent);
self._executeClick(results,targetParent);
/** $.get(url+"?keyword="+targetVal+"×tamp="+new Date().getTime(),function(data){
var ret = $.parseJSON(data.content),
results = ret.results;
if(results.length > 0) {
self._renderHTML(results,targetParent);
self._executeClick(results,targetParent);
}else {
!$('.auto-tips',targetParent).hasClass('hidden') && $('.auto-tips',targetParent).addClass("hidden");
$('.auto-tips',targetParent).html('');
}
});**/
},
_renderHTML: function(ret,targetParent) {
var self = this,
_config = self.config,
_cache = self.cache,
html = '';
for(var i = 0, ilen = ret.length; i < ilen; i+=1) {
html += '
' +
'' +
''+ret[i].lastName+'('+ret[i].emplId+')' +
'
_config.renderHTMLCallback && $.isFunction(_config.renderHTMLCallback) && _config.renderHTMLCallback();
// 出现滚动条 计算p的长度 * 一项p的高度 是否大于 设置的高度 如是的话 出现滚动条 反之
var plen = $('.auto-tips p',targetParent).length,
pheight = $('.auto-tips p',targetParent).height();
if(_config.height > 0) {
if(plen*pheight > _config.height) {
$('.auto-tips',targetParent).css({'height':_config.height,'overflow':'auto'});
}else {
$('.auto-tips',targetParent).css({'height':'auto','overflow':'auto'});
}
}
},
/**
* 当数据相同的时 点击对应的项时 返回数据
*/
_executeClick: function(ret,targetParent) {
var self = this,
_config = self.config,
_cache = self.cache;
$('.auto-tips p',targetParent).unbind('click');
$('.auto-tips p',targetParent).bind('click',function(e){
var dataAttr = $(this).attr('data-html'),
embId = $(this).attr('embId');
// 判断是否多选
if(_config.manySelect) {
_cache.inputArrs.push(dataAttr);
_cache.inputArrs = self._unique(_cache.inputArrs);
self._manySelect(targetParent);
}else {
$(_config.targetCls,targetParent).val(dataAttr);
var parentCls = $(_config.targetCls,targetParent).closest(_config.parentCls),
hiddenCls = $(_config.hiddenCls,parentCls);
$(hiddenCls).val(embId);
self._createDiv(targetParent,dataAttr);
// hover
self._hover(targetParent);
!$(_config.targetCls,targetParent).hasClass('hidden') && $(_config.targetCls,targetParent).addClass('hidden');
}
self._closed(targetParent);
if(_config.isSelectHide) {
!$('.auto-tips',targetParent).hasClass('hidden') && $('.auto-tips',targetParent).addClass('hidden');
}
_config.callback && $.isFunction(_config.callback) && _config.callback();
});
// 鼠标移上效果
$('.auto-tips p',targetParent).hover(function(e){
!$(this,targetParent).hasClass(_config.hoverBg) &&
$(this,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
});
},
_hover: function(targetParent){
$('.create-input span',targetParent).hover(function(){
$(this).css({"background":'#ccc','padding-left':'0px'});
},function(){
$(this).css({"background":''});
});
},
// 动态的创建div标签 遮住input输入框
_createDiv: function(targetParent,dataAttr){
var self = this,
_config = self.config;
var iscreate = $('.create-input',targetParent);
// 确保只创建一次div
if(iscreate.length > 0) {
$('.create-input',targetParent).remove();
}
$(targetParent).prepend($('
var targetInput = $(_config.targetCls,targetParent);
if($(targetInput).attr('up') || $(targetInput).attr('down')) {
$(targetInput).attr('up') && $(targetInput).removeAttr('up');
$(targetInput).attr('down') && $(targetInput).removeAttr('down');
}
_config.closedCallback && $.isFunction(_config.closedCallback) && _config.closedCallback();
});
},
/*
* 数组去重复
*/
_unique: function(arrs) {
var obj = {},
newArrs = [];
for(var i = 0, ilen = arrs.length; i < ilen; i++) {
if(obj[arrs[i]] != 1) {
newArrs.push(arrs[i]);
obj[arrs[i]] = 1;
}
}
return newArrs;
},
/*
* 输入框多选操作
*/
_manySelect: function(targetParent) {
var self = this,
_config = self.config,
_cache = self.cache;
if(_cache.inputArrs.length > 0) {
$(_config.targetCls,targetParent).val(_cache.inputArrs.join(','));
}
},
/*
* 判断是否是string
*/
_isString: function(str) {
return Object.prototype.toString.apply(str) === '[object String]';
},
/*
* JS 动态添加css样式
*/
_addStyleSheet: function(refWin, cssText, id){
var self = this;
if(self._isString(refWin)) {
id = cssText;
cssText = refWin;
refWin = window;
}
refWin = $(refWin);
var doc = document;
var elem;
if (id && (id = id.replace('#', ''))) {
elem = $('#' + id, doc);
}
. ; There is a bug in IE8 that cannot be created this way
. ', doc).append(elem);
if (elem.styleSheet) { // IE
elem.styleSheet.cssText = cssText;
} else { // W3C
elem .appendChild(doc.createTextNode(cssText));
}
},
/*
* Destroy operation to release memory
*/
destory: function() {
var self = this,
_config = self.config,
_cache = self.cache;
_cache.ret = [];
_cache.currentIndex = 0;
_ cache.oldIndex = 0 ;
_cache.inputArrs = [];
_config.targetCls = null;
}
};
// Initialization
$(function(){
var auto = new AutoComplete({
// url: '/rocky/commonservice/user/find.json'
});
});