This is a migrated thread and some comments may be shown as answers.

Example of cascading dropdownlist with remote binding

4 Answers 566 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
Jon
Top achievements
Rank 1
Jon asked on 16 Jan 2014, 04:25 AM
I'm looking for an example of casting KendoUI DropDownList using remote data.  

Specifically,
I have a dropdownlist for state.  Once the state is selected, the dropdown list for city populates (based on the selection value of the state dropdown list).  Once the city item is selected, the School dropdown is populated (based off both the state and city values).  Seems simple enough...but

Please note:
//This example on cascading won't work for me because I'm not working with MVC or server-side to handle this
http://demos.kendoui.com/web/dropdownlist/cascadingdropdownlist.html

//I wired up the change event using this example, but did not have any luck
http://www.kendoui.com/forums/kendo-ui-web/dropdownlist/3-cascade-remote-dropdownlists.aspx

//This jsFiddle example is close to what I'm trying to do...but I'm not using oData and wasn't too sure
http://jsfiddle.net/krustev/xuZn9/

//I've seen other examples where the 2nd dropdownlist dataset actually has ALL values and is just filtered - this won't work because the sets are too large to load all at once.

//Here's the code for 2 of the 3 dropdownlists (figured if i could get 2 I could get 3), any help would be much appreciated.

<script type="text/javascript">

    jQuery(document).ready(function () {
        LoadStates(1);
       LoadCities(70);
   });

function LoadStates(pageLoad) {
    var stateDataSource = [
        { stateName: "MA", stateValue: "1" },
        { stateName: "NH", stateValue: "2" },
        { stateName: "VT", stateValue: "3" }
    ];

    var states = jQuery("#StateDropDown").kendoDropDownList({
        optionLabel: "Select State...",
        dataTextField: "stateName",
        dataValueField: "stateValue",
        dataSource: stateDataSource,
        change: function () {
            var stateId = this.value();
            var ddl = jQuery("#CityDropDown").data("kendoDropDownList");
            if (stateId) {
                LoadCities(stateId);
                ddl.enable();
            } else {
                ddl.enable(false);
            }
        }
    });
      
    //if first time on page, select 1st option in dropdown
    var ddlStates = states.data("kendoDropDownList");
    if (pageLoad == 1) {
        ddlStates.select(1);
    }
}

function LoadCities(stateId) {

    //Load all the cities based on a particular state
    var cities = $("#CityDropDown").kendoDropDownList({
        dataTextField: "Text",
        dataValueField: "Value",
        optionLabel: "Select City...",
        dataSource: {
            transport: {
                read: {
                    dataType: "json",
                    url: ".../api/digital/GetAllCities/" + stateId,
                    cache: false
                }
            },
            schema: {
                //This works correctly, the Web API returns the following when passed in state ID 1 for MAy
                // {"Table":[{"Value":111,"Text":"Boston"},{"Value":222,"Text":"Cambridge"},...{"Value":333,"Text":"Lexington"}]}
                data: "Table"
            }
        }
    });

    //Always set the list to the first option unless on initial page load...TODO
    var ddlCities = cities.data("kendoDropDownList");
    ddlCities.select(0);
}

</script>

<input id="StateDropDown" />                       
<input id="CityDropDown" />  
<input id="SchoolDropDown" disabled="disabled" />

4 Answers, 1 is accepted

Sort by
0
Georgi Krustev
Telerik team
answered on 17 Jan 2014, 01:16 PM
Hello Jon,

The data source, which DropDownList widget uses, supports two ways of binding - client and server. If you want to use client side binding with cascading widgets, then you will need to provide the all data on the client. The other option is to use server binding and thus to filter on server and serialize only a small subset of data to the client. I would like to suggest you check this help topic, which describes how the cascading functionality works.

The aforementioned jsFiddle demo just shows how to implement the cascading functionality manually. Please note that the shown implementation is not limited to ODATA protocol. You can use a regular service, which return JSON or XML and still to use the suggested approach. Note also that this demo uses server binding, as the cascading demo.

As to your question, I noticed that the URL of cities' data source is defined statically. In other words the URL is set once with current stateId value and it will not be updated on dropdownlist change. You can overcome this defining the URL as function:
read: {
                   dataType: "json",
                   url: function() { return ".../api/digital/GetAllCities/" + stateId: },
                   cache: false
               }
For more information I will suggest you check the Getting Started and API of the DataSource component.

Regards,
Georgi Krustev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Jon
Top achievements
Rank 1
answered on 17 Jan 2014, 09:47 PM
Thanks for the response.  I think I'm getting "closer".  I've looked at the referenced links many times (thanks), however I'm still having issues.
Specifically, the state ddl loads fine and the city ddl loads fine.  But, when I change the state, the city does "something", but doesn't change.  But then, if I change the state a 2nd time, the previously anticipated list shows up.  It is as if there is a "one off".

Ex. Load page
State dropdown selection starts with  = MA
City dropdown contains Boston, Lexington, and Cambridge

Change State to CA
City dropdown still has Boston, Lexington, and Cambridge

Change State to Nebraska
City dropdown shows San Diego, San Fransisco, LA  

I did change my url to a function, however it made no difference, so I changed it back.

Thanks for you help.

0
Georgi Krustev
Telerik team
answered on 20 Jan 2014, 11:17 AM
Hello Jon,

Thank you for the additional information. Unfortunately, based on the given information I am not sure where could be the problem and the only way to continue with our investigation is to provide a runnable test project, which reproduces the problem. Thus I will be able to review current implementation and see the erroneous behavior.

Regards,
Georgi Krustev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Accepted
Jon
Top achievements
Rank 1
answered on 22 Jan 2014, 05:22 PM
Here is how I was able to create cascading multiple dropdown lists using remote RESTful ASP.net API sources.
Note: the api calls all return Text/Value within HttpResponseMessage.
Ex (raw from Fiddler):
{"Table":[{"Value":1,"Text":"City 1"},{"Value":2,"Text":"City 2"},{"Value":3,"Text":"City 3"},...{"Value":99999,"Text":"City 99999"}]}and

{"Table":[{"Value":1,"Text":"School 1"},{"Value":2,"Text":"School 2"},{"Value":3,"Text":"School 3"},...{"Value":99999,"Text":"School 99999"}]}

 function CascadingDropdowns() {
        var pageLoad = 1;
        LoadStates(pageLoad);

        var ddlState = jQuery("#ddlStates").data("kendoDropDownList");

        if (pageLoad == 1) {
            var defaultStateId = 70;
            ddlState.value(defaultStateId);
        }

        var stateId = ddlState.value();
        LoadCities(stateId, pageLoad);
    }

    function LoadStates(pageLoad) {
        var stateData = [
            { StateName: "MA", StateValue: "1" },
            { StateName: "NH", StateValue: "2" },
            { StateName: "VT", StateValue: "3" }
        ];

            $("#ddlStates").kendoDropDownList({
                optionLabel: "Select State...",
                dataTextField: "StateName",
                dataValueField: "StateValue",
                dataSource: stateData,
                index: 0,
                change: function () {
                    var value = this.value();
                    var ddlCity = jQuery("#ddlCities").data("kendoDropDownList");
                    var ddlSchool = jQuery("#ddlSchools").data("kendoDropDownList");
                    ddlCity.select(0);
                    ddlSchool.select(0);
                    if (value) {
                        LoadCities(value, 0);
                        ddlCity.enable();
                    } else {
                        ddlSchool.enable(false);
                        ddlCity.enable(false);
                    }
                }
            });
    }


    function LoadCities(stateId, pageLoad) {
        var apiUrl = baseUrl + "/api/GetAllCities/" + token + "?stateId=" + stateId + "&callback=?";

        var cityData = new Array();

        $.getJSON(apiUrl, function (jsonResultObj) {

            // because our RESTful api is returning a dataset within an HttpResponseMessage,
            // we loop through result and create our data array here
            for (var i = 0; i < jsonResultObj.Table.length; i++) {
                var x = jsonResultObj.Table[i];
                cityData.push(x);
                for (var j = 0; j < x.length; j++) {
                    var cityId = x[j];
                    cityData.push(cityId);
                }
            }

            $("#ddlCities").kendoDropDownList({
                optionLabel: "Select City...",
                dataTextField: "Text",
                dataValueField: "Value",
                dataSource: cityData,
                change: function () {
                    var value = this.value();
                    var ddlSchool = jQuery("#ddlSchools").data("kendoDropDownList");
                    ddlSchool.select(0);
                    if (value) {
                        LoadSchools(stateId, value, 0);
                        ddlSchool.enable();
                    } else {
                        ddlSchool.enable(false);
                    }
                }
            });

            
            if (pageLoad == 1) {
                var ddlCity = $("#ddlCities").data("kendoDropDownList");
                (ddlCity.select(1));
                LoadSchools(stateId, ddlCity.value(), pageLoad);
            }
        });
    }

    function LoadSchools(stateId, cityId, pageLoad) {
        var apiUrl = baseUrl + "/api/GetAllSchools/" + token + "?stateId=" + stateId + "&cityId=" + cityId + "&callback=?";

        var schoolData = new Array();

        $.getJSON(apiUrl, function (jsonResultObj) {

            // because our RESTful api is returning a dataset within an HttpResponseMessage,
            // we loop through result and create our data array here
            for (var i = 0; i < jsonResultObj.Table.length; i++) {
                var x = jsonResultObj.Table[i];
                schoolData.push(x);
                for (var j = 0; j < x.length; j++) {
                    var schoolId = x[j];
                    schoolData.push(schoolId);
                }
            }

            $("#ddlSchools").kendoDropDownList({
                optionLabel: "Select School...",
                dataTextField: "Text",
                dataValueField: "Value",
                dataSource: schoolData,
                change: function () {
                    //show chart based off selections
                }
            });

            if (pageLoad == 1) {
                var ddlSchool = $("#ddlSchools").data("kendoDropDownList");
                (ddlSchool.select(1));
                //show chart based off selections
            }
        });
    }
    
Tags
DropDownList
Asked by
Jon
Top achievements
Rank 1
Answers by
Georgi Krustev
Telerik team
Jon
Top achievements
Rank 1
Share this question
or