我有一个带有两个下拉列表的WebForm,其中第二个列表的内容取决于第一个。
因此,如果用户更改类别,则需要使用子类别列表填充第二个下拉列表。
这听起来像是AutoPostBack的典型工作 但是,AutoPostBack存在一些问题:如果列表未被打开,并且用户使用键盘进行选择,则在第一次击键后立即发生回发。这可以防止用户使用向下箭头向下滚动列表,或者键入类别的名称。
这种情况发生在Chrome和IE和Opera中,但不会发生在Firefox中。 Firefox只有在离开控件时才会触发onchange
事件(Tabbing到下一个控件),就像打开列表时那样,这就是我希望其他浏览器也能做到的事情。
任何解决方案我如何才能实现这一目标?
我尝试删除AutoPostBack
属性并使用onblur
,但显然该页面与AutoPostBack的工作方式不同,因为浏览器开始抱怨Javascript错误。
现在因为我们都非常喜欢jsFiddle,here's one。它实际上没有做任何事情,但它可以证明问题。单击第一个下拉列表,然后再次单击以关闭列表。 (当您使用Tab键在表单中导航时会发生这种情况:下拉列表无法打开。)现在键入一个字母或向下箭头。 Firefox改变了当前的选择并等待你做其他事情,但Chrome和IE以及Opera都试图立即提交表格,结果非常好。
那我怎么能避免呢?请注意,仅仅改变小提琴可能还不够,它必须可以转换回ASP.NET解决方案。
答案 0 :(得分: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>