2014-01-31 37 views
5

我有一个WebForm与两个下拉列表,其中第二个的内容取决于第一个。做没有AutoPostBack回发

enter image description here

因此,如果用户改变了类别,第二个下拉需要填充子类别的列表。

这听起来像是AutoPostBack的典型工作。
但是,AutoPostBack存在一些问题:如果列表没有放开,并且用户使用键盘进行选择,则回发会在第一次按键之后发生。这可以防止用户使用向下箭头向下滚动列表,或者输入类别的名称。

这发生在Chrome和IE和Opera中,但不在Firefox中。只有当离开控件时,Firefox才会触发onchange事件(切换到下一个控件),就像当列表打开时一样,这也是我希望其他浏览器也可以这样做的事情。

任何解决方案,我可以实现这一目标?

我试图删除AutoPostBack属性并使用onblur,但显然该页面与AutoPostBack的工作方式不同,因为浏览器开始抱怨Javascript错误。

现在因为我们都很喜欢jsFiddle,here's one。它实际上并没有做任何事情,但它可以证明问题。点击第一个下拉菜单,然后再次点击关闭列表。 (这是使用Tab键导航窗体时发生的情况:下拉列表不打开。)现在,输入一个字母或向下箭头。 Firefox会改变当前的选择,并等待您做其他事情,但Chrome和IE以及Opera都会立即提交表单,并取得令人瞩目的结果。

那么我该如何避免这种情况?并且请注意,仅仅更改小提琴可能还不够,它必须转换回ASP.NET解决方案。

回答

1

好的,这里是我如何通过使用ajax并避免使用AutoPostback一起来填充我的子类别。

创建一个对象,该对象表示要发回的选择列表json对象。

public class SelectItem 
    { 
     public string Id { get; set; } 
     public string Text { get; set; } 
    } 

然后创建一个PageMethod的:

[WebMethod] 
    public static List<SelectItem> GetSubCategories(string Id) 
    { 
     // Returning dummy data for demo purposes 
     var subCats = new List<SelectItem>(); 

     if (Id == "1") 
     { 
      subCats.Add(new SelectItem { Id = "1", Text = "1 Subs"}); 
     } 
     else if (Id == "2") 
     { 
      subCats.Add(new SelectItem { Id = "2", Text = "2 Subs"}); 
     } 

     return subCats; 
    } 

添加脚本经理和EnablePageMethods

<asp:ScriptManager runat="server" EnablePageMethods="true"> 
</asp:ScriptManager> 

更改您的下拉列表中使用ClientIDMode="Static"

<asp:DropDownList Id="ddlCategory" runat="server" ClientIDMode="Static"> 
    <asp:ListItem Value ="1" Text ="One"></asp:ListItem> 
    <asp:ListItem Value ="2" Text ="Two"></asp:ListItem> 
</asp:DropDownList> 

<asp:DropDownList Id="ddlSubCategory" runat="server" ClientIDMode="Static"> 
</asp:DropDownList> 

然后使用以下的jQuery:

<script type="text/javascript"> 
    $(function() { 

     var $cat = $('#ddlCategory'); 

     $cat.click(function() { 

      var catId = $cat.val(); 

      $.ajax({ 
       type: "POST", 
       url: "Default.aspx/GetSubCategories", 
       data: "{ Id: " + catId + " }", 
       contentType: "application/json; charset=utf-8", 
       dataType: "json", 
       success: function (msg) { 

        var subs = msg.d; 
        // empty selection 
        var $ddlSubCategory = $('#ddlSubCategory'); 
        $ddlSubCategory.empty(); 

        $.each(subs, function (index, sub) { 
         $ddlSubCategory.append($('<option/>', { 
          value: sub.Id, 
          text: sub.Text 
         })); 
        }); 

       } 
      }); 
     }); 

    }); 

</script> 
+0

对不起,我从来没有回本。我必须做的其他事情突然变得更加紧迫。无论如何,我确实设法实现了这一点,但要避免这种Web方法只能是静态的限制并不容易。所以我最终发送了大量的信息给客户端(在隐藏的输入中),然后将它发送回web控件的参数到函数中。如果有更优雅的方式去做,我会很高兴! –

+0

@MrLister没问题:紧急,我知道它会是什么样子。是的,不幸的是,你不得不把东西发回给客户。我现在主要在MVC工作,所有事情都必须发回去,所以我习惯了。它在网络表单中看起来有点脱节,但防止回发给出了良好的用户体验。祝好运与其余。 :) – hutchonoid

相关问题