Ajax无刷新联动之XML

先讲一下本问的意思,就是用Ajax简单做一个二级联动,从数据库读取数据,转换成XML格式输入,然后Ajax接收实现无刷联动效果...

 

先看一下前台页面的JS代码:(为了方便Copy,代码中的行号取消了).

 

1. CreateXMLObj无可非议是创建xmlHttpRequest对象的,网上一搜一大堆,这个可以根据自己的习惯来写...

function CreateXMLObj()
{
    
try {
      xmlHttp 
= new ActiveXObject("Msxml2.XMLHTTP");
    } 
catch (e) {
        
try {
            xmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP");
        } 
catch (e2) {
            xmlHttp 
= false;
        }
    }
    
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
      xmlHttp 
= new XMLHttpRequest();
    }
}

 

2.下面这个就是发送数据给后台,等待返回数据的了,看代码前先看张页面图片:

下面代码中的if语句解释一下:

if(flag == 1)
    {
       ddl = document.getElementById('<%=ddlApproPath.ClientID %>');//这个是 -原流程- 中的流程名称的下拉框
    }
    else
    {
       ddl = document.getElementById('<%=ddlProcPath.ClientID %>');//这个是 -复制到流程- 中的流程名称的下拉框
    }

因为我是两组联动的,又不想写两个方法,因此就加了个flag来标识选了那一个 '流程名称',然后来无刷出各自的节点.

 

下面这段代码是获得你选中的列表项的值,然后以GET的方式追加到URL参数中,并传递到Selectappr.aspx这个页面中的

var index=ddl.selectedIndex;
    var apprid = ddl.options[index].value;
    if ((apprid == null) || (apprid == "")) return;
    var url = "Selectappr.aspx?apprid=" + apprid;

 

 

这个flag的用法和上面的一样

if(flag == 1)
        xmlHttp.onreadystatechange = updatePage;
    else
        xmlHttp.onreadystatechange = updateWeb;

由于onreadystatechange 订阅的方法在同一个方法里不好写,所以就分开各自订阅自己的等待接收数据方法

function callServer(flag) 
{
    CreateXMLObj();
    
var ddl;
    
if(flag == 1)
    {
       ddl 
= document.getElementById('<%=ddlApproPath.ClientID %>');
    }
    
else
    {
       ddl 
= document.getElementById('<%=ddlProcPath.ClientID %>');
    }
    
var index=ddl.selectedIndex; 
    
var apprid = ddl.options[index].value;
    
if ((apprid == null|| (apprid == "")) return;
    
var url = "Selectappr.aspx?apprid=" + apprid;
    xmlHttp.open(
"GET", url, true);
    
if(flag == 1)
        xmlHttp.onreadystatechange 
= updatePage;
    
else
        xmlHttp.onreadystatechange 
= updateWeb;
    xmlHttp.send(
null);  
}

 

 

3.下面的就是接收Selectappr.aspx页面返回回的数据方法了,我把两组控件的都贴出来,其实是一样的,只是控件名称不一样而已.

下面是代码的解释:

       var oDoc=new ActiveXObject("Msxml2.DOMDocument");//首先要先创建一个DOM用来接受处理XML格式
       var drpNode = document.getElementById('<%=ddlChilds.ClientID %>');//这个就是你要联动的二级控件了
       
       var result=xmlHttp.responseText;//定义一个result来接收Selectappr.aspx返回的数据

     

     alert(result);//这里我弹出一下XML的格式给大家看一下具体是什么样子的XML文档格式

    

    //下面是截图,因为是从DataSet中直接导出的所以前面会有一个<NewDataSet></NewDataSet>节点
      

 

      oDoc.loadXML(result);//这里就是用DOM来load这个XML了
       names = oDoc.selectNodes("/NewDataSet/Table/RsKey");//这里要注意: 这就是取XML中的节点,也就是你的二级下拉框中要联动的信息了,取的格式是用"/"来分割节点的
       codes = oDoc.selectNodes("/NewDataSet/Table/RsCode");
  

     for (var i=drpNode.options.length;i>=0;i--)//把从XML中得到的数据填充到二级下拉框之前要先清空一下,避免第二次选择的时候,选择项一直追加
       {
           drpNode.remove(i);
       }

       var itemsLength = names.length;
       for(i=0;i<itemsLength;i++)//这里就是给二级下拉框添加列表项了,这个就不用多解释了吧
       {
           var newOption = document.createElement("option");
           newOption.text = names[i].text;//下拉框的显示文本就是你从XML中取出的要显示的数据
           newOption.value = codes[i].text;//这是选中列表现时得到的Value
           drpNode.options.add(newOption);
       }
    }

 

function updatePage()
{
    
if (xmlHttp.readyState == 4)
    {
       
var oDoc=new ActiveXObject("Msxml2.DOMDocument");
       
var drpNode = document.getElementById('<%=ddlNodes.ClientID %>');
       
       
var result=xmlHttp.responseText;
       oDoc.loadXML(result);
       names 
= oDoc.selectNodes("/NewDataSet/Table/RsKey");
       codes 
= oDoc.selectNodes("/NewDataSet/Table/RsCode");

       
for (var i=drpNode.options.length;i>=0;i--)
       {
           drpNode.remove(i);
       }

       
var itemsLength = names.length;
       
for(i=0;i<itemsLength;i++)
       {
           
var newOption = document.createElement("option");
           newOption.text 
= names[i].text;
           newOption.value 
= codes[i].text;
           drpNode.options.add(newOption);
       } 
    }
}

function updateWeb()
{
    
if (xmlHttp.readyState == 4)
    {
       
var oDoc=new ActiveXObject("Msxml2.DOMDocument");
       
var drpNode = document.getElementById('<%=ddlChilds.ClientID %>');
       
       
var result=xmlHttp.responseText;
       oDoc.loadXML(result);
       names 
= oDoc.selectNodes("/NewDataSet/Table/RsKey");
       codes 
= oDoc.selectNodes("/NewDataSet/Table/RsCode");

       
for (var i=drpNode.options.length;i>=0;i--)
       {
           drpNode.remove(i);
       }

       
var itemsLength = names.length;
       
for(i=0;i<itemsLength;i++)
       {
           
var newOption = document.createElement("option");
           newOption.text 
= names[i].text;
           newOption.value 
= codes[i].text;
           drpNode.options.add(newOption);
       } 
    }
}

 

 

JS代码部分贴完了,现在来看看页面控件(CopyAppPath.asxp)的代码:

两组联动是一样的,这里我暂且贴一组出来

<div style="padding-top: 4px;">
    
<fieldset style="width: 100%; height: 58px; border: 1px solid #a2d1ff;">
        
<legend style="width: 89px; background-color: #fff; text-align: center; font-family: arial;
            font-weight: bold">原流程 </legend>
        <div style="margin: 0 2 4 2; padding: 0 2 4 2;">
            
<div style="padding-top: 6px; width: 60%; float: left;">
                
<asp:Label ID="Label1" runat="server" Text="流程名称:"></asp:Label>
                
<asp:DropDownList ID="ddlApproPath" runat="server" Width="179px">
                
</asp:DropDownList>
                
<asp:Label ID="Label4" runat="server" Text="部门选择:"></asp:Label>
                
<asp:TextBox ID="txtDept1" runat="server" ReadOnly="True" Width="176px"></asp:TextBox>
                
<input id="Button1" type="button" value=" " onclick="javascript:ShowDeptListForCopyAppor('0')" />
                
<asp:Label ID="Label5" runat="server" Text="节点:"></asp:Label>&nbsp;<asp:DropDownList
                    ID
="ddlNodes" runat="server" Width="179px" AutoPostBack="True" OnSelectedIndexChanged="ddlNodes_SelectedIndexChanged">
                
</asp:DropDownList></div>
            
<div style="float: left; width: 39%;">
                
<fieldset style="width: 100%; height: 56px; border: 1px solid #a2d1ff;">
                    
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
                        
<Columns>
                            
<asp:BoundField HeaderText="部门/子部门" />
                            
<asp:BoundField HeaderText="节点审批人" />
                        
</Columns>
                    
</asp:GridView>
                
</fieldset>
            
</div>
        
</div>
    
</fieldset>
</div>

 

在CopyAppPath.asxp.cs文件里的代码也很简单:

 

private void BinderDDLAppro()
        {
            ddlApproPath.DataSource 
= this.GetApprovalPathName();//从数据库取出数据(次数据为DataTable)
            ddlApproPath.DataTextField = "RsKey";//DropdownList要显示的数据
            ddlApproPath.DataValueField = "RsCode";//DropdownList选中值
            ddlApproPath.DataBind();
            ddlApproPath.Items.Insert(
0new ListItem("--请选择--""-1"));//添加一个提示选项
            ddlApproPath.Attributes.Add("onchange""callServer(1)");//这里是要注意的,给你的一级DropdownList注册一个onchange事件,就是在你选中某一项的时候会调用前面的callServer(1)" 这个JS方法了,里面的参数1就是为了区分我选了哪一组联动的

            ddlProcPath.DataSource 
= this.GetApprovalPathName();//从这里可以看出我的两组联动是一样的了吧,调用的方法根本就是同一个
            ddlProcPath.DataTextField = "RsKey";
            ddlProcPath.DataValueField 
= "RsCode";
            ddlProcPath.DataBind();
            ddlProcPath.Items.Insert(
0new ListItem("--请选择--""-1"));
            ddlProcPath.Attributes.Add(
"onchange""callServer(2)");
        }

 

 

上面的代码也就是同一个页面的前台和后台代码:

重点还是得看Ajax请求数据的页面(其实也很简单,只要得到一个xml格式就行了,当然如果你是调用的webservice,也是大同小异,因为webservice返回的也就是一个XML格式的文档):

来看看Selectappr.aspx页面的代码, 为了得到一个标准的XML格式,只需要保留第一行的Page指令就行了,其他的删除即可.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Selectappr.aspx.cs" Inherits="TopFounder.Web.Protals.BaseFrameWork.Selectappr" %>

 

在Selectappr.aspx.cs 中的我们只需要接收Ajax 传过来的参数,到数据库中找到 二级联动的数据,然后填充到DataSet中,在用XmlTextWriter 直接吧DS中的数据写出到页面

protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["apprid"] != null || Request.QueryString["apprid"].ToString() != "")
            {
                string procid = Request.QueryString["apprid"].ToString();//从GET请求中得到传过来的一级联动的VALUE
                DataSet ds = CommonHelper.GetAllPathNameForDs(procid); //到数据库中查找出数据,然后存放到DataSet中,因为DataSet导出XML最直接,有自带的方法,当然其他的也是可以的
                XmlTextWriter xtw = new XmlTextWriter(Response.OutputStream, System.Text.Encoding.UTF8);//这点要注意了,编码格式要正确不然中文是乱码,在AJAX接收的时候会接收不到乱码的,oDoc.loadXML(result);乱码的情况家DOM也是LOAD不到XML的....
                xtw.Formatting = Formatting.Indented;//这几句是格式的设置
                xtw.Indentation = 4;
                xtw.IndentChar = ' ';
                ds.WriteXml(xtw);     //这个就是吧XML写到Selectappr.aspx的页面中去了.....

                xtw.Flush();
                Response.End();
                xtw.Close();
            }
        }

也就这么多了,希望大家能看的明白,上班时间也就先这样了,不明白的在问我好了...................

posted on 2008-08-21 10:33  kevin.Cheng  阅读(1077)  评论(0编辑  收藏  举报