godtrue

这里是我们的项目中的一个使用JS实现联想输入的功能代码,在此做个小的记录并且将它分享给大家希望对园中的朋友有用!

我将分享三段都非常简单的代码,仅仅作为个人的一点小小的积累而已!

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

    /**
     * @说明:这是一段伪码,主要想说明从后台返回的数据是JSON格式的,并且形如:[{"linkDataProperty":xxx1},{"linkDataProperty":xxx2},{"linkDataProperty":xxx3}]
     * @author godtrue
     * @修改时间:2014-02-23
     * @param
     * @return
     */
    public void getLinkDataList(){
linkData.setLinkDataProperty(linkDataProperty); 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("{\"linkDataProperty\":\"").append(linkDataList.get(i).getLinkDataProperty()).append("\"},"); } stringBuffer.append("{\"linkDataProperty\":\"").append(linkDataList.get(linkDataList.size()-1).getLinkDataProperty()).append("\"}]"); renderJson(ServletActionContext.getResponse(),stringBuffer.toString()); }else{ renderJson(ServletActionContext.getResponse(),"[]"); } }
renderJson方法的源码:
    /** 
     * 直接输出纯JSON 
     */ 
    public void renderJson(HttpServletResponse response, String text) { 
    	PrintWriter out = null;
    	response.setContentType("html/txt");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache, must-revalidate");
		response.setHeader("Pragma", "no-cache");
		try {
			out = response.getWriter(); 
			out.write(text);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			 if (out != null) { 
				 out.flush(); 
	             out.close(); 
	             out = null; 
	          } 
		}
    }
说明:假设上面的代码中LinkData是一个对象其中他有一个属性是linkDataProperty(在此Aciton对象中有linkData和linkDataProperty的声明和对应的SET/GET方法,所以们的值在前后台能相互的传送),linkDataService是业务层的一个接口对象,它调用对应的方法获得对应的模糊查询的数据结果集linkDataList,然后将结果集中的数据封装成单列结构的JSON格式的数据形如:[{"linkDataProperty":xxx1},{"linkDataProperty":xxx2},{"linkDataProperty":xxx3}]

2:前台JSP中的HTML代码,这段代码主要是展示HTML输入框和为联想输入的下拉选项列表做支撑的
                 <td><input style="width:100%;" id="linkDataProperty" name="linkData.linkDataProperty" type="text" 
onkeyup
="getLinkData();" /> <div id="popup" style="position: absolute;"> <table width="100%" bgcolor="#fffafa"> <tbody id="popupBody"></tbody> </table> </div> </td>:

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

            function getLinkData() {
                var popupDiv = document.getElementById("popup");//获得对应的div对象
                var popupBody = document.getElementById("popupBody");//获得对应的tbody对象
                var linkDataProperty = document.getElementById("linkDataProperty"); //获得对应的输入框对象
                clearModels();//清除联想输入提示框的内容
                //利用ajax获取后台的模糊查询的数据,并且封装成下拉列表的形式展现出来
                $.ajax({
                    type : "post",//提交的方法为post
                    url : "getLinkDataList.action",//对应的Action提交的路径
data:{linkDataProperty:linkDataProperty.value},//从前台传递到后台的查询语句的参数 dataType : "json", //从Action中返回的数据的类型为json类型的 error:function(){ alert("没有对应的数据,请查看输入的查询条件!"); }, success : function(data) {//当Ajax提交成功时调用的方法 if(data.length==0){return;} setOffsets();//设置联想输入下拉列表提示框的位置 var tr,td,text; for (var i = 0; i < data.length; i++) {//根据返回的值,手动的拼tbody的内容 text = document.createTextNode(data[i].linkDataProperty);//从Action中返回的数据中取出linkDataProperty的值 td = document.createElement("td");//创建一个td的对象 tr = document.createElement("tr");//创建一个tr的对象 td.mouseOver = function(){this.className="mouseOver;"}; td.mouseOut = function(){this.className="mouseOut;"}; td.onclick = function(){populateModel(this)};//单击td是的方法为populateModel td.appendChild(text); tr.appendChild(td); popupBody.appendChild(tr); } }}); //点击下拉列表中的某个选项时调用的方法 function populateModel(cell) { clearSelect(); linkDataProperty.value = cell.firstChild.nodeValue; //initOtherData(linkDataProperty.value);利用输入框中的数据调用其他方法,初始化其他数据 clearModels();//清除自动完成行 } //清除自动完成行,只要tbody有子节点就删除掉,并且将将外围的div的边框属性设置为不可见的 function clearModels() { while (popupBody.childNodes.length > 0) { popupBody.removeChild(popupBody.firstChild); } popupDiv.style.border = "none"; } //设置下拉列表的位置和样式 function setOffsets() { var width = linkDataProperty.offsetWidth;//获取linkDataProperty输入框的相对宽度 var left = getLeft(linkDataProperty); var top = getTop(linkDataProperty) + linkDataProperty.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 linkDataProperty=document.getElementById(linkDataProperty);
linkDataProperty.value="";
}

 注:此方法对于单列结构的集合是适用的,可以展示比较好的联想输入的效果,并且更可以利用选中的输入框中的数据再去调用其他的方法来处理其他的数据,特别是再次的调用其他的ajax方法,再从后台获取数据来做其他的数据处理的时候尤显的此方法灵活好用!(常常利用输入框中的数据去后台查询出一条记录,所以它多适用于输入框中的数据能唯一标示出一条记录的情景下)

posted on 2014-02-23 18:17  godtrue  阅读(13479)  评论(4编辑  收藏  举报