我是靠谱客的博主 幸福日记本,最近开发中收集的这篇文章主要介绍仿autoComplete输入联想且带分页 远程数据源(纯自创),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

效果图:

仿写初衷:因为代码表的数据量太大了,用select做下拉列表和点击后弹框选择,都不太人性化了,再加上本人的一点点强迫症,再就jQuery autoCompete吧,它竟然分不了页,这下我蛋疼了,还非得强迫我自己写啊!


仔细想想,这功能要做的话,也不太难,就几个地方要考虑:

1.通过什么事件来刷新数据?

答案:通过文本框的onkeyup,监听onkeyup事件,即可将键入的值传到后台去进行模糊匹配

2.在用户到频率的输入下,怎样减少服务器的压力?

答案:通过timer定时器,设置当前只能有一个且唯一一个定时器,当定时器时满,则开始查询数据库

3.分页需要再重新查数据库吗?

答案:如果数据量很大,建议分页再重新查数据库

4.下拉列表用什么做?

答案:下拉列表用div来仿做,一行就是一个div,且id也必须规范为类似 item+数字 的形式,以便显示高亮选中状态

5.div行选中后怎么赋值?

答案:给每个div做一个onclick事件,函数为assignValue()

5.怎么通过键盘的上(↑)下(↓)键控制下拉列表框的上下移动,及其enter后选中并填充?

答案:监听文本框的onkeyup事件,设置一个全局变量curItemIndex(当前下拉框被选中的项目索引号),获取event的key值,比较key与38(上方向键的ASCII) 40(下方向键的ASCII),对应curItemIndex加一或减一,然后css,使其背景发生变化就可以了.enter后填充,则是通过curItemIndex定位div行,当前选中的div的id当然就是item+curItemIndex了,调用onclick事件就可以了。


在输入过程中监听input的onkeyup事件,500ms后查询数据库刷新下拉列表框,进行联想显示,且支持分页效果

index.jsp代码:

先加入我写的MyAutoComplete.js(最下面有下载链接)和MyAutoComplete.css(最下面有下载链接)以及DWR所需js文件

        <link href="css/myAutoComplete.css" rel="stylesheet" type="text/css" />
	<!-- DWR相关js文件 -->
	<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/engine.js"></script><%--固定写法--%>
	<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/util.js"></script>
	<script type="text/javascript" src="<%=request.getContextPath()%>/dwr/interface/DwrServer.js"></script>
	<!-- 实现输入联想主要JS文件 -->
	<script type="text/javascript" src="jscript/myAutoComplete.js"></script>
index.jsp body部分

<!-- 仿jquery的autoComplete联想输入下拉列表框 -->
	<div id="newStackDiv" class="newStackDiv" style="display:none;">
		<div id="top_items" class="top_items">
			<!-- 向前、向后 实现分页 -->
		    <span class="span_leftTo">« 向前</span>
			<span class="span_rightTo">向后 »</span>
	    </div>
	    <div id="panel_items" class="panel_items">
	    <!-- 模拟的下拉列表框就在这 -->
	    </div>
	    <div id="bottom_items">
	    	<a class="rightTo" href="javascript:hiddenNewDiv();">关闭</a>
	    </div>
	</div>
	
	<!-- 设置autocomplete="off"是为了禁止浏览器的输入提醒,这个很烦的,以免遮挡层叠的div还是加上吧,也可以在form里写上 -->
	<input type="hidden" name="partsNameId" id="partsNameId" value="" />
	配件名称:
	<input type="text" name="partsName" id="partsName" <span style="color:#CC33CC;">onkeyup</span>="javascript:<span style="color:#FF0000;">searchAndmoveNewDiv</span>('partsNameId','partsName','num','3',event);" <span style="color:#FF0000;">autocomplete="off"</span>/>
	排产数量:
	<input type="text" name="num" id="num" autocomplete="off"/>
onkeyup事件主要监听键盘输入包括上下键的移动及enter选中等事件,好了,我们来看MyAutoComplete.js内容,里面有很详细的说明

	var curItemIndex = 1;// 下拉框被选中的项目索引号
	var maxRows = 5;// 每页显示的最大记录数
	var curPageRow = 5;// 当前页实际行数
	var totalRows = 0;// 总记录数
	var itemDataJson;// 查询返回的json数据
	var time = 500; // 500毫秒
	var v_inputId;// 和inputValue对应的隐藏的id主键
	var v_inputName;// 要被显示下拉框的name属性值
	var v_nextInputId;// 下一个文本框,当选中下拉框后,焦点的指向位置
	var timer;// 定时器,控制只有每时每刻只有一个timer
	function getAbsPoint(e)// 获取绝对坐标
	{
	    var x = e.offsetLeft;
	    var y = e.offsetTop;
	    while(e = e.offsetParent)
	    {
	        x += e.offsetLeft;
	        y += e.offsetTop;
	    }
	    return {"x": x, "y": y};
	}
	// input onkeydown后开始查询-这里延迟300ms,为了避免引发频繁的search
	function startSearchItems(type){
		if(timer == null)
			timer = setTimeout("searchItems('"+type+"')",time); //跳转
	}
	// 利用DWR查询like inputName的结果
	function searchItems(type){
		var searchName = document.getElementById(v_inputName).value;
		// ###############根据具体项目要求可把这里进行重写 BEGIN################
		DwrServer.getNewSearchList(type,searchName,backNewSearchData);// backNewSearchData返回结果函数
		// ###############根据具体项目要求可把这里进行重写 END##################
	}
	
	// DWR返回查询后的json记录
	function backNewSearchData(data){
		data = eval(data);
		itemDataJson = data;
		totalRows = data.length;
		var htmlStr = "";
		var index = 0;
		for(; index < totalRows; index++){
			if(index >= maxRows)
				break;
			if(index == 0){
				htmlStr += "<div id="item1"  class="itemlineover" οnmοuseοver="javascript:onmouseoverFuc('1');" οnclick="javascript:assignNewValue('"+data[index].id+"','"+data[index].name+"');">";
			}else{
				htmlStr += "<div id="item"+(index+1)+""  class="itemline" οnmοuseοver="javascript:onmouseoverFuc('"+(index+1)+"');" οnclick="javascript:assignNewValue('"+data[index].id+"','"+data[index].name+"');">";
			}
			htmlStr += "<span class="ralign">"+data[index].name+"</span></div>";
		}
		curPageRow = index;
		var topHtmlStr = "<span class="span_leftTo">« 向前</span>";
		if(maxRows < totalRows){// 当前列表行数超过每页最大行数,则有下一页
			topHtmlStr += "<a class="rightTo" href="javascript:item_showlist(2);">向后 »</a>";
		}else{
			topHtmlStr += "<span class="span_rightTo">向后 »</span>";
		}
		document.getElementById("top_items").innerHTML = topHtmlStr;
		document.getElementById("panel_items").innerHTML = htmlStr;
		timer = null;
		if(index >= 1)
			curItemIndex = 1;// 初始化
		else
			curItemIndex = 0;// 初始化
		showNewDiv();
	}
	
	// 翻页-index索引页
	function item_showlist(toPageIndex){
		document.getElementById(v_inputName).focus();
		var htmlStr = "";
		var index = (toPageIndex - 1) * maxRows;
		var count = 0;
		for(; index < totalRows; index++){
			count++;
			if(count == 1){
				htmlStr += "<div id="item1"  class="itemlineover" οnmοuseοver="javascript:onmouseoverFuc('1');" οnclick="javascript:assignNewValue('"+itemDataJson[index].id+"','"+itemDataJson[index].name+"');">";
			}else{
				htmlStr += "<div id="item"+count+""  class="itemline" οnmοuseοver="javascript:onmouseoverFuc('"+count+"');" οnclick="javascript:assignNewValue('"+itemDataJson[index].id+"','"+itemDataJson[index].name+"');">";
			}
			htmlStr += "<span class="ralign">"+itemDataJson[index].name+"</span></div>";
			if(count >= maxRows)
				break;
		}
		if(count >= 1)
			curItemIndex = 1;// 初始化
		else
			curItemIndex = 0;// 初始化
		curPageRow = count;
		var topHtmlStr = "";
		if(toPageIndex <= 1){
			topHtmlStr += "<span class="span_leftTo">« 向前</span>";
		}else{
			topHtmlStr += "<a class="leftTo" href="javascript:item_showlist("+(toPageIndex - 1)+");">« 向前</a>";
		}
		if(index < (totalRows - 1)){// 索引还没达到最大记录数时,则有下一页
			topHtmlStr += "<a class="rightTo" href="javascript:item_showlist("+(toPageIndex + 1)+");">向后 »</a>";
		}else{
			topHtmlStr += "<span class="span_rightTo">向后 »</span>";
		}
		document.getElementById("top_items").innerHTML = topHtmlStr;
		document.getElementById("panel_items").innerHTML = htmlStr;
	}
	
	// 显示查询后的下拉列表
	function showNewDiv(){
		var e = document.getElementById(v_inputName);
		var position = getAbsPoint(e);
		var t = position["x"];
		var l = position["y"];
		var h = e.offsetHeight;
		var d = document.getElementById("newStackDiv");
		d.style.left = t + 'px';
		d.style.top = (l + h) + 'px';
		d.style.display = "block";
	}
	// 点击列表中选项后触发的事件,id和name的赋值操作
	function assignNewValue(idValue, nameValue){
		document.getElementById(v_inputId).value = idValue;
		document.getElementById(v_inputName).value = nameValue;
		document.getElementById("newStackDiv").style.display = "none";
		if(v_nextInputId != null)
            document.getElementById(v_nextInputId).focus();
	}
	// 失去焦点事件
	function onmouseoutFuc(j){
		var e = document.getElementById("item"+j);
		e.className = "itemline";
	}
	// 获取焦点事件,j获取焦点,使得其它全部失去焦点
	function onmouseoverFuc(j){
		curItemIndex = j;
		var e = document.getElementById("item"+j);
		e.className = "itemlineover";
		for(var k = 1; k <= curPageRow; k++){
			if(k != j)
				onmouseoutFuc(k);
		}
	}
	// 隐藏层叠div
	function hiddenNewDiv(){
		document.getElementById("newStackDiv").style.display = "none";
		document.getElementById(v_inputId).value = "";
		document.getElementById(v_inputName).value = "";
	}
	// 当键盘按下的时候,捕捉上下及enter键
    function searchAndmoveNewDiv(inputId1, inputName1, nextInputId, type, evt) {
    	v_inputId = inputId1;
		v_inputName = inputName1;
    	v_nextInputId = nextInputId;
    	evt = (evt) ? evt : ((window.event) ? window.event : ""); //兼容IE和Firefox获得keyBoardEvent对象
		var key = evt.keyCode?evt.keyCode:evt.which;//兼容IE和Firefox获得keyBoardEvent对象的键值 
        //获取 event 对象
        var event = event || window.event;
        if(key != 38 && key != 40 && key != 13){
        	startSearchItems(type);
        	return;
        }
        switch (key) {
            case 38:{   //键盘中左键(↑)
            	if(curItemIndex > 1 && curItemIndex <= curPageRow){
            		curItemIndex--;
            	}else if(curItemIndex == 1){
            		curItemIndex = curPageRow;
            	}
            	onmouseoverFuc(curItemIndex);
                break;
            }
            case 40:{  //键盘中下键(↓)
            	if(curItemIndex >= 1 && curItemIndex < curPageRow){
            		curItemIndex++;
            	}else if(curItemIndex == curPageRow){
            		curItemIndex = 1;
            	}
            	onmouseoverFuc(curItemIndex);
                break;
			}
			case 13:{ //enter
            	if(curItemIndex >= 1 && curItemIndex <= curPageRow){
            		var oneItem = document.getElementById("item"+curItemIndex);
            		if(oneItem != null)
            			oneItem.onclick();
            	}
            	if(v_nextInputId != null)
            		document.getElementById(v_nextInputId).focus();
                break;
			}
        }
        return;
    }
以及最后的css:

/* 层叠div(选项框) 罗蓉蓉 2014-10-29 */
.newStackDiv{ position:absolute;background:#F7F8F9; z-index:1; width:350px;padding: 1px;border-width: 1px;border-style: solid;border-color: #7F9DB9;font-family: Arial;}
.top_items{height: 22px;}
#panel_items div{padding: 2px;cursor: pointer;font-size: 12px;}
#panel_items span {padding: 1px 0px 0px;display: block;color: #05A;}
.ralign {float: left;text-align: left;padding:0 0 0 2px;}
.itemlineover {height: 20px;border-top: 1px solid #68A7F6;border-bottom: 1px solid #68A7F6;color: #666;background-color: #C8E3FC;}
.itemline {height: 20px;background-color: #FFF;border-top: 1px solid #FFF;border-bottom: 1px solid #FFF;}
.leftTo,.rightTo{font-size: 12px;color: #000;text-decoration: none;cursor:pointer;padding:2px;}
.leftTo{float:left;}
.rightTo{float:right;}
.span_leftTo,.span_rightTo{font-size: 12px;color: #000;text-decoration: none;cursor:pointer;padding:2px;}
.span_leftTo{float:left;}
.span_rightTo{float:right;}
.leftTo:hover{color: #F00;text-decoration: underline;}
.rightTo:hover{color: #F00;text-decoration: underline;}
a, a:focus {outline: medium none;}

代码里面注释说的挺仔细的,要是还是不清楚的话,就直接去下载我上传的资源吧,里面的程序直接导入myeclipse中就可以运行

资源链接 http://download.csdn.net/detail/u011054048/8326699

最后

以上就是幸福日记本为你收集整理的仿autoComplete输入联想且带分页 远程数据源(纯自创)的全部内容,希望文章能够帮你解决仿autoComplete输入联想且带分页 远程数据源(纯自创)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部