Search code examples
javascriptasp.netfunctionradiobuttonlist

One function that will work with multiple elements


I have about 50 RadioButtonList on a form with a checkbox next to them. When you check the checkbox the radioButtonList gets enabled. I have the code to make it work for one but I am looking for a way to write one function that will work for all 50 RadioButtonList instead of writing fifty different functions. The checkboxes and RadioButtonLists are in a table. Thanks in advance

    <script type="text/javascript">
        function dis() {
            var controlObject = document.getElementById('MainContent_RadioButtonList1');
            controlObject.removeAttribute('disabled')
            RecursiveDisable(controlObject);
            return false;
        }
        function RecursiveDisable(control) {
            var children = control.childNodes;
            try { control.removeAttribute('disabled') }
            catch (ex) { }
            for (var j = 0; j < children.length; j++) {
                RecursiveDisable(children[j]);
                //control.attributes['disabled'].value = '';     

            }
        }
        function able() {
            var controlObject = document.getElementById('MainContent_RadioButtonList1');
            controlObject.setAttribute('disabled')
            RecursiveDisable2(controlObject);
            return false;
        }
        function RecursiveDisable2(control) {
            var children = control.childNodes;
            try { control.setAttribute('disabled') }
            catch (ex) { }
            for (var j = 0; j < children.length; j++) {
                RecursiveDisable2(children[j]);
                //control.attributes['disabled'].value = '';     

            }
        }


        function disable() {
        var checkbox = document.getElementById('MainContent_CheckBox1');
            if (
            checkbox.checked == true)
                dis();
            else
            able();
            }
    </script>



    <table>
    <tr>
    <td><asp:CheckBox ID="CheckBox1" runat="server" OnClick="return disable();" /></td>
    <td>
    <asp:RadioButtonList ID="RadioButtonList1" runat="server" Enabled="false">
    <asp:ListItem value="1">ListItem 1</asp:ListItem>
    <asp:ListItem value="2">ListItem 2</asp:ListItem>
    <asp:ListItem value="3">ListItem 3</asp:ListItem>
    </asp:RadioButtonList>
    </td>
    </tr>
    <tr>
    <td><asp:CheckBox ID="CheckBox2" runat="server" OnClick="return disable();" /></td></td>
    <td>
    <asp:RadioButtonList ID="RadioButtonList2" runat="server" Enabled="false">
    <asp:ListItem value="1">ListItem 1</asp:ListItem>
    <asp:ListItem value="2">ListItem 2</asp:ListItem>
    <asp:ListItem value="3">ListItem 3</asp:ListItem>
    </asp:RadioButtonList>
    </td>
    </tr>
    </table>

Solution

  • REWRITE

    I believe that the action you want to perform is to toggle the enabled/disabled state of a drop down list that matches a given radio button. The radio buttons and drop down lists are stored in a table. If a radio button is "checked", you want the drop down list enabled. Otherwise, you want it disabled.

    Create a custom attribute in the markup that binds the checkbox to its target drop-down list. For example, modify the markup like this:

    <asp:CheckBox ID="CheckBox1" 
                  runat="server" 
                  target="DropDownList1" />
    

    Then, iterate over all the checkboxes on the form using a piece of JavaScript and set an event handler for them.

    (I chose target as my attribute name below, you can use whatever you like to save keystrokes, so long as it doesn't collide with an established DOM attribute.)

    function setCheckBoxHandlers()
    {
        var boxes = document.getElementsByTagName("input");
        for (box in boxes)
        {
            // Only bind those that have a target attribute; leave all 
            // others alone.
            if (box.getAttribute("type").toLowerCase() == "checkbox" &&
                box.getAttribute("target") != null)
            {
                // Set up the onclick handler.
                box.onclick = toggleCheckBox;
            }
       }
    }
    
    function toggleCheckBox(e)
    {
        // Mozilla browsers pass the event source as argument zero. Microsoft
        //  doesn't; get it from the window.
        e = e || window.event.source;
        var target = document.getElementById(e.getAttribute("toggleTarget"));
        if (e.checked)
        {
            target.removeAttribute("disabled");
        } 
        else
        {
            target.setAttribute("enabled");
        }
    }
    

    As this is a drop-down list, I see no need to enable/disable the idividual ListItems within it.

    Your HTML looks like it might actually be generated (if not, it's likely a candidate for it), so this should work pretty well provided that I've understood the problem correctly.

    UPDATE

    I have it working, but you're right: ASP.NET's funky table-based layouts wreak havoc with what you want to do. Good news is, it CAN be done. :)

    You can find the working solution at http://jsfiddle.net/tyrantmikey/RxY5s/. Note the following:

    • During document load, you need to call setCheckBoxHandlers.
    • I had to split the function into two parts. One for the on click handler, the other for the tree traversal.
    • The checkbox should include a TARGET attribute that points to its matching radiobuttonlist. (Its value should be the ID of the radio button list.)
    • You don't need to set the onclick handler in the tag; this will happen automatically when you call setCheckBoxHandlers. This is a nice solution, as it makes it easier to add new rows to your table later.

    Hope this does the trick for you!