Ajax 完成 AutoComplete

Ajax 真的令人著迷

 

為了方便使用者的輸入, 提供了類似 Google Suggest & Gmail/Yahoo Mail 所提供的功能

讓使用者輸入一個字及可帶出相關的選項供選擇

 

其做法也是在 Page 中定義一個 <div> Tag 來供 XHttpRequest 將回傳的 responseText

加入其 innerHTML 屬性中, 再透過 Javascript 與 DOM 的操作來控制該 <div> Tag 顯示的位置

 

後端要注意的是, 輸出的 HTML (目前我還是習慣用 HTML 的方式輸出, 因為 XML 還需搭配 XSLT 來呈現

還沒學到那邊), 要能與原先的 Page 互動. (可以在主 Page 上 define 一個 JS Function 供呼叫)

 

程式片段:

 

CSS 與 DIV





 

 <style type="text/css">
 DIV{
  scrollbar-DarkShadow-Color:#9FB7D7;
  scrollbar-Track-Color:#F7F7F7;
  scrollbar-Face-Color:#C7CFFF;
  scrollbar-Shadow-Color:#FFFFFF;
  scrollbar-Highlight-Color:#FFFFFF;
  scrollbar-3dLight-Color:#C7CFF7;
  scrollbar-Arrow-Color:#4F5F87;
 }
 .autocomplete {
  background:#E0E0E0;
  position: absolute;
  border: solid 1px;
  overflow-y:scroll;
  overflow-x:auto;
  height:100px;
  display: none;
 }

</style> 
<div id="autocomplete" class="autocomplete"></div>

 

 

Script






 <script type="text/javascript">
  var oauto=new AjaxService();
  oauto.callback=autoCompleteResponse;  


  
  function autoCompleteField(cust_code) {
   event.cancelBubble=true;
    var key=window.event.keyCode;
   switch (key){
     case 9,13,27: // Tab, Enter, Esc 鍵
      return;
   }
  
   var querystring="cust_code="+encodeURI(cust_code);
   var url = "/Authority/autoComplete.jsp?"+querystring;
   oauto.loadXMLDoc(url);
   return false;
  }
   
  function autoCompleteResponse() {
   // only if req shows "loaded"
   if (oauto.xhttp.readyState == 4) {
    // only if "OK"
    if (oauto.xhttp.status == 200) {            
     $('autocomplete').innerHTML = oauto.xhttp.responseText;
     $('autocomplete').style.display="block";
     $('autocomplete').style.width=$('cust_code').offsetWidth;
     var point = fGetXY($('cust_code'));
     $('autocomplete').style.top=point.y+$('cust_code').offsetHeight+15;
     $('autocomplete').style.left=point.x+10;
    } else {
     alert(errormsg + oauto.xhttp.statusText);
    }
   }
  }    


  function Point(iX, iY){
   this.x = iX;
   this.y = iY;
  }  
  
  function fGetXY(aTag){
   var oTmp = aTag;
   var pt = new Point(0,0);
   do {
    pt.x += oTmp.offsetLeft;
    pt.y += oTmp.offsetTop;
    oTmp = oTmp.offsetParent;
   } while(oTmp.tagName!="BODY");
   return pt;
  }  
  
  function ChangeSelect(){
   event.cancelBubble=true;
    var key=window.event.keyCode;
   switch (key){
     case 9,13,27: // Tab, Enter, Esc 鍵
      $('autocomplete').style.display="none";
   }
  }
  
  function setValue(v){
    $('cust_code').value=v;
   $('autocomplete').style.display="none";
   query(1,v);
  }
 </script>


控制項






<input autocomplete="off" type="text" name="cust_code" id="cust_code" size="20" onkeyup="if (frmQuery.chkAutoComplete.checked) autoCompleteField(this.value);" onkeydown="return ChangeSelect();" /> <input type="checkbox" value="1" name="chkAutoComplete" checked="checked" />啟用自動完成


 


在控制項的 onkeyup event 中去呼叫 autoCompleteField() 與後端 autoComplete.jsp 進行 Ajax 互動


encodeURI 是為了中文碼(雙位元碼)在 XMLHTTP 傳輸中 Unicode 轉換問題


在後端的 jsp 程式需使用






String cust_code=new String(request.getParameter("cust_code").getBytes("ISO-8859-1"),"UTF8");


來讀取 QueryString 中傳遞的參數.


主頁面編碼設為






<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


這樣就不會有編碼的問題


後端 jsp 輸出






while (rs.next()){
  out.print("<a href='#' onclick='setValue(\""+rs.getString("occ01").trim()+"\")' style='cursor:default'>"+rs.getString("occ01").trim()+" ("+rs.getString("occ02").trim()+")</a><br />");
}


透過呼叫主頁面 setValue() 將選取的值回存至控制項中, 即大功告成. :)


可以將 script 的部份 define 成 .js 並修改參數的傳遞 及可當作 library 來使用囉.

張貼留言