Matt King
Matt King

Reputation: 749

Jquery in Multi Select Drop down list

I have put myself together a multiple select drop down list user control that looks like this:

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <div id="multiTop" class="multiTop">
            <asp:Button ID="DropDownButton" CssClass="dropDownButton" Text="All" runat="server" />
        </div>
        <div ID="multiMain" class="multiMain" style="display:none">              
            <asp:Button ID="SelectAllButton" Text="All" runat="server" CssClass="allButton" OnClick="AllButton_Click" />
            <asp:CheckBoxList ID="MultiCheckBox" runat="server" RepeatDirection="Vertical" AutoPostBack="true"
            OnSelectedIndexChanged="MultiCheckBox_SelectedIndexChanged" CssClass="mutiCbl">
            </asp:CheckBoxList>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>

To begin with I was using a server side event to show and hide the "multiMain" panel (now a div) whenever the DropDownButton was pressed. A bit of Css fiddling later and the whole thing looked like a drop down list.

The main problem however is if the user clicks anywhere else on the page, unlike a real dropdownlist, the drop down part didn't dissapear. Thus with a heavy heart I've turned to Jquery, something I have little to no idea about.

I'm looking for some jquery that will show and hide the div when the button is clicked, and hide the div whenever you click anywhere else. So far I've come up with:

$(document).ready(function () {
    var dropDownButton = $get('<%= DropDownButton.ClientID %>');
    var multiMain = $get('<%= multiMain.ClientID %>');       

    dropDownButton.click(function () {           
        if (multiMain.is(":hidden")) {
            multiMain.slideDown("slow");
        }
        else {
            multiMain.slideUp("slow");
        }
        return false;
    });


    $(document).click(function () {
        multiMain.hide();            
    });
    multiMain.click(function (e) {            
        e.stopPropagation();
    });
});

However, nothing is happening when the drop down button is clicked, or when the rest of the page is clicked I have several of these multi select drop down lists on the page, and I'm really not sure how I sort out the events. Any ideas?

Upvotes: 3

Views: 2394

Answers (1)

Matt King
Matt King

Reputation: 749

As it turns out, the solution was to move away from server side handling of the checklist, and do much more client side using Jquery. Instead of trying to get the exact ID for the controls, which can be difficult given the stuff asp.net appends, everything is done by class. The key bits of code used are as follows:

$("div.multiTop .dropDownButton").bind('click', function (e) {
    var masterDiv = $(this).parents("div.multiMaster");
    var multiMain = $("div.multiMain", masterDiv);        

    if (multiMain.is(":hidden")) {
        $("div.multiMain").hide();
        multiMain.show();
    }
    else {
        multiMain.hide();
    }        
    return false;
});

When the button that looks like a drop down list is clicked, jquery finds all of the other drop down div's on the page and hides them, then only shows the current drop down div.

$(".multiCbl").bind('change', function (e) {
    var masterDiv = $(this).parents("div.multiMaster");
    var multiMain = $(this).parents("div.multiMain");
    var names = [];

    $("input:checked", multiMain).each(function () {
        names.push(" " + $(this).next().text());
    });

    var text = names.toString();

    if (text.length == 0) {
        text = "All";
    }
    else if (text.length > 29) {
        text = text.substring(1, 29) + "...";
    }
    else {
        text = text.substring(1, text.length);
    }

    $(".dropDownButton", masterDiv).val(text);
    $(".dropDownButton", masterDiv).next().val(text);

    e.stopPropagation();
});

JQuery is also now used to populate the button text as checkboxes are clicked or unclicked. In hindsight this is a much better was of doing it, as opposed to posting back each time a box is checked.

$(document).bind('click', function () {
    $("div.multiMain").hide();
});

$("div.multiMain").bind('click', function (e) {
    e.stopPropagation();
});

When anywhere else but the drop down div itself is clicked, all of the drop down divs are hidden.

The only other major change is to remind people that buttons do not post back as form fields! Thus where you see ".next().val" I am also populating the value of a hidden field. When I post back, the text value of the field is restored from the hidden field.

I hope this is useful to other people!

Upvotes: 3

Related Questions