Doing a postback without AutoPostBack
Asked Answered
C

1

6

I've got a WebForm with two drop down lists, where the contents of the second one depend on the first.

enter image description here

So if the user changes the category, the second dropdown needs to be filled with the list of subcategories.

This sounds like a typical job for AutoPostBack.
However, there's a bit of a problem with AutoPostBack: if the list isn't dropped open, and the user uses the keyboard to make the choice, the postback happens right after the first keystroke. This prevents the user from scrolling down the list with the down arrow, or typing the name of the category.

This happens in Chrome and IE and Opera, but not in Firefox. Firefox fires the onchange event only when leaving the control (tabbing to the next control), just like it would when the list was dropped open, and that's what I want the other browsers to do too.

Any solutions how I can achieve this?

I tried to remove the AutoPostBack attribute and use onblur, but apparently the page works differently with AutoPostBack than without, because the browsers start complaining about Javascript errors.

Now since we're all so fond of jsFiddle, here's one. It doesn't actually do anything, but it can demonstrate the problem. Click on the first dropdown, then click again to close the list. (This is what happens when you navigate through the form with the tab key: dropdown lists don't open up.) Now type a letter or the down arrow. Firefox changes the current selection and waits for you to do anything else, but Chrome and IE and Opera all attempt to submit the form immediately, with drastic results.

So how can I avoid that? And note that simply changing the fiddle may not be enough, it must be translatable back to an ASP.NET solution.

Conductivity answered 31/1, 2014 at 11:18 Comment(0)
C
1

Ok here is how I'd do it by using ajax and avoiding the use of AutoPostback all together to populate my sub category.

Create an object that represents the select list json object to send back.

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

Then create a 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;
    }

Add a script manager and EnablePageMethods i.e.

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

Change your dropdown lists to use 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>

Then use the following 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>
Clarion answered 31/1, 2014 at 13:26 Comment(2)
Sorry I never got back to this. Other things I had to do suddenly became more urgent. Anyway, I did manage to implement this, but it wasn't easy getting around the restriction that such web methods can only be static. So I ended up sending a lot of info to the client side (in hidden inputs) and then sending it back to the web control in the parameters to the function. If there's any more elegant way to do it, I'd be delighted!Conductivity
@MrLister No problem re: urgency, I know what it can be like. Yes, unfortunately you do have to send stuff back to the client. I mainly work in MVC now and it all has to be sent back so I am used to it. It does seem a bit disjointed in web forms but preventing the postback gives a good user experience. Good luck with the rest. :)Clarion

© 2022 - 2024 — McMap. All rights reserved.