先讲一下本问的意思,就是用Ajax简单做一个二级联动,从数据库读取数据,转换成XML格式输入,然后Ajax接收实现无刷联动效果...
先看一下前台页面的JS代码:(为了方便Copy,代码中的行号取消了).
1. CreateXMLObj无可非议是创建xmlHttpRequest对象的,网上一搜一大堆,这个可以根据自己的习惯来写...
{
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 订阅的方法在同一个方法里不好写,所以就分开各自订阅自己的等待接收数据方法
{
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);
}
}
{
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)的代码:
两组联动是一样的,这里我暂且贴一组出来
<fieldset style=" 100%; height: 58px; border: 1px solid #a2d1ff;">
<legend style=" 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; 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> <asp:DropDownList
ID="ddlNodes" runat="server" Width="179px" AutoPostBack="True" OnSelectedIndexChanged="ddlNodes_SelectedIndexChanged">
</asp:DropDownList></div>
<div style="float: left; 39%;">
<fieldset style=" 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文件里的代码也很简单:
{
ddlApproPath.DataSource = this.GetApprovalPathName();//从数据库取出数据(次数据为DataTable)
ddlApproPath.DataTextField = "RsKey";//DropdownList要显示的数据
ddlApproPath.DataValueField = "RsCode";//DropdownList选中值
ddlApproPath.DataBind();
ddlApproPath.Items.Insert(0, new 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(0, new 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();
}
}
也就这么多了,希望大家能看的明白,上班时间也就先这样了,不明白的在问我好了...................