一个ajax自动完成的例子

 

   在项目当中,经常会有输入省市名称的要求,如果采用下拉框的形式,用户选择会很不方便,因为选项太多。这种情况下可以采用AJAX自动完成功能。 见下图:

      

 首先看页面的标签(部分):

Html代码 复制代码
  1. <td>航段起点</td>  
  2.        
  3. <td>     
  4.     <html:hidden property="cityBegin" />     <!-- 这里存放的是实际存储的ID-->  
  5.     <html:text property="cityBeginText" onkeyup="search('cityBeginText','cityBegin','popup')"/>    
  6.    <div style="autodiv" id="popup"><table><tbody></tbody></table></div>                      
  7. </td>  

 search函数具体实现:

Js代码 复制代码
  1. function search(inputId,outputId,divId){   
  2.     init(inputId,outputId,divId);        //初始化相关页面元素       
  3.     if ((inputField.value.length<=0)||(event.keyCode==13)){   
  4.         outputField.value="";   
  5.         return false;   
  6.     }   
  7.     var tmp= inputField.value;   
  8.        
  9.     var url='autocomplete.do';   
  10.     var pars ='action=city&city=' + tmp;   
  11.     var myAjax = new Ajax.Request(   
  12.         url,   
  13.         {   
  14.             method: 'get',   
  15.             parameters: pars,   
  16.             onComplete: this.showResponse                  //这里是回调函数。    
  17.          }   
  18.      );   
  19. }  

  在服务器端,返回的是xml格式的数据。形如:

 

Xml代码 复制代码
  1. <response>  
  2.     <item>  
  3.          <id>1</id><value>南京市</value>  
  4.     </item>  
  5.     <item>  
  6.          <id>2</id><value>南昌市</value>  
  7.     </item>  
  8. </response>  

 

showResponse的任务有:解析返回的xml数据,计算div的位置,填充div。

 

Js代码 复制代码
  1. function showResponse(originalRequest){   
  2.     clearDiv();            //先清空。   
  3.     outputField.value="";   
  4.     var values=originalRequest.responseXML.getElementsByTagName("value");   
  5.     var ids =originalRequest.responseXML.getElementsByTagName("id");   
  6.     var size = values.length;   
  7.     setOffsets();               //计算div的位置   
  8.     var row, cell, txtNode;   
  9.     for (var i = 0; i < size; i++) {                             //开始填充   
  10.         var nextNode = values[i].firstChild.data;   
  11.         var nextId = ids[i].firstChild.data;   
  12.         row = document.createElement("tr");   
  13.         cell = document.createElement("td");   
  14.         cell.onmouseout = function() {this.className='mouseOver';};   
  15.         cell.onmouseover = function() {this.className='mouseOut';};   
  16.         cell.setAttribute("bgcolor""#FFFAFA");   
  17.         cell.setAttribute("border""0");   
  18.         var input = document.createElement("input");   
  19.         input.setAttribute("type","hidden");   
  20.         input.setAttribute("name","id");   
  21.         input.setAttribute("value",nextId);   
  22.         cell.onclick = function() { populateName(this); } ;    //注意这个函数populateName   
  23.         txtNode = document.createTextNode(nextNode);   
  24.         cell.appendChild(txtNode);   
  25.         cell.appendChild(input);   
  26.         row.appendChild(cell);   
  27.         tbody.appendChild(row);   
  28.      
  29.     }      
  30.         
  31.     completeDiv.appendChild(table);   
  32. }  

 

populateName函数的作用是什么呢?当鼠标在下拉的div上选择了某一行(地区)的时候,该地区在数据库端的id被存储到隐藏的input当中,这里是“cityBegin”,该函数的代码:

Js代码 复制代码
  1. function populateName(cell){   
  2.     inputField.value = cell.firstChild.nodeValue;    //value被赋给了“cityBeginText”   
  3.     outputField.value=cell.lastChild.value;            //id被赋给了“cityBegin”    
  4.     clearDiv();                                                                   
  5.         
  6. }  

 当该页面被提交后,服务器端先检查“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();
   
}

posted @ 2009-01-09 13:28  猪鼻驴耳  阅读(525)  评论(0)    收藏  举报