jqueryasp.net-mvckendo-uikendo-combobox

Populating kendo MVC combo box based on another kendo combobox


I am trying to populate the value of one combo box based on selection of another combo box. I am using kendo mvc combo box in MVC 5 application. In my case , I am trying to populate the Sales Office combo box based on selection of SalesOrganisation combo box.In order to do that I would need to call the controller method of SalesOffice combo and pass the country code value. I have written a ajax method on the change event of the drop down control of the Sales Organisation. Its calling the controller method. I can see the method firing but when I do an alert on the data in the javascript code, the value is showing [object] [object].The status however is showing success Not sure what is wrong. How do I get the Sales Office dropdown populated

Combobox

  <div class="form-group">
                @Html.LabelFor(model => model.Company, htmlAttributes: new { @class = "control-label col-md-4" })
                <div class="col-md-6">
                    <div class="editor-field">
                        @(Html.Kendo().ComboBoxFor(model => model.Company)
                            .Name("SalesOrganisation")
                            .HtmlAttributes(new { style = "width:300px" })
                            .DataTextField("Company")
                            .DataValueField("CountryCode")

                            .DataSource(dataSource => dataSource
                            .Read(read => read.Action("RequestHeader_SalesOrganisation", "Request").Type(HttpVerbs.Post))

                            )
                             .Events(e =>
                             {
                                 e.Change("onChange");
                             })
                        )
                    </div>
                    @Html.ValidationMessageFor(model => model.Company, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="clearfix"></div>
            <div class="form-group">
                @Html.LabelFor(model => model.SalesOffice, htmlAttributes: new { @class = "control-label col-md-4" })
                <div class="col-md-6">
                    <div class="editor-field">
                        @(Html.Kendo().ComboBoxFor(model => model.SalesOffice)
                            .Name("SalesOffice")
                            .HtmlAttributes(new { style = "width:300px" })
                            .DataTextField("SalesOffice")
                            .DataValueField("SalesOfficeID")

                            .DataSource(dataSource => dataSource
                            .Read(read => read.Action("RequestHeader_SalesOffice", "Request").Type(HttpVerbs.Post))
                            )
                        )
                    </div>
                    @Html.ValidationMessageFor(model => model.SalesOffice, "", new { @class = "text-danger" })
                </div>
            </div>

SalesOffice controller method

    public ActionResult RequestHeader_SalesOffice(string id)
            {
                var response = requestRepository.GetSalesOffice(id).AsQueryable().ProjectTo<SalesOfficeViewModel>();

                var jsonResult = Json(response, JsonRequestBehavior.AllowGet);
                jsonResult.MaxJsonLength = int.MaxValue;
                return jsonResult;
            }

Jquery

 function onChange() {

        alert($('#SalesOrganisation').val());

        var ServiceUrl = "/CC.GRP.MCRequest/Request/RequestHeader_SalesOffice?id=" + $('#SalesOrganisation').val();
        var content = '';
        $.support.cors = true;

        $.ajax({
            type: 'Post',
            url: ServiceUrl,
            async: true,
            cache: false,
            crossDomain: true,
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            error: function (xhr, err) {
            },
            success: function (data, status) {
                $('#SalesOffice').val(data);
                alert(data);
                alert(status);
            }
        });
    }

Solution

  • So based on your specific scenario. The top combobox should control the select items from the second combobox. In this instance using the cascading feature of the combobox will be the simplest way and also reduce the amount of code you have.

    So the top combobox we can get rid of the change event.

    The second one we change slightly to this:

    @(Html.Kendo().ComboBoxFor(model => model.SalesOffice)
                                .Name("SalesOffice")
                                .HtmlAttributes(new { style = "width:300px" })
                                .DataTextField("SalesOffice")
                                .DataValueField("SalesOfficeID")
    
                                .DataSource(dataSource => dataSource
                                    .Read(read =>
                                    {
                                        read.Action("RequestHeader_SalesOffice", "Request")
                                            .Type(HttpVerbs.Post)
                                            .Data("GetFilterOption"); <-- This Bit
                                    })
                                    ).CascadeFrom("SalesOrganisation") //<--This Bit
    
    )
    

    Then we add the javascript function called GetFilterOption which returns the selected value from your top combobox.

    function GetFilterOption(){
        return { id: $('#SalesOrganisation').val() }
    
    }
    

    This will then return back the new result set for you to bind to the combobox and allow you to select the value from the newly gathered results.

    The reason your current solution is not working is that you are bringing back your select list and binding it to the value and not the underlying datasource.

    So if you wanted to change just your javascript code you could do something like this:

    success: function (data, status) {
                  //  $('#SalesOffice').val(data); <-- FROM THIS TO
                    $('#SalesOffice').data('kendoComboBox').setDataSource(data); 
                    alert(data);
                    alert(status);
                }
    

    Hopefully that answers your question. Any issues let me know and I will update the answer to reflect any changes.

    EDIT

    After much trial and Error with Tom through chat we got to the solution to add .Filtering("Contains")

    and then .ServerFiltering(true) within the combobox so ending up with this:

    @(Html.Kendo().ComboBoxFor(model => model.SalesOffice)
                                .Name("SalesOffice")
                                .HtmlAttributes(new { style = "width:300px" })
                                .DataTextField("SalesOffice")
                                .DataValueField("SalesOfficeID")
                                .Filter("Contains")
                                .DataSource(dataSource => dataSource
                                    .Read(read =>
                                    {
                                        read.Action("RequestHeader_SalesOffice", "Request")
                                            .Type(HttpVerbs.Post)
                                            .Data("GetFilterOption"); <-- This Bit
                                    })
                                     .ServerFiltering(true)
                                    ).CascadeFrom("SalesOrganisation") //<--This Bit
    
    )