1

I have a parent dropdownlist(named ddlCountry here after) on selected index change of which i am making a ajax call to present relevant data in a cascaded dropdown(Like if i select a country in the parent dropdown, it is going to give me the state names in ddlState.)

Alongside with it,I am cloning ddlCountry and ddlState with the help of the clone() function in my btnClone button. I want my dynamically generated controls to exhibit the same behavior. Like if select an item in ddlCountry_1, i should have the correct state name in ddlState_1 and so on...

Here is my code:

<body>
<form id="form1" runat="server">
    <div>           
        <asp:Button ID="btnClone" Text="Clone" runat="server" />
    </div>
    <br />
    <br />
    <table>
        <tr>
            <td>Cateogry:
            </td>
            <td>
                <div>
                    <asp:DropDownList ID="ddlCountryList" runat="server" class="ddlCountryClass"></asp:DropDownList>
                </div>
            </td>
            <td>SubCategory:
            </td>
            <td>
                <div>
                    <asp:DropDownList ID="ddlStateList" runat="server" class="ddlStateClass"></asp:DropDownList>
                </div>
            </td>
        </tr>
        <tr>
            <td>
                <div id="target">
                </div>
            </td>
            <td>
                <div id="target2">
                </div>
            </td>
        </tr>
    </table>
</form>

<script type="text/javascript">

    $(function () {

        $("[id*=btnClone]").bind("click", function () {
            var index = $("#target select").length + 1;
            //Clone the DropDownList
            var ddl = $("[id$=ddlCountryList]").clone();
            //Set the ID and Name
            ddl.attr("id", "ddlCountryList_" + index);
            ddl.attr("name", "ddlCountryList_" + index);
            //[OPTIONAL] Copy the selected value
            var selectedValue = $("[id$=ddlCountryList] option:selected").val();
            ddl.find("option[value = '" + selectedValue + "']").attr("selected", "selected");
            //Append to the DIV.
            $("#target").append(ddl);
            $("#target").append("<br /><br />");
            return false;
        });
    });

    $(function () {

        $("[id*=btnclone]").bind("click", function () {

            var index = $("#target2 select").length + 1;

            //clone the dropdownlist
            var ddl = $("[id$=ddlstatelist]").clone();

            //set the id and name
            ddl.attr("id", "ddlstatelist_" + index);

            ddl.attr("name", "ddlstatelist_" + index);

            //[optional] copy the selected value
            var selectedvalue = $("[id$=ddlstatelist] option:selected").val();
            ddl.find("option[value = '" + selectedvalue + "']").attr("selected", "selected");

            //append to the div.
            $("#target2").append(ddl);
            $("#target2").append("<br /><br />");

            return false;
        });
    });

    //  Make Ajax call to fetch the state values.
    $(function () {
        $('#ddlStateList').attr('disabled', 'disabled');
        $('#ddlStateList').append('<option selected="selected" value="0">Select State</option>');
        $('#ddlCountryList').change(function () {
            var country = $('#ddlCountryList').val()
            $('#ddlStateList').removeAttr("disabled");
            $.ajax({
                type: "POST",
                url: "Default.aspx/BindStates",
                data: "{'country':'" + country + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (msg) {
                    var j = jQuery.parseJSON(msg.d);
                    var options;
                    for (var i = 0; i < j.length; i++) {
                        options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>'
                    }
                    $('#ddlStateList').html(options)
                },
                error: function (data) {
                    alert('Something Went Wrong')
                }
            });
        });
    });           
</script>

Ninja
  • 331
  • 1
  • 3
  • 16
  • You will probably want to use delegated event handling for dynamically created elements [Does jQuery.on() work for elements that are added after the event handler is created?](http://stackoverflow.com/questions/9814298/does-jquery-on-work-for-elements-that-are-added-after-the-event-handler-is-cre/9814409?s=3|0.0000#9814409) and [jQuery .live() vs .on() method for adding a click event after loading dynamic html](http://stackoverflow.com/questions/8752321/jquery-live-vs-on-method-for-adding-a-click-event-after-loading-dynamic-ht/8752376#8752376) – jfriend00 Jul 25 '15 at 05:56
  • That article was worth reading. Thank you! – Ninja Jul 25 '15 at 07:03

1 Answers1

1

In order for your cloned dropdowns to inherit the behavior of the originals, you are going to have to do a couple things.

First, as laid out in the jQuery documentation for .clone(), you need to pass true to the clone function so that it clones data and events.

Second, you are going to want to rewrite your #ddlCountryList change function so that it doesn't reference specific ids -- it needs to be able to use the element that the event was triggered on (one of the country dropdowns) and figure out the corresponding state dropdown to populate with data. One possible way to do this would be as follows:

$('#ddlCountryList').change(function () {
    var $countryDropdown = $(this); // "this" is the event source
    var country = $countryDropdown.val();
    // Figure out the index of the country dropdown
    var index = $countryDropdown.attr('id').split("_")[1] || "";
    if (index) {
      index = "_" + index;
    }
    var $stateDropdown = $("#ddlStateList" + index);
    $stateDropdown.removeAttr("disabled");
    $.ajax({
        type: "POST",
        url: "Default.aspx/BindStates",
        data: "{'country':'" + country + "'}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (msg) {
            var j = jQuery.parseJSON(msg.d);
            var options;
            for (var i = 0; i < j.length; i++) {
                options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>'
            }
            $stateDropdown.html(options)
        },
        error: function (data) {
            alert('Something Went Wrong')
        }
    });
});

Disclaimer: This code snippet has not been tested, but it gives the basic idea.

jswett33
  • 41
  • 1
  • 3