联动下拉菜单 AjaxPro + JS



因为在项目的发票管理中,用户要求在弹出的对话框(网页)中选择单位后,返回原来页面,并且将单位值填充进来!
实际上 单位的 选择涉及三个部分:



<td align="center" style="height: 30px">
            
&nbsp;&nbsp;&nbsp; 位<span style="color:Red">*</span></td>
        
<td style="height: 30px" >
            
<input id="inp_iComId" type="hidden" name="inp_iComId" runat="server" />
            
<asp:textbox id="tb_vComName" runat="server" Width="80%" ReadOnly="true"></asp:textbox>
            
<onclick="return SelectCompany();" href="#"><img src="Images/search.gif" style="border:0" alt="检索" /></a>
            
            
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="tb_vComName"
                Display
="Dynamic" ErrorMessage="*"> </asp:RequiredFieldValidator>
        
</td>
1、input隐藏表单,保存单位ID
2、textbox保存单位名称
3、img单击弹出对话框

本例中代码涉及比较多,所以只贴出相关代码:
该页面中,js selectCompany和相关函数
<script language="javascript" type="text/javascript">
    
function Unable(){
        
        
//document.getElementById("<%=ddl_iConId.ClientID%>").disabled="disabled" ;
    }

    
    
function SelectCompany()
    
{
        document.getElementById(
"<%=ddl_iConId.ClientID %>").disabled=false;
        
var window_height = 500;
        
var window_width = 800;
        
var top  = (window.screen.availHeight-window_height)/2;
        
var left = (window.screen.availWidth-window_width)/2;
        
        
var fileName = "OpenWindow.aspx?title='请选择单位'&controlName=SelectCompany&ctrlid=<%=inp_iComId.ClientID%>&ctrlnameid=<%=tb_vComName.ClientID%>";
        
        window.open(fileName,
"","left="+left+",top="+top+",height="+window_height+",width="+window_width+",resizable=yes,scrollbars=yes,status=no,toolbar=no,menubar=no,location=no");
        
    }

    
    
var comid;
    
function ReRender()
    
{
        alert(
"1");
        icomid
=document.getElementById("<%=inp_iComId.ClientID %>").value;
        
//每次比较 comid是否为新值,如果为新就重新绘制select
        if((icomid!="")&&(icomid!=comid)){
            PitchWeb.Modules.Balance.InvoiceBillForm.GetContract(icomid,CreateDropDownList);
        }

        comid
=icomid;
    }

    
    
function CreateDropDownList(res)
    
{
        
if(res.error) return alert("AjaxPro发生错误\n" + res.error.Message);
        
if(res==nullreturn;
        
var sel=document.getElementById("<%=ddl_iConId.ClientID %>");
        
var tbl=res.value;
        
if(sel.options.length>1)            
            sel.options.length
=1;
            
//刷新select选择菜单
        for(var i=0;i<tbl.Rows.length;i++){                           
            
var op=document.createElement("option");
            op.setAttribute(
"value",tbl.Rows[i]["Id"]);
            op.setAttribute(
"text",tbl.Rows[i]["vCode"]);
            
//alert(op.text + ":" + op.value);
            sel.options.add(op);
        }

    }


</script>

在该页的cs文件中:
引用了AjaxPro.dll
[AjaxPro.AjaxMethod]
        
public DataTable GetContract(string icomid)
        
{
            DataTable dt 
= null;
            
try
            
{
                
string companyname=ShowHelper.GetCompanyNameById(icomid);
                
                PitchWeb.Contract contract1 
= BillFactory.CreateContract(BillTypes.UnYield);

                
if (icomid != "")
                    dt 
=contract1.GetConByCom(icomid);
                
return dt;
            }

            
catch (Exception ce)
            
{
                
return dt;
            }

            
finally
            
{
               
            }

        }

在被打开的对话框中(openwindow中)
    <script type="text/javascript" language="javascript">
        
var ctrlValue    //传递的主键参数
        var ctrlNameValue
        
function GetDetail(sid,sName)
        
{
            ctrlValue 
= sid;
            ctrlNameValue 
= sName;
        }
        
        
function returnopen(retbutton,retnamebutton,retvalue,retnamevalue)
        
{
                window.opener.document.all(retbutton,
0).value=retvalue;
                window.opener.document.all(retnamebutton,
0).value=retnamevalue;
                window.opener.document.all(retnamebutton,
0).focus();
                
                window.opener.ReRender();                
//添加者:周翔;用以回调刷新select控件
                window.close();
                
        }
    
    
</script>

在向父窗体中赋值以后,就可以调用父页中的函数ReRender(); 来重新绘制Selector下拉列表;

本例中调用了 ajaxpro但是具体的配置很简单,关键是要了解 ajaxpro在js和c#类型 type之间如何调用的关系:
比如我要是想连续初始化多个数据部分,比如说:重新绘制两个Select控件(dropdownlist在客户端的控件)
我就可以返回一个dataset
然后在 callback(res)函数中
    可以这样得到 DataTable在js中的对象
               var ds = res.value;
            
var tbl = ds.Tables[0]; 
然后再调用 就可以了!

但是,注意的是在ds中添加数据表 DataTable的时候,可能会遇到DataTable已经被另一个DataSet包含的错误;
我的服务端c#代码是这么写的:

[AjaxPro.AjaxMethod]
        
public DataSet GetContract(string icomid, string isortid)
        
{
            DataSet ds 
= new DataSet("DS");
            DataTable dt 
= null;
            
try
            
{
                
string companyname = System.Web.HttpContext.Current.Server.UrlEncode(ShowHelper.GetCompanyNameById(icomid));

                PitchWeb.Contract contract1 
= null;
                PitchWeb.Plan plan1 
= null;


                
if (isortid == "2")
                
{
                    contract1 
= BillFactory.CreateContract(BillTypes.Yield);
                    plan1 
= BillFactory.CreatePlan(BillTypes.Yield);

                }

                
else
                
{
                    contract1 
= BillFactory.CreateContract(BillTypes.UnYield);
                    plan1 
= BillFactory.CreatePlan(BillTypes.UnYield);
                }


                
if (icomid != "")
                    dt 
= contract1.GetConByCom(icomid);
                dt.TableName 
= "con";
                ds.Tables.Add(dt.Copy());

                DataTable dt2 
= new DataTable();
                dt2.Columns.Add(
"vComName"typeof(System.String));
                dt2.Rows.Add(companyname);
                
                ds.Tables.Add(dt2);

                DataTable dtplan 
= plan1.GetPlanByCom(icomid);
                ds.Tables.Add(dtplan.Copy());

                
return ds;
            }

            
catch (Exception ce)
            
{
                
return ds;
            }

            
finally
            
{

            }

        }

其实Ajaxpro在使用的时候可以根据服务端返回的对象灵活使用,具体的问题下面会描述:
Ajaxpro的效率就是很大的问题;
我曾经在一个AjaxPro的CallBack函数后面紧跟了另一个Ajaxpro的js请求函数;
结果发现没有响应,怎么调试都不行;后来发现在那个请求结束时,添加 alert("!!")提示框就可以了?(到现在无解)
但是,即使那个请求的CallBack函数有响应,却发生了新的问题;

    发现第一个CallBack成功执行;
    第二个CallBack执行填充的下拉菜单,Asp.NET不能识别填充的 options
    Html里面明明是有options;但是就是在服务端的 XXX . SelectedValue="" 取不到值;
最后没有办法了,将两级关系统统放到服务端,然后返回一个DataSet(这个东西就像一个包,什么都可以往里面放)

在客户端读取的代码:(只有部分)

//选定原计划、合同赋值、绑定新计划
    function ReBindContract(){
        
var iplanid=document.getElementById("<%=ddl_iOldPlan.ClientID %>").value;
        
        
/* 明细表单中 PostToParent 为优先赋值单位名称 追加计划编号;*/
        
var PostToBody=document.getElementById("PostToParent");
        PostToBody.value
=PostToBody.value+"&iPlanId=" + iplanid;
        
        
if((iplanid!=planid)&&(comid!="")&&(iplanid!="")&&(sortid!=""))
            PitchWeb.Modules.Balance.AdjustBillForm.GetConId(iplanid,comid,sortid,DisplayContrList);        
    }
function DisplayContrList(res){
    
if(res.error) return alert("AjaxPro发生错误\n" + res.error.Message);
        
if(res==nullreturn;
       
var ds=res.value;
       
var tbl=ds.Tables[0].Rows[0]["conid"];
       
       
if((tbl!=conid)&&(tbl!="")&&(tbl!=null))
       
{
            document.getElementById(
"<%=iConId.ClientID %>").value=tbl;
            conid
=tbl;
        }

       tbl
=ds.Tables[1];
       
       
var sel=document.getElementById("<%=ddl_iNewPlan.ClientID %>");
       ReBindList(sel, tbl);       
    }

/*几乎通用的Ajaxpro绑定下拉菜单js函数*/
function ReBindList(sel,tbl)
    
{
        
if(sel.options.length>1)            
            sel.options.length
=1;
            
//刷新select选择菜单
        for(var i=0;i<tbl.Rows.length;i++){                           
            
var op=document.createElement("option");
            op.setAttribute(
"value",tbl.Rows[i]["Id"]);
            op.setAttribute(
"text",tbl.Rows[i]["vCode"]);
            
//alert(op.text + ":" + op.value);
            sel.options.add(op);
        }
 
    }



代码很乱,就提到这里了吧!
留个问题给大家:ajaxpro怎么应用web窗体下的变量(this.Somevariable)?


posted on 2007-09-24 13:43  Herist  阅读(1738)  评论(2编辑  收藏  举报

导航