随笔 - 0  文章 - 0  trackbacks - 0
<2025年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

留言簿

文章档案

搜索

  •  

最新评论

Ajax 实现查询助手( Query Helper

1       概述

1.1    查询助手功能介绍

在通常的 BS 软件项目中,查询助手使用频率非常高,其功能是点击图标,页面上元素的值为条件,到后台查询结果,弹出查询结果对话框,选择纪录,关闭对话框,并且把你选择的有关内容显示到父页面中指定的元素中。由于其友好的界面设计和操作性能,对用户和设计开发人员都有很大的吸引力,但存在开发效率低,复用性差,复杂度较高等问题。

1.2    Ajax 现状和项目实践

随着 Ajax 的风靡全球, Google 的推波助澜,优秀的界面风格,局部刷新的全新感受,给人耳目一新的印象。但由于 Ajax 诸多 javascript 脚本和后台应用的复杂性,使 ajax 的推广困难重重,国内的应用大多都是玩具级,距项目实用还有不小的差距,包括 Microsoft IBM SUN 都在积极攻关研发,以提高项目开发的实用性,降低开发难度。为了使用 ajax 在项目的实用性,针对查询助手功能的 Ajax 做了一些有益的尝试,特别愿意和大家分享。

1.3    Ajax 简介

网上关于 Ajax 的文章汗牛充栋,具体的 Ajax 理论可以到网上搜索,这儿只做简单介绍:

Ajax Asynchronous JavaScript and XML 的缩写。 Ajax 并不是一门新的语言或技术 , 它实际上是几项技术按一定的方式组合在一在同共的协作中发挥各自的作用,它包括:

Ø          使用 XHTML CSS 标准化呈现

Ø          使用 DOM 实现动态显示和交互

Ø          使用 XML XSLT 进行数据交换与处理

Ø          使用 XMLHttpRequest 进行异步数据读取 ;

Ø          使用 JavaScript 绑定和处理所有数据

Ajax 的工作原理相当于在用户和服务器之间加了 个中间层 , 使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器 , 些数据验证和数据处理等都交给 Ajax 引擎自己来做 , 只有确定需要从服务器读取新数据时再由 Ajax 引擎代为向服务器提交请求。

 

 

2       Ajax 查询助手功能设计理念

查询助手功能设计的的 Ajax 的设计主要集中在从前台的 jsp 页面提出 Ajax 请求,所有的 Ajax 请求都提交给查询助手中间层,查询助手中间层自动创建查询助手具体实现类来实现查询助手的具体查询功能,查询助手具体实现类实现数据库查询并组织传回前台数据文本。传到前台后自动选择不同的 JavaScript 函数来解析数据,并显示到页面的 Div 或者直接显示到页面元素中。

2.1    Ajax 实现查询助手功能示意图如下:

3       Ajax 实现详述

3.1    Jsp 前台

Jsp 中,点击查询助手图标,或者在输入框中打回车键,则显示如图 3-1 界面, Ajax 从后台获取数据显示在前台页面上方,但此时页面并未刷新,并且缺省单选按钮选中第一行,第一行背景色为绿色。有两种操作可以选择:

 

1)   选择是使用上下方向键来选择纪录,上下键移动时纪录背景色自动改变,单选按钮也自动选择。当决定选择某一行纪录时,点击回车键。

2)   选择使用鼠标,当鼠标移动时,纪录的背景色发生改变。

3)   当点击回车键,或者点击鼠标左键时则相关内容填充到具体的页面元素中,并把输入焦点自动下移到指定的输入框,并关闭选择界面。

4)   如果你不想选择,也可以直接点击选择界面右上角的关闭图标

3-1

如果查询结果为没有纪录,则:

 

3-2

具体代码如下:

3.1.1    引入 js css 文件

<link rel="stylesheet" href="<%=request.getContextPath()%>/tplife/css/maginfier.css" type="text/css">

<script type="text/javascript" src="<%=request.getContextPath()%>/js/ajax/maginfier.js"></script>

 

组织机构查询助手: <br/><img src = "<%=request.getContextPath()%>/images/magifiericon.gif" onclick="orgMaginfier('<%=request.getContextPath()%>','selOrg','DivShim','orgId,orgCode,orgName','0,2,1','message','','');">

    <input type="text" id = "orgCode" style="width:300px" onkeydown="if(event.keyCode == 13){orgMaginfier('<%=request.getContextPath()%>','selOrg','DivShim','orgId,orgCode,orgName','0,2,1','message'); gnIsSelectCtrl = 1;}else{}">

    <input type="text" id = "orgName" style="width:300px">

    <input type="hidden" id = "orgId">

   

    <br/>        

      <div id="selOrg"  style="display:none; z-index:100" class="termFrame" ></div>   

       <iframe

        id="DivShim"

        src="javascript:false;"

        scrolling="no"

        frameborder="0"

        style="position:absolute; top:0px; left:0px; display:none;">

       </iframe> 

3.1.1.1       Js 文件内容:

var xmlHttp;
var maginfierName ;
var displayName ;//显示结果Div
var displayIFrame;//显示结果IFrame
var posNames ;//回填页面元素数组,如currencyId,currencyAbbrName,currencyName
var valueIndexs;//回填所需值的列号,如0,1,2
var nextPos;   //回填后focus的元素名
var serverPath;
var maginfierFunction;
var tableHead = new Array();


function createXMLHttpRequest() {
  
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
   
}
function keyDowm(obj, pos, value, maginfierName0, maginfierDisplayName, maginfierDisplayIFrame)
{
  if(event.keyCode == 13)//回车键
  {
     filled(pos, value, maginfierDisplayName, maginfierDisplayIFrame);
  }
  else if(event.keyCode == 40)//上移键
  {    
    document.getElementById(maginfierName0+"divrow" + obj).bgColor=''; 
   
    var t = eval(obj) + 1;
    if(document.getElementById(maginfierName0+"divrow" + t) != null)
    {
        document.getElementById(maginfierName0+"divrow" + t).bgColor='#CCFF99';
    }   
   
  }
  else if(event.keyCode == 38)//下移键
  {
    document.getElementById(maginfierName0+"divrow" + obj).bgColor='';  
    var t = eval(obj) - 1;
    if(t >= 0)
    {
       document.getElementById(maginfierName0+"divrow" + t).bgColor='#CCFF99';
    }
  }

}
function closeDiv(maginfierDisplayName, maginfierDisplayIFrame)
{
    _termFrame=getElement(maginfierDisplayName);
    _termFrame.style.display = 'none'   
   getElement(maginfierDisplayIFrame).style.display = 'none';
}
function operationRequest(queryString, postBlock) {  
   
    var url = serverPath + "/AjaxMaginfier?" +  queryString;
   
    createXMLHttpRequest();
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open("POST", url, true);    
  //    postBlock = "获得界面元素";
  //设置大块数据传输postBlock,这样可以解决大数据量传向后台。
    xmlHttp.send(postBlock);
}
// 获得界面元素
function getElement(idString)
{
 return(document.all?document.all[idString]:document.getElementById(idString));
}
// 鼠标移动
function rollover(tdObject)
{
 tdObject.bgColor='#CCFF99';
}
function rollout(tdObject)
{
 tdObject.bgColor='';
}

function filled(keyStr, valueStr, maginfierDisplayName, maginfierDisplayIFrame)

   keys = keyStr.split(",");
   values = valueStr.split("<c>");
  
   for(i = 0; i < keys.length; i++)
   {
     
      _test = getElement(keys[i]);
      _test.value = values[i];
   }     
   _termFrame=getElement(maginfierDisplayName);
   _termFrame.style.display = 'none'   
   getElement(maginfierDisplayIFrame).style.display = 'none';
   if(document.getElementById(nextPos) != null)
   {   
      document.getElementById(nextPos).focus();
   }
}

function responseDisplay() {      
    var responseText = xmlHttp.responseText;
    var responseContent = responseText.split("|");
    var dataText = responseContent[0];
   if(dataText.length == 0)
   {
       var displayStr =  '<table width="98%"><tr><td align="right" style="border-bottom:0px"><img src = "/fs/graphics/closeMaginfier.jpg" onclick="closeDiv(\''+displayName+'\',\''+displayIFrame+'\')"></td></tr></table><input type="radio" id="'+maginfierName+'rdoAlert" name="rdo"  onkeydown=" closeDiv(\''+displayName+'\',\''+displayIFrame+'\')">' + '<font class="sfont" color="red">没有符合条件的记录,点任意键返回</font>';
       displayAlert(displayStr);
       return;
   }
    var rows = dataText.split("<r>");   
    var _t=[];   
    var cols;
    var pos = "\'" + posNames + "\'";   
   
    for(var i = 0; i < rows.length; i++) {
        cols = rows[i].split("<c>");      
        values = "\'" ;
        valuesIndexArray = valueIndexs.split(",");
        for( j = 0; j < valuesIndexArray.length; j++)
        {
            var temp = cols[eval(valuesIndexArray[j])];
            //回填时把null置换成空字符串
            if(temp == 'null')
            {
                temp = '';
            }
            if(j < valuesIndexArray.length - 1)
            {
                values = values + temp + "<c>";
            }
            else
           {
               values = values + temp + "\'";
           }
        } 
       
        if(i == 0)
        {
           _t[i] = '<tr  class="maginfierBody" id = "'+maginfierName+'divrow0" onmouseover="rollover(this)" onmouseout="rollout(this)" ><td width="5"  align="center"><input type="radio" id="'+maginfierName+'rdo" name="rdo"  onkeydown=" keyDowm('+i+', '+pos+', '+values+',\''+maginfierName+'\',\''+displayName+'\',\''+displayIFrame+'\');" ></td>';
        }
        else
        {
            _t[i] = '<tr class="maginfierBody" id = "'+maginfierName+'divrow'+i+'" onmouseover="rollover(this)" onmouseout="rollout(this)"  ><td width="5"  align="center"><input type="radio" name="rdo"  onkeydown=" keyDowm('+i+', '+pos+', '+values+',\''+maginfierName+'\',\''+displayName+'\',\''+displayIFrame+'\');" ></td>';
        }
        //根据表头显示相关数据    
        for(var j = 1 ; j < tableHead.length ; j++)
        {
            //在放大镜表格显示时,把null置换成空格显示
            if(cols[j] == 'null')
            {
                cols[j] = "&nbsp;";
            }
            _t[i] = _t[i] + '<td  onclick="filled('+pos+', '+values+',\''+displayName+'\',\''+displayIFrame+'\')"><span class="rs">'+cols[j]+'</span></td>';
        }
        _t[i] = _t[i] + '</tr>';
       
    } 
    
     var tableHeadStr = addMaginfierHeader();
    
    displayStr =  '<table width="98%"><tr><td align="right" style="border-bottom:0px"><img src = "/fs/graphics/closeMaginfier.jpg" onclick="closeDiv(\''+displayName+'\',\''+displayIFrame+'\')"></td></tr></table><table cellspacing="1" width="98%" cellpadding="1" class="ItemList">'+ tableHeadStr +_t.join('')+'</table> ';
    if(responseContent[1] != null)
    {
        pageParams = responseContent[1].split(",");
        prePageNo = parseInt(pageParams[2]) - 1;
        prePageFunction = maginfierFunction + "," +prePageNo+")";
        nextPageNo = parseInt(pageParams[2]) + 1;
        nextPageFunction = maginfierFunction + ", "+nextPageNo+")";
       
        displayStr += '<br> <a href="javascript:if('+prePageNo+' == 0){alert(\'已经是第一页了\');}else{'+prePageFunction+'} ">上一页</a>';
        displayStr += '<font class="sfont"> | 第'+pageParams[2]+'页 | </font> ';
        displayStr += '<a href="javascript:if('+nextPageNo+' > '+pageParams[1]+'){alert(\'已经是最后一页了\'); }else{'+nextPageFunction+'}">下一页</a>';
        displayStr += '<font class="sfont"> | 共'+pageParams[1]+'页 | 共'+pageParams[0]+'行</font>';      
    }
  
    displayMaginfier(displayStr);
 
}
function test()
{
    var a = '23,,,43,23';
    var b = a.split(",");
    alert(b.length);
}
function addMaginfierHeader()
{
    var tableHeadStr = '<tr class="maginfierTitle"><td width="5"  align="center" ></td>';
    for(i = 1 ; i < tableHead.length ; i++)
    {
        tableHeadStr = tableHeadStr + '<td align="center" >' + tableHead[i] + "</td>"
    }
    tableHeadStr = tableHeadStr + "</tr>";
    return tableHeadStr;
}
function displayAlert(displayStr)
{
    displayDiv = getElement(displayName);   
 displayDiv.innerHTML = displayStr; 
 displayDiv.style.display='block';  
 
    IfrRef = getElement(displayIFrame);
 IfrRef.style.width = displayDiv.offsetWidth;
    IfrRef.style.height = displayDiv.offsetHeight;
    IfrRef.style.top = displayDiv.style.top;
    IfrRef.style.left = displayDiv.style.left;
    IfrRef.style.zIndex = displayDiv.style.zIndex - 1;
    IfrRef.style.display = "block";
 
 document.getElementById(maginfierName+"rdoAlert").checked = true; 
 document.getElementById(maginfierName+"rdoAlert").focus(); 
}
function displayMaginfier(displayStr)
{
    displayDiv = getElement(displayName);   
 displayDiv.innerHTML = displayStr; 
 displayDiv.style.display='block'; 
 
 
    IfrRef = getElement(displayIFrame);
 IfrRef.style.width = displayDiv.offsetWidth;
    IfrRef.style.height = displayDiv.offsetHeight;
    IfrRef.style.top = displayDiv.style.top;
    IfrRef.style.left = displayDiv.style.left;
    IfrRef.style.zIndex = displayDiv.style.zIndex - 1;
    IfrRef.style.display = "block";
 
 document.getElementById(maginfierName+"divrow0").bgColor='#CCFF99';
 document.getElementById(maginfierName+"rdo").checked = true; 
 document.getElementById(maginfierName+"rdo").focus();
}

/*具体放大镜页面处理方法*/
function handleStateChange() {   
    if(xmlHttp.readyState == 4) {
        if(xmlHttp.status == 200) {          
           responseDisplay();          
        }
    }
}
function initMaginfierParas(serverPath0, divName, iFrameName, posNames0, valueIndexs0, nextPos0)
{
    serverPath = serverPath0; 
    displayName = divName;
    displayIFrame = iFrameName;
    posNames = posNames0;
    valueIndexs = valueIndexs0
    nextPos = nextPos0;
}

/*具体放大镜JavaScript*/

//组织机构放大镜
function orgMaginfier(serverPath0, divName, iFrameName, posNames0,valueIndexs0, nextPos0, orgCode, orgId, transTypeId, maginfierType, pageNo)
{   
 initMaginfierParas(serverPath0, divName, iFrameName, posNames0, valueIndexs0, nextPos0);
 maginfierName = 'OrgMaginfier' + divName; 
 maginfierFunction = "orgMaginfier(\'"+serverPath0+"\', \'"+divName+"\', \'"+iFrameName+"\', \'"+posNames0+"\',\'"+valueIndexs0+"\', \'"+nextPos0+"\', \'"+orgCode+"\', \'"+orgId+"\', \'"+transTypeId+"\', \'"+maginfierType+"\'";
   
    len = tableHead.length;
    tableHead.splice(0, len);
    tableHead[0] = "单位ID";
    tableHead[1] = "单位编号";
    tableHead[2] = "单位名称";      
    tableHead[3] = "单位英文名称";
   
    queryString = "maginfierClassName=OrgMaginfier&orgCode="+orgCode+"&orgId="+orgId+"&maginfierType="+maginfierType+"&transTypeId="+transTypeId+"&pageNo="+pageNo;
   
  operationRequest(queryString);
}

 

3.1.1.2       Css 文件内容:

 

/* 界面样式 */

.termFrame{

       width:298px !important;

       width:500px;

       overflow:auto;

       height:360px;

       scrollbar-face-color: #FFFFCC; scrollbar-shadow-color: #FFFFCC; scrollbar-highlight-color: #FFFFCC; scrollbar-3dlight-color: #FFFFCC;  scrollbar-darkshadow-color: #6699CC; scrollbar-track-color: #FFFFCC; scrollbar-arrow-color: #99CCFF;

   

       margin-top:1px !important;

       margin-top:0; 

       border:1px solid #999999;

       background-color:#FFFFFF;

       position:absolute;

       cursor:hand;

       padding:2px;

       font-size:70%;

       z-index:100

       }

       .maginfierTitle {

 BORDER-RIGHT: 1px; BORDER-TOP: 1px;BORDER-LEFT: 1px; BORDER-BOTTOM: 1px;BACKGROUND-COLOR: #456795; color: #FFFFFF;

}

       .maginfierBody {

        BORDER-RIGHT: 1px;BORDER-TOP: 1px;BORDER-LEFT: 1px;BORDER-BOTTOM: 1px;

}

3.1.2    当点击查询助手图标时(例如查询组织机构):

function orgMaginfier(serverPath0, divName, iFrameName, posNames0,valueIndexs0, nextPos0, orgCode, orgId, transTypeId, maginfierType, pageNo)

{   

       initMaginfierParas(serverPath0, divName, iFrameName, posNames0, valueIndexs0, nextPos0);

       maginfierName = 'OrgMaginfier' + divName;      

       maginfierFunction = "orgMaginfier(\'"+serverPath0+"\', \'"+divName+"\', \'"+iFrameName+"\', \'"+posNames0+"\',\'"+valueIndexs0+"\', \'"+nextPos0+"\', \'"+orgCode+"\', \'"+orgId+"\', \'"+transTypeId+"\', \'"+maginfierType+"\'";

   

    len = tableHead.length;

    tableHead.splice(0, len);

    tableHead[0] = " 单位 ID";

    tableHead[1] = " 单位编号 ";

    tableHead[2] = " 单位名称 ";      

    tableHead[3] = " 单位英文名称 ";

   

    queryString = "maginfierClassName=OrgMaginfier&orgCode="+orgCode+"&orgId="+orgId+"&maginfierType="+maginfierType+"&transTypeId="+transTypeId+"&pageNo="+pageNo;

   

  operationRequest(queryString);

}

3.1.3    Js 中的处理请求的函数

function operationRequest(queryString, postBlock) {  

   

    var url = serverPath + "/AjaxMaginfier?" +  queryString;

   

    createXMLHttpRequest();

    xmlHttp.onreadystatechange = handleStateChange;

    xmlHttp.open("POST", url, true);    

  //    postBlock = " 获得界面元素 ";

  // 设置大块数据传输 postBlock ,这样可以解决大数据量传向后台。

    xmlHttp.send(postBlock);

}

3.1.4    当数据传回前台后

// 该函数的名称不要改变,因为我在 js 文件中决定了用该函数来处理传回的数据

function handleStateChange() {   

    if(xmlHttp.readyState == 4) {

        if(xmlHttp.status == 200) {          

           responseDisplay();          

        }

    }

}

3.1.5    具体处理传回的数据:

function responseDisplay() {      

    var responseText = xmlHttp.responseText;

    var responseContent = responseText.split("|");

    var dataText = responseContent[0];

   if(dataText.length == 0)

   {

       var displayStr = rightSpace + '<img src = "/fs/graphics/closeMaginfier.jpg" onclick="closeDiv(\''+displayName+'\',\''+displayIFrame+'\')"><br><input type="radio" id="'+maginfierName+'rdoAlert" name="rdo"  onkeydown=" closeDiv(\''+displayName+'\',\''+displayIFrame+'\')">' + '<font class="sfont" color="red"> 没有符合条件的记录,点任意键返回 </font>';

       displayAlert(displayStr);

       return;

   }

    var rows = dataText.split(";");   

    var _t=[];   

    var cols;

    var pos = "\'" + posNames + "\'";   

   

    for(var i = 0; i < rows.length; i++) {

        cols = rows[i].split(",");      

        values = "\'" ;

        valuesIndexArray = valueIndexs.split(",");

        for( j = 0; j < valuesIndexArray.length; j++)

        {

            var temp = cols[eval(valuesIndexArray[j])];

            // 回填时把 null 置换成空字符串

            if(temp == 'null')

            {

                temp = '';

            }

            if(j < valuesIndexArray.length - 1)

            {

                values = values + temp + ",";

            }

            else

           {

               values = values + temp + "\'";

           }

        } 

       

        if(i == 0)

        {

           _t[i] = '<tr  class="maginfierBody" id = "'+maginfierName+'divrow0" onmouseover="rollover(this)" onmouseout="rollout(this)" ><td width="5"  align="center"><input type="radio" id="'+maginfierName+'rdo" name="rdo"  onkeydown=" keyDowm('+i+', '+pos+', '+values+',\''+maginfierName+'\',\''+displayName+'\',\''+displayIFrame+'\');" ></td>';

        }

        else

        {

            _t[i] = '<tr class="maginfierBody" id = "'+maginfierName+'divrow'+i+'" onmouseover="rollover(this)" onmouseout="rollout(this)"  ><td width="5"  align="center"><input type="radio" name="rdo"  onkeydown=" keyDowm('+i+', '+pos+', '+values+',\''+maginfierName+'\',\''+displayName+'\',\''+displayIFrame+'\');" ></td>';

        }

        // 根据表头显示相关数据     

        for(var j = 0 ; j < tableHead.length ; j++)

        {

            // 在查询助手表格显示时,把 null 置换成空格显示

            if(cols[j] == 'null')

            {

                cols[j] = "&nbsp;";

            }

            _t[i] = _t[i] + '<td  onclick="filled('+pos+', '+values+',\''+displayName+'\',\''+displayIFrame+'\')"><span class="rs">'+cols[j]+'</span></td>';

        }

        _t[i] = _t[i] + '</tr>';

       

    } // 显示表头内容

function addMaginfierHeader()

{

    var tableHeadStr = '<tr class="maginfierTitle"><td width="5"  align="center" ></td>';

    for(i = 0 ; i < tableHead.length ; i++)

    {

        tableHeadStr = tableHeadStr + '<td align="center" >' + tableHead[i] + "</td>"

    }

    tableHeadStr = tableHeadStr + "</tr>";

    return tableHeadStr;

}

// 如果未查询到纪录,显示提示信息

function displayAlert(displayStr)

{

    _termFrame=getElement(displayName);

   

       _termFrame.innerHTML = displayStr;

       // 显示结果

      

       _termFrame.style.display='block';

      

       IfrRef = getElement(displayIFrame);

       IfrRef.style.width = _termFrame.offsetWidth;

    IfrRef.style.height = _termFrame.offsetHeight;

    IfrRef.style.top = _termFrame.style.top;

    IfrRef.style.left = _termFrame.style.left;

    IfrRef.style.zIndex = _termFrame.style.zIndex - 1;

    IfrRef.style.display = "block";

      

       document.getElementById(maginfierName+"rdoAlert").checked = true;

      

       document.getElementById(maginfierName+"rdoAlert").focus();

      

}

// 显示查询助手

function displayMaginfier(displayStr)

{

    _termFrame=getElement(displayName);

   

       _termFrame.innerHTML = displayStr;

       // 显示结果

       _termFrame.style.display='block';

       //setHidden(overlaySelEles);

       //_termFrame.style.visibility="visible";

       IfrRef = getElement(displayIFrame);

       IfrRef.style.width = _termFrame.offsetWidth;

    IfrRef.style.height = _termFrame.offsetHeight;

    IfrRef.style.top = _termFrame.style.top;

    IfrRef.style.left = _termFrame.style.left;

    IfrRef.style.zIndex = _termFrame.style.zIndex - 1;

    IfrRef.style.display = "block";

      

       document.getElementById(maginfierName+"divrow0").bgColor='#CCFF99';

       document.getElementById(maginfierName+"rdo").checked = true;

      

       document.getElementById(maginfierName+"rdo").focus();

}

3.2    Servlet 后台

选择 Servlet 作为后台,是因为如果采用 Struts Action 为后台处理程序,则必须指定要返回的页面。而使用 Servlet 则没有这个要求。默认返回到请求页面。而这个查询助手 Servlet 接受所有的查询助手请求,根据前台传来的查询助手实现类名称参数,由 Spring 创建查询助手实现类对象,该对象实现了查询助手接口( MaginfierInterface ),从而获取返回值文本。返回到前台。

3.2.1    具体代码如下:

3.2.1.1       查询助手 Servlet

public void doGet(HttpServletRequest request, HttpServletResponse response)

                     throws ServletException, IOException {

              String maginfierClassName = request.getParameter("maginfierClassName");           

              MaginfierFactory factory = MaginfierFactory.getInstance();

              MaginfierInterface maginfier = factory.createMaginfier(maginfierClassName);

        String ret =  maginfier.getReturnValue(request);

        System.out.println("ret = " + ret);

              response.setContentType("text/xml;charset=GBK");

              PrintWriter out = response.getWriter();

                           

              out.write(ret);

             

              out.close();

       }

3.2.1.2       Web.xml 配置

3.2.1.2.1       在Web.xml中配置查询助手 Servlet

<servlet>

        <servlet-name>AjaxMaginfier</servlet-name>

        <servlet-class>com.iss.fs.web.module.example.AjaxMaginfier</servlet-class>

        <!— 在系统初次启动时,初始化 1 -->       

        <load-on-startup>1</load-on-startup>

 </servlet>

<servlet-mapping>

        <servlet-name>AjaxMaginfier</servlet-name>

        <url-pattern>/AjaxMaginfier</url-pattern>

 </servlet-mapping>

3.2.1.3       查询助手具体实现类

3.2.1.3.1       实现查询助手接口方法

public class CurrencyMaginfier implements MaginfierInterface

{

       public String getReturnValue(HttpServletRequest request)

       {

              List list = null;

              StringBuffer results = new StringBuffer();

              CurrencyDAO dao = new CurrencyDAO();

              String currencyAbbrName = request.getParameter("currencyAbbrName");

              String responsibilityId = request.getParameter("responsibilityId");

              if(currencyAbbrName == null || currencyAbbrName.equals("") || currencyAbbrName.equals("undefined"))

              {

                     currencyAbbrName = "";

              }

              if(responsibilityId == null || responsibilityId.equals("") || responsibilityId.equals("undefined"))

              {

                     responsibilityId = "-1";

              }

              try

              {

                     list = dao.getMaginfierResults(currencyAbbrName, responsibilityId);

                    

              }

              catch (Exception ex)

              {

                     ex.printStackTrace();

              }

              if (list != null)

              {

                     Currency currency = null;                  

                     for(int i = 0 ; i < list.size(); i++)

                     {

                            currency = (Currency)list.get(i);

                            results.append(currency.getID()).append(",");

                            results.append(currency.getCurrencyAbbrName()).append(",");

                            results.append(currency.getCurrencyName());                         

                            if(i < (list.size() - 1))

                            {

                                   results.append(";");

                            }

                     }

              }

              return results.toString();

       }

}

3.3    技术难点解析

3.3.1    查询助手函数参数设计:

固定参数: serverPath, divName, iFrameName, posNames,valueIndexs, nextPos

serverPath :表示 webserver 的地址,如: /myapp

divName :显示选择界面的 Div 名称

iFrameName :显示选择界面的 Ifranme 名称,因为 IE 的缺陷, div 显示时不能覆盖下面的选择框,所以我们使用 Iframe 作为 div 的底板。

posNames :选择纪录后回显的页面元素,如: orgId,orgName,orgCode

valueIndexs :对应回显页面元素,纪录的列序号,如 0,2,1

nextPos :选择结束后要把输入焦点,移动到下一个页面元素名称

固定参数后面的参数,不同的查询助手有不同参数列表,主要是条件数据。

3.3.2    查询助手选择界面的表头设计:

不同的查询助手选择界面有不同的表头,我们使用 js 的全局数组变量来存储,每个查询助手使用前都先清空表头数组,使用 splice(0, len)

len = tableHead.length;

    tableHead.splice(0, len);   

    tableHead[0] = " 外部账户 ID";

    tableHead[1] = " 外部账户编号 ";

    tableHead[2] = " 外部账户名称 ";

    tableHead[3] = " 外部银行名称 ";

    tableHead[4] = " 机构号 ";

    tableHead[5] = " 联行号 ";

显示表头:

var tableHeadStr = '<tr class="maginfierTitle"><td width="5"  align="center" ></td>';

    for(i = 0 ; i < tableHead.length ; i++)

    {

        tableHeadStr = tableHeadStr + '<td align="center" >' + tableHead[i] + "</td>"

    }

tableHeadStr = tableHeadStr + "</tr>";

3.3.3    处理后台传来的数据:

3.3.3.1.1       接受数据:

var responseText = xmlHttp.responseText;

3.3.3.1.2       查询无纪录处理:

if(responseText.length == 0)

   {

       var displayStr = rightSpace + '<img src = "/fs/graphics/closeMaginfier.jpg" onclick="closeDiv()"><br><input type="radio" id="'+maginfierName+'rdoAlert" name="rdo"  onkeydown=" closeDiv()">' + '<font class="sfont" color="red"> 没有符合条件的记录,点任意键返回 </font>';

       displayAlert(displayStr);

       return;

   }

Onkeydown 表示响应任意键,则关闭查询助手选择界面。

Onclick 表示响应鼠标点击

3.3.3.1.3       显示查询结果:

因为我们在后台把查询数据封装成文本传回前台,所以到前台后要解析文本,我不使用 xml 文本,数据封装规则是纪录间用“;”隔离,列之间用“,”隔离。同样到前台后使用相同的规则解析数据。

把文本数据分成若干行数据

var rows = responseText.split(";");

3.4    总结

Ajax 实现查询助手功能是 Ajax 在项目中实战的一个小小的例子,根据以后的研发,将会产生更多更好的应用,本人在文档的 Ajax 简介部分引用了别的文档的说明,在查询助手的实现中借鉴了 Google Suggest 设计理念, Suggest 实现是直接从后台传来表格 Frame ,后台定义显示逻辑,在查询助手的设计中,前台来决定显示逻辑,后台仅提供数据,实现数据和显示的分离,这样就会造成前台需要解析数据文本,处理显示逻辑的 Javascript 函数,显得前台的 JavaScript 比较多,但我认为这是可以接受的,因为 Ajax 主要是前台逻辑。另外, Ajax 查询助手的后台实现采用了 Spring Bean 管理容器,只是为了后期扩展的方便性,借助 Spring 容器管理的强大功能,实现类似工厂模式的功能。

  努力,在于我热爱我的事业,与中国的软件一起走向成熟,走向世界。

 

 

 

 

 

 

 

 

 

 

联系作者: lijj_72@hotmail.com

posted on 2006-06-11 16:31 lijj 阅读(371) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: