JS实现联想输入(一)是主要针对单列结构的JSON格式的数据的,如果想满足多列结构的JSON格式的数据,也是非常容易的,其解决方案有至少有三种选择:

1:在后台Action方法中将多列的值拼成单列结构的值,然后和JS实现联想输入(一)中的实现方式没什么大的变化,只是在前台看数据时有点怪怪的(比如用“|”隔开的情景下),而且需要在前台将对应数剧拆开来用

2:利用联想输入框中的数据,再次的调用AJAX方法到后台去查询对应的数据,也和JS实现联想输入(一)中的实现方式没什么大的变化,只是又多调用了一下后台的Action方法,当然他有一些局限性,如果联想输入框中的数据到后台作为参数不能唯一定位到一条数据的话,就有些不适用了

3:第三种方式就是我下面要分享的一种方式了,从后台返回多列结构的JSON格式的数据(一般两列就足够了,一列是表的主键数据列,另一列是要显示的作为联想输入的数据列)在前台用两个TD封装,一个显示其中的内容,另一个则隐藏。实现的方式和JS实现联想输入(一)也基本类似,只是从后台Action方法中返回的数据是双列结构的JSON数据(当然,你也可以使用其他格式的数据)和拼装下拉列表的方式所有不同而已

下面是我要分享的代码段,仅作为我的小小的记录而已!

1:首先同样是后台的Action方法的代码,用于取数据,查询语句是模糊查询的方式(如果数据库中的数据相似度非常大,可以采用分页的方式取部分的数据,比如:取十条记录)。

     /**
* @说明:这仍是一段伪码,主要想说明从后台返回的数据是JSON格式的,并且形如:[{"linkDataName":name1,"linkDataId":id1},{"linkDataName":name2,"linkDataId":id2},{"linkDataName":name3,"linkDataId":id3}]
* @author godtrue
* @修改时间:2014-02-24
* @param
* @return
*/
public void getLinkDataList(){
linkData.setLinkDataName(linkDataName);
List<LinkData> linkDataList = linkDataService.getLinkDataList(linkData);
if(linkDataList!=null&&linkDataList.size()>0){
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("[");
for(int i=0;i<linkDataList.size()-1;i++){
stringBuffer.append("{\"linkDataName\":\"").append(linkDataList.get(i).getLinkDataName()).append("\",");
stringBuffer.append("\"linkDataId\":\"").append(linkDataList.get(i).getLinkDataId()).append("\"},");
}
stringBuffer.append("{\"linkDataName\":\"").append(linkDataList.get(linkDataList.size()-1).getLinkDataName()).append("\",");
stringBuffer.append("\"linkDataId\":\"").append(linkDataList.get(linkDataList.size()-1).getLinkDataId()).append("\"}]");
renderJson(ServletActionContext.getResponse(),stringBuffer.toString());
}else{
renderJson(ServletActionContext.getResponse(),"[]");
}
}

renderJson方法的源码和JS实现联想输入(一)中renderJson方法的源码是一模一样的再次就不再给出了!

说明:同样假设上面的代码中LinkData是一个对象其中他拥有两个属性分别是linkDataName和linkDataId(在此Aciton类中有linkData和linkDataName的声明和对应的SET/GET方法,所以们的值在前后台能相互的传送,并且linkDataId属性对应的数据库中表的列能够唯一的标示出数据库中的一条记录),linkDataService是业务层的一个接口对象,它调用对应的方法获得对应的模糊查询的数据结果集linkDataList,然后将结果集中的数据封装成双列结构的JSON格式的数据形如:[{"linkDataName":name1,"linkDataId":id1},{"linkDataName":name2,"linkDataId":id2},{"linkDataName":name3,"linkDataId":id3}]

2:前台JSP中的HTML代码,这段代码同样主要是展示HTML输入框和为联想输入的下拉选项列表做支撑的(此段代码和JS实现联想输入(一)中的对应的代码基本一模一样,只是多了一个样式"z-indexe:1001"以使下拉列表处在页面的最上层,当然这是在需要的情况下才添加此样式的,在我们的项目中就需要这个,当然还有一个隐藏域专门来接收linkDataId属性的数据,只要将他放在FORM表单中就可)
 <td><input id="linkDataId" name="linkData.linkDataId" type="hidden"></input><input style="width:100%;" id="linkDataName" name="linkData.linkDataName" type="text" onkeyup="getLinkData();" />
<div id="popup" style="position: absolute;z-index:1001;">
<table width="100%" bgcolor="#fffafa">
<tbody id="popupBody"></tbody>
</table>
</div>
</td>

3:前台JSP中的javaScript代码,当然这段代码具有一定的通用性,最好封装在一个单独的js文件中更好一些(这也是实现此功能最为关键的一段代码,原理很简单:利用ajax动态调用后台的方法获取对应的联想输入的数据,然后将数据拼装成下拉选项列表的形式,再在对应的列表选项上添加对应的事件来控制选中的选项数据,只是和JS实现联想输入(一)的不同在于,这次的事件加在了TR上,并且隐藏了一列我们不想让用户看到的TD列)

           function getLinkData() {
var popupDiv = document.getElementById("popup");//获得对应的div对象
var popupBody = document.getElementById("popupBody");//获得对应的tbody对象
var linkDataName = document.getElementById("linkDataName"); //获得对应的联想输入框对象
var linkDataId = document.getElementById("linkDataId"); //获得对应的隐藏域对象
clearModels();//清除联想输入提示框的内容
$.ajax({
type : "post",//提交的方法为post
url : "getLinkDataList.action",//提交的路径
dataType : "json", //从Action中返回的值得类型为json类型的
data:{linkDataName:linkDataName.value},//从前台传递到后台的参数,可以避免出现乱码的情况
error:function(){
alert("没有对应的数据,请查看输入的查询条件!");
},
success : function(data) {//当Ajax提交成功时调用的方法
if(data.length==0||data=="[]"){return;}
setOffsets();//设置联想输入提示框的位置及样式
var tr,td,text,td_,text_;
for (var i = 0; i < data.length; i++) {//根据返回的值,手动的拼tbody的内容,此为此功能的核心代码
text = document.createTextNode(data[i].linkDataName);//从Action中返回的数据中取出linkDataName的值
td = document.createElement("td");//创建一个td的对象
tr = document.createElement("tr");//创建一个tr的对象 text_ = document.createTextNode(data[i].linkDataId);//从Action中返回的数据中取出linkDataId的值
td_ = document.createElement("td");//创建一个另一个td的对象
td_.style.display="none"; //并且设置其样式是不可见的 td.appendChild(text);
td_.appendChild(text_);
tr.appendChild(td);
tr.appendChild(td_); tr.mouseOver = function(){this.className="mouseOver;";};
tr.mouseOut = function(){this.className="mouseOut;";};
tr.onclick = function(){populateModel(this);};//tr单击事件对应的实现方法
popupBody.appendChild(tr);
}
}});
//获取下拉列表项的内容,初始化相关的数据
function populateModel(cell) {
clearSelect();
linkDataName.value = cell.firstChild.firstChild.nodeValue;
linkDataId.value=cell.lastChild.lastChild.nodeValue;
clearModels();//清除自动完成行
}
//清除自动完成行,只要tbody有子节点就删除掉,并且将将外围的div的边框属性设置为不可见的
function clearModels() {
while (popupBody.childNodes.length > 0) {
popupBody.removeChild(popupBody.firstChild);
}
popupDiv.style.border = "none";
}
//设置下拉列表框的的位置及样式
function setOffsets() {
var width = linkDataName.offsetWidth+20;//如果下拉列表中有折叠的行,可以在此加大些宽度
var left = getLeft(linkDataName);
var top = getTop(linkDataName) + linkDataName.offsetHeight;
popupDiv.style.border = "black 1px solid";
popupDiv.style.left = left + "px";
popupDiv.style.top = top + "px";
popupDiv.style.width = width + "px";
}
//获取指定元素在页面中的宽度起始位置
function getLeft(e) {
var offset = e.offsetLeft;
if (e.offsetParent != null) {
offset += getLeft(e.offsetParent);
}
return offset;
}
//获取指定元素在页面中的高度起始位置
function getTop(e) {
var offset = e.offsetTop;
if (e.offsetParent != null) {
offset += getTop(e.offsetParent);
}
return offset;
}
}
//清空联想输入框的内容以及隐藏域的值
function clearSelect() {
var linkDataId = document.getElementById("linkDataId");
linkDataId.value = "";
var linkDataName = document.getElementById("linkDataName");
linkDataName.value = "";
}
注:此方法对于双列结构的集合是适用的,大部分代码和JS实现联想输入(一)是一致的,仅在数据的传送和拼装上做了少许的变动,关键的地方在于前台的JS代码如何实现下拉列表的形式展现数据并形成联想输入的样子!

JS实现联想输入(二)的更多相关文章

  1. JS实现联想输入(一)

    这里是我们的项目中的一个使用JS实现联想输入的功能代码,在此做个小的记录并且将它分享给大家希望对园中的朋友有用! 我将分享三段都非常简单的代码,仅仅作为个人的一点小小的积累而已! 1:后台的Actio ...

  2. 【高德地图API】从零开始学高德JS API(二)地图控件与插件——测距、圆形编辑器、鼠标工具、地图类型切换、鹰眼鱼骨

    原文:[高德地图API]从零开始学高德JS API(二)地图控件与插件——测距.圆形编辑器.鼠标工具.地图类型切换.鹰眼鱼骨 摘要:无论是控件还是插件,都是在一级API接口的基础上,进行二次开发,封装 ...

  3. qrcode.js 动态生成二维码

    用qrcode.js动态生成二维码图片非常简单,只需要引入qrcode.js即可使用,而且可以自定义图片大小.背景色等信息. 1.jsp代码---页面头部引入qrcode.js,jquery文件可选 ...

  4. node.js 初学(二)—— 搭建注册/登录服务器

    node.js 初学(二)—— 搭建注册/登录服务器 理论上来说,代码实现在理论和实际上是一样的.但实际上来说,他们不是 做一个最简单的用户注册登录功能 1.接口定义: 注册:/user?act=re ...

  5. js生成简单二维码

    js文件下载地址:https://download.csdn.net/download/weixin_38296752/10554485 一.引入qrcode.js文件 <script type ...

  6. 进击Node.js基础(二)

    一.一个牛逼闪闪的知识点Promise npm install bluebird 二.Promise实例 ball.html <!doctype> <!DOCTYPE html> ...

  7. js生成中文二维码

    http://www.cnblogs.com/xcsn/archive/2013/08/14/3258035.html http://www.jb51.net/article/64928.htm 使用 ...

  8. Cordova app 检查更新 ----JS进行调用(二)

    原文:Cordova app 检查更新 ----JS进行调用(二) 1.获取版本号 需要添加 插件 cordova plugin add https://github.com/whiteoctober ...

  9. Hammer.js分析(二)——manager.js

    “Manager”是所有识别器实例的容器,它为你设置的元素安装了交互事件监听器,并设置了触摸事件特性. manager.js中的代码会涉及到input.js和recoginzer.js中的内容,这里会 ...

随机推荐

  1. Android中的布局优化方法

    http://blog.csdn.net/rwecho/article/details/8951009 Android开发中的布局很重要吗?那是当然.一切的显示样式都是由这个布局决定的,你说能不重要吗 ...

  2. 黄聪:Wordpress 模版技术手册 - WordPress Theme Technical manuals

    WordPress基本模板文件 一套完整的WordPress模板应至少具有如下文件: style.css : CSS(样式表)文件 index.php : 主页模板 archive.php : Arc ...

  3. Linux IO调度器相关算法介绍(转)

    IO调度器(IO Scheduler)是操作系统用来决定块设备上IO操作提交顺序的方法.存在的目的有两个,一是提高IO吞吐量,二是降低IO响应时间.然而IO吞吐量和IO响应时间往往是矛盾的,为了尽量平 ...

  4. Exception error message with incorrect line number

    In Release mode the number in front of the exception is NOT the line of code. Instead it's an offset ...

  5. PLSQL_数据泵定参数批量导入多表Expdp/Impdp Parfile(案例)

    2015-04-01 Created By BaoXinjian

  6. CF 461B Appleman and Tree 树形DP

    Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...

  7. python(4) 小程序-异步加载

    注:处理异步加载需要模拟浏览器登陆,然后用import json,用loads解析 例如:

  8. 转--Android按钮单击事件的四种常用写法总结

    这篇文章主要介绍了Android按钮单击事件的四种常用写法总结,比较了常见的四种写法的优劣,有不错的参考借鉴价值,需要的朋友可以参考下     很多学习Android程序设计的人都会发现每个人对代码的 ...

  9. 转__Android Studio ,基于intellij idea

    看到论坛里一些关于Android Studio的帖子,基本上是停留在使用教程上.在此做一些功能性的分析和测评 下载地址 :http://developer.android.com/index.html ...

  10. Chrome每次打開都要打開123.sogou.com

    剛開始還以為中毒了,又是殺毒又是掃描的,最後發覺,原來就是chrome的一個設置被改了. Chrome->設置->啟動時 : 選打开特定网页或一组网页->設置網頁 , 將其中的123 ...