JS实现联想输入(二)
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实现联想输入(二)的更多相关文章
- JS实现联想输入(一)
这里是我们的项目中的一个使用JS实现联想输入的功能代码,在此做个小的记录并且将它分享给大家希望对园中的朋友有用! 我将分享三段都非常简单的代码,仅仅作为个人的一点小小的积累而已! 1:后台的Actio ...
- 【高德地图API】从零开始学高德JS API(二)地图控件与插件——测距、圆形编辑器、鼠标工具、地图类型切换、鹰眼鱼骨
原文:[高德地图API]从零开始学高德JS API(二)地图控件与插件——测距.圆形编辑器.鼠标工具.地图类型切换.鹰眼鱼骨 摘要:无论是控件还是插件,都是在一级API接口的基础上,进行二次开发,封装 ...
- qrcode.js 动态生成二维码
用qrcode.js动态生成二维码图片非常简单,只需要引入qrcode.js即可使用,而且可以自定义图片大小.背景色等信息. 1.jsp代码---页面头部引入qrcode.js,jquery文件可选 ...
- node.js 初学(二)—— 搭建注册/登录服务器
node.js 初学(二)—— 搭建注册/登录服务器 理论上来说,代码实现在理论和实际上是一样的.但实际上来说,他们不是 做一个最简单的用户注册登录功能 1.接口定义: 注册:/user?act=re ...
- js生成简单二维码
js文件下载地址:https://download.csdn.net/download/weixin_38296752/10554485 一.引入qrcode.js文件 <script type ...
- 进击Node.js基础(二)
一.一个牛逼闪闪的知识点Promise npm install bluebird 二.Promise实例 ball.html <!doctype> <!DOCTYPE html> ...
- js生成中文二维码
http://www.cnblogs.com/xcsn/archive/2013/08/14/3258035.html http://www.jb51.net/article/64928.htm 使用 ...
- Cordova app 检查更新 ----JS进行调用(二)
原文:Cordova app 检查更新 ----JS进行调用(二) 1.获取版本号 需要添加 插件 cordova plugin add https://github.com/whiteoctober ...
- Hammer.js分析(二)——manager.js
“Manager”是所有识别器实例的容器,它为你设置的元素安装了交互事件监听器,并设置了触摸事件特性. manager.js中的代码会涉及到input.js和recoginzer.js中的内容,这里会 ...
随机推荐
- 指定WebService访问的语言
场景: 在访问ERP发布的WebService时,由于其指定了访问语言,导致不指定访问语言时,会有部分数据丢失. 解决: 通过WSDL工具生成代理类后,再次对其中的GetWebRequest方法进行重 ...
- [系统集成] CI持续集成项目简介
一.问题的产生 公司的多个部门围绕着产品开发.测试.发布.维护,设置有不同的岗位和系统,这些岗位和系统缺少有效的整合,没有实现自动化,效率不是很高,因此就有了CI(持续集成)的项目需求. 二.解决方案 ...
- 236. Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
- C#中abstract和virtual区别
在C#的学习中,容易混淆virtual方法和abstract方法的使用,现在来讨论一下二者的区别.二者都牵涉到在派生类中与override的配合使用. 一.Virtual方法(虚方法) virtual ...
- .NET中值得体验的精妙设计
转自: http://developer.51cto.com/art/201104/255455_all.htm .NET 是 Microsoft XML Web services 平台.MEF是.N ...
- 黄聪:Wordpress 模版技术手册 - WordPress Theme Technical manuals
WordPress基本模板文件 一套完整的WordPress模板应至少具有如下文件: style.css : CSS(样式表)文件 index.php : 主页模板 archive.php : Arc ...
- MySQL运算符之 <=>
问题 : 我在看以前的一个开发者的代码时看到 WHERE p.name <=> NULL 在这个查询语句中 <=>符号是什么意思啊?是不是和 =号是一样啊?还是一个语法错误啊? ...
- R %operator% 含义
%foo% is the syntax for a binary operator. In base R: %in%: '"%in%" <- function(x, tabl ...
- 8 个 Git 的小技巧
git 已经成为了我日常必备工具之一,我总结我几乎每天使用的8个有用(且简洁)的git技巧. 使用-p选择性添加 当你想提交内容时,你可以通过使用 git commit -am 来选择所有文件或使 ...
- [InnoSetup]Inno Setup软件打包脚本
脚本由 Inno Setup 脚本向导 生成! ; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档! #define MyAppName "SFT期货交易系统&quo ...