Populate cascading dropdown using JSON and jQuery…!


I got a requirement to populate two dropdowns with Country and Province/State data for a SharePoint 2007 project (data retrieved from SharePoint lists). So the first dropdown will contain the Country names. Second dropdown should populate details depending on the selected country on first dropdown. In my scenario, if the country is USA then populate the states from USA, and if its Canada, populate the provinces from Canada, if any other country keep the dropdown disabled.

I simple added two asp dropdown controls and bound data respectively of the first dropdown selected index change event. But the issue was for better user experience we had to avoid that post back.

Was reading about how to implement this and because of the reason, possible data for the province/state dropdown is small I went for a jQuery + JSON solution. I could have used a update panel and provided a Ajax solution. But with SharePoint 2007 integrating Ajax is a bit messy and also only because of dropdown data loading for it was a overhead doing that.

So when the page loads, I retrieve all the countries and doing the binding to the first dropdown. And also retrieving all possible state and provinces and getting it all into a JSON object and passing it to client side. And using jQuery from client side I am populating the second drop down accordingly.

Step 01:

Dictionary<string, string> states = new Dictionary<string, string>();
states.Add("DC", "Washington DC");
states.Add("BC", "Brtish Colombia");
states.Add("NY", "New York");

Dictionary<string, string> province = new Dictionary<string, string>();
province.Add("ON", "Ontario");
province.Add("AB", "Alberta");
province.Add("QB", "Qubec");

Dictionary<string, Dictionary<string, string>> selection = new
Dictionary<string, Dictionary<string, string>>();
selection.Add("USA", states);
selection.Add("CAN", province);

JavaScriptSerializer serializer = new JavaScriptSerializer();
string str = serializer.Serialize(selection);
ctrFormData.Value = str;

I populate a dictionary with my data that goes into sate and province dropdown and I create a structured object so that I can retrieve the values as Key Value pair, and then using JavaScriptSerializer I serialize this object to a string and then placing it inside a hidden field on my markup. This is how I am passing my data to client side.

Step 02:

Then generated the markup as needed. You can see there I have placed two hidden fields, and one is to store all the state/province items and one is to store the selected. The text box field will display the selected value after the user submit the values.

<div>
    <asp:HiddenField ID="ctrFormData" runat="server" />
    <asp:HiddenField ID="ctrSelectedState" runat="server" />
    <table>
        <tr>
            <td>
                Country :
            </td>
            <td>
                <asp:DropDownList ID="ddlCountry" runat="server" />
            </td>
        </tr>
        <tr>
            <td>
                State / Province :
            </td>
            <td>
                <select id="ddlStateOrProvince" name="ddlStateOrProvince" 
style="width: 150px">
                    <option value="XXX">Select</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>
                Selected Code:
            </td>
            <td>
                <asp:TextBox ID="txtName" runat="server" />
            </td>
        </tr>
    </table>
    <asp:Button ID="btnSelect" runat="server" Text="Get Selected" />
</div>

The page looks like this in the browser.

image

Step 03:

I included jQuery script file to the page and wrote the function needed to populate the state / province dropdown according to country selection.

function populateStateProvince(hiddenControlId, state) {

    var dropDownData = document.getElementById(hiddenControlId);

    $states = $('#ddlStateOrProvince');
    var selectedState = null;

    if (state === "USA") {
        selectedState = eval('(' + dropDownData.value + ')').USA;
    }
    else if (state === "CAN") {
        selectedState = eval('(' + dropDownData.value + ')').CAN;
    }
    else {
        selectedState = null;
    }

    $states.children('option:not(:first)').remove();

    if (selectedState === null) {
        $states.attr("disabled", true);
    }
    else {
        $states.attr("disabled", false);
        $.each(selectedState, function (k, v) {
            $states.append('<option value="' + k + '">' + v + '</option>');
        });
    }
}

 

Step 04:

Now we need to make a call to the above function when there is a selection change in the country drop down. Also need to update the ctrSelectedState hidden field to store the newly selected state province. And when the page initially loads we need to the above proper selected and data loading. For that I am invoking the above function on document onready using jQuery.

$('#<%=ddlCountry.ClientID%>').change(function () {
    populateStateProvince('<%= ctrFormData.ClientID %>', $(this).val());
});

$('#ddlStateOrProvince').change(function () {
    $('#<%=ctrSelectedState.ClientID%>').val($(this).val());
});

$(function () {
    populateStateProvince('<%= ctrFormData.ClientID %>', 
      $('#<%=ddlCountry.ClientID%>').val());

    if ($('#<%=ctrSelectedState.ClientID%>').val() != '') {
        $('#ddlStateOrProvince').val($('#<%=ctrSelectedState.ClientID%>').val());
    }
});
That’s all about it! Happy Coding! Smile
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s