一个ajax自动完成的例子
在项目当中,经常会有输入省市名称的要求,如果采用下拉框的形式,用户选择会很不方便,因为选项太多。这种情况下可以采用AJAX自动完成功能。 见下图:
首先看页面的标签(部分):
- <td>航段起点</td>
- <td>
- <html:hidden property="cityBegin" /> <!-- 这里存放的是实际存储的ID-->
- <html:text property="cityBeginText" onkeyup="search('cityBeginText','cityBegin','popup')"/>
- <div style="autodiv" id="popup"><table><tbody></tbody></table></div>
- </td>
search函数具体实现:
- function search(inputId,outputId,divId){
- init(inputId,outputId,divId); //初始化相关页面元素
- if ((inputField.value.length<=0)||(event.keyCode==13)){
- outputField.value="";
- return false;
- }
- var tmp= inputField.value;
- var url='autocomplete.do';
- var pars ='action=city&city=' + tmp;
- var myAjax = new Ajax.Request(
- url,
- {
- method: 'get',
- parameters: pars,
- onComplete: this.showResponse //这里是回调函数。
- }
- );
- }
在服务器端,返回的是xml格式的数据。形如:
- <response>
- <item>
- <id>1</id><value>南京市</value>
- </item>
- <item>
- <id>2</id><value>南昌市</value>
- </item>
- </response>
showResponse的任务有:解析返回的xml数据,计算div的位置,填充div。
- function showResponse(originalRequest){
- clearDiv(); //先清空。
- outputField.value="";
- var values=originalRequest.responseXML.getElementsByTagName("value");
- var ids =originalRequest.responseXML.getElementsByTagName("id");
- var size = values.length;
- setOffsets(); //计算div的位置
- var row, cell, txtNode;
- for (var i = 0; i < size; i++) { //开始填充
- var nextNode = values[i].firstChild.data;
- var nextId = ids[i].firstChild.data;
- row = document.createElement("tr");
- cell = document.createElement("td");
- cell.onmouseout = function() {this.className='mouseOver';};
- cell.onmouseover = function() {this.className='mouseOut';};
- cell.setAttribute("bgcolor", "#FFFAFA");
- cell.setAttribute("border", "0");
- var input = document.createElement("input");
- input.setAttribute("type","hidden");
- input.setAttribute("name","id");
- input.setAttribute("value",nextId);
- cell.onclick = function() { populateName(this); } ; //注意这个函数populateName
- txtNode = document.createTextNode(nextNode);
- cell.appendChild(txtNode);
- cell.appendChild(input);
- row.appendChild(cell);
- tbody.appendChild(row);
- }
- completeDiv.appendChild(table);
- }
populateName函数的作用是什么呢?当鼠标在下拉的div上选择了某一行(地区)的时候,该地区在数据库端的id被存储到隐藏的input当中,这里是“cityBegin”,该函数的代码:
- function populateName(cell){
- inputField.value = cell.firstChild.nodeValue; //value被赋给了“cityBeginText”
- outputField.value=cell.lastChild.value; //id被赋给了“cityBegin”
- clearDiv();
- }
当该页面被提交后,服务器端先检查“cityBegin”的值空否,如果不空,则不需要再根据“cityBeginText”的值查询数据库,避免了地区id的重复查询。 当然,前提条件是地区信息是用户从下拉div当中选择的。
var completeDiv;
var inputField;
var outputField;
var table;
var tbody;
function init(inputId,outputId,divId){
completeDiv=$(divId);
inputField=$(inputId);
inputField.onpaste=function(){"this.value=''"}
outputField=$(outputId);
table = completeDiv.firstChild;
tbody=table.firstChild;
completeDiv.onblur=function(){ completeDiv.style.display="none"; }
inputField.onclick=function(){ completeDiv.style.display="none"; }
}
function clearDiv(){
var ind = tbody.childNodes.length;
for (var i = ind - 1; i >= 0 ; i--) {
tbody.removeChild(tbody.childNodes[i]);
}
completeDiv.style.display="none";
}
function search(inputId,outputId,divId){
init(inputId,outputId,divId);
if ((inputField.value.length<=0)||(event.keyCode==13)){
outputField.value="";
return false;
}
var tmp= inputField.value;
var url='autocomplete.do';
var pars ='action=city&city=' + tmp;
var myAjax = new Ajax.Request(
url,
{
method: 'get',
parameters: pars,
onComplete: this.showResponse
}
);
}
function showResponse(originalRequest){
clearDiv();
outputField.value="";
var values=originalRequest.responseXML.getElementsByTagName("value");
var ids =originalRequest.responseXML.getElementsByTagName("id");
var size = values.length;
setOffsets();
var row, cell, txtNode;
for (var i = 0; i < size; i++) {
var nextNode = values[i].firstChild.data;
var nextId = ids[i].firstChild.data;
row = document.createElement("tr");
cell = document.createElement("td");
cell.onmouseout = function() {this.className='mouseOver';};
cell.onmouseover = function() {this.className='mouseOut';};
cell.setAttribute("bgcolor", "#FFFAFA");
cell.setAttribute("border", "0");
var input = document.createElement("input");
input.setAttribute("type","hidden");
input.setAttribute("name","id");
input.setAttribute("value",nextId);
cell.onclick = function() { populateName(this); } ;
txtNode = document.createTextNode(nextNode);
cell.appendChild(txtNode);
cell.appendChild(input);
row.appendChild(cell);
tbody.appendChild(row);
}
completeDiv.appendChild(table);
}
function setOffsets(){
var end = inputField.offsetWidth;
var left = calculateOffsetLeft();
var top = calculateOffsetTop() + inputField.offsetHeight;
completeDiv.style.border = "black 1px solid";
completeDiv.style.left = left + "px";
completeDiv.style.top = top + "px";
completeDiv.style.display = "";
table.style.width = end + "px";
}
function calculateOffsetLeft(){
return calculateOffset("offsetLeft");
}
function calculateOffsetTop(){
return calculateOffset("offsetTop");
}
function calculateOffset(attr){
var offset = 0;
var tmpField=inputField;
while(tmpField) {
offset += tmpField[attr];
tmpField = tmpField.offsetParent;
}
return offset;
}
function populateName(cell){
inputField.value = cell.firstChild.nodeValue;
outputField.value=cell.lastChild.value;
clearDiv();
}


浙公网安备 33010602011771号