概述
效果图:
仿写初衷:因为代码表的数据量太大了,用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输入联想且带分页 远程数据源(纯自创)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复