Search code examples
jquerykendo-uitelerikkendo-gridkendo-dropdown

Rebind DropDownList in KendoGrid, depending on Value Selected in other DropDownList on the same row


This is a common problem, but i dont know how to figure it out with KendoUI widgets and Javascript. I have a KendoGrid whose datasource is coming from an AJAX call to a Web Services. Data is bound to the columns. Two columns (Source and Destination) are two drop down lists:

enter image description here

Each column is defined as

 if (stringStartsWith(colTitle, 'Source')) {
                    columns.push({
                        field: dataItem.replace(/\s+/g, ''),
                        title: colTitle,
                        width: 150,
                        locked: false,
                        editor: sourceDropDownEditor,
                        //template: "#=SourcetankIdentifier#",
                        attributes: { style: "text-align: left" },
                        type: "text"
                    });
                }

And the SourceDropDownEditor is as follow:

function sourceDropDownEditor(container, options) {
    $('<input id="sourcesDropDownList" required data-text-field="Source" data-value-field="Source" data-bind="value:' + options.field + '"/>')
        .appendTo(container)
        .kendoDropDownList({
            dataTextField: "Source",
            dataValueField: "Source",
            dataSource: Sources           
        });
}

The same is done for the Destination Drop Down List.

Now, what i want is, when the user clicks into the Edit button (Grid is defined with In-Line Edit) and choose a certain Source Value from the Source DDL; the list into the Destination DDL must change according to this value.

I wrote a function for retrieving the correct list, depending from the value chosen in the Source DDL. But what i CANNOT do, is to get the Destion DLL of THAT row and to set the Datasource accordingly.

More Details as requested:

Grid is built dynamically:

function generateGrid(JSONData) {

    var model = generateModel(JSONData, selectedMenu);
    var columns = generateColumns(model);
    var data = generateData(gridData, columns);  

   var grid = $("#mainGrid").kendoGrid({              
        edit: function (e) {            
           ..
        },
        dataSource: {
            data: data,
            schema: {
                model: model
            },
            sort:   {
                field: defaultSort.replace(/\s+/g, ''),
                dir: "desc"               
            }
        },
        toolbar: [
            ..
        ],
        columns: columns,        
        editable: "inline",       
        sortable: true,                 
        resizable: true,
        filterable: true,
        selectable: "multiple",
        cancel: function(e) {
            $('#mainGrid').data('kendoGrid').dataSource.cancelChanges();
        },

KENDO DOJO

Here dojo.telerik.com/uXeKa . It reflects basically the grid template and the column fields

FINAL SOLUTION

Final solution is here: dojo.telerik.com/uXeKa/2 . Don't need to add anything into the Edit function of the Grid. Just need to implement onChange function of the Source DDL, and to set the datasource of the destination.


Solution

  • Please try with the below code snippet.

    <!DOCTYPE html>
    <html>
    <head>
        <title>Jayesh Goyani</title>
        <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.common.min.css">
        <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.rtl.min.css">
        <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.default.min.css">
        <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.mobile.all.min.css">
    
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
        <script src="http://kendo.cdn.telerik.com/2015.3.1111/js/angular.min.js"></script>
        <script src="http://kendo.cdn.telerik.com/2015.3.1111/js/jszip.min.js"></script>
        <script src="http://kendo.cdn.telerik.com/2015.3.1111/js/kendo.all.min.js"></script>
    </head>
    <body>
    
        <div id="grid">
        </div>
        <script>
    
    
    
            var sources = [];
            var destinations = [];
    
            var products = [{
                ProductID: 1,
                ProductName: "Chai",
                SourceID: 1,
                DestinationID: 1,
    
            }, {
                ProductID: 2,
                ProductName: "Chang",
                SourceID: 2,
                DestinationID: 1,
    
            }, {
                ProductID: 3,
                ProductName: "Aniseed Syrup",
                SourceID: 3,
                DestinationID: 2,
    
            }, {
                ProductID: 4,
                ProductName: "Chef Anton's Cajun Seasoning",
                SourceID: 4,
                DestinationID: 2,
            }, {
                ProductID: 5,
                ProductName: "Chef Anton's Gumbo Mix",
                SourceID: 4,
                DestinationID: 2,
            }];
    
            $(document).ready(function () {
                $("#grid").kendoGrid({
                    dataSource: {
                        data: products,
                        schema: {
                            model: {
                                id: "ProductID",
                                fields: {
                                    ProductName: { type: "string" }
                                }
                            }
                        },
                        pageSize: 10
                    },
                    sortable: true,
                    edit: onGridEdit,
                    filterable: true,
                    pageable: {
                        input: true,
                        numeric: false
                    },
                    columns: [
                        { field: "ProductName" },
                         { field: "SourceID", title: "SourceID", values: sources },
                         { field: "DestinationID", title: "DestinationID", values: destinations },
                         { command: ["edit", "destroy"], title: "&nbsp;" }
    
                    ],
                    editable: "inline"
                });
            });
    
            var destinationID = 0;
    
            function onGridEdit(arg) {
                destinationID = arg.model.DestinationID;
                $.ajax({
                    url: "http://localhost:3470/Home/GetSource",
                    type: 'GET',
                    success: function (data) {
                        var sourceDDL = $(arg.container).find("select[name^='SourceID']").data("kendoDropDownList");
                        sourceDDL.bind("change", onChange);
                        sourceDDL.setDataSource(data);
                        sourceDDL.value(arg.model.SourceID);
                        onChange();
                    }
                });
    
            }
    
            function onChange(arg) {
                var sourceid = $("select[name^='SourceID']").data("kendoDropDownList").value();
    
    
    
                $.ajax({
                    url: "http://localhost:3470/Home/GetDestination",
                    type: 'GET',
                    data: { SourceID: sourceid },
                    success: function (data) {
                        var destinationDDL = $("select[name^='DestinationID']").data("kendoDropDownList");
                        destinationDDL.setDataSource(data);
    
                        if (arg) {
                            // Please uncomment below code if you want to reset ddl value on sourceDDl value change
                            // destinationDDL.select(-1);
                        }
                        else {
                            destinationDDL.value(destinationID);
                            destinationID = 0;
                        }
                    }
                });
            }
        </script>
    </body>
    </html>
    

    For reference:-

    public class Source
    {
        public int value { get; set; }
        public string text { get; set; }
    }
    
    public class Destination
    {
        public int value { get; set; }
        public string text { get; set; }
    }
    
    .....
    .....
    public ActionResult GetSource()
    {
        List<Source> list = new List<Source>();
    
        list.Add(new Source() { value = 1, text = "cat1" });
        list.Add(new Source() { value = 2, text = "cat2" });
        list.Add(new Source() { value = 3, text = "cat3" });
        list.Add(new Source() { value = 4, text = "cat4" });
        list.Add(new Source() { value = 5, text = "cat5" });
    
        return Json(list, JsonRequestBehavior.AllowGet);
    }
    
    public ActionResult GetDestination(int? SourceID)
    {
        List<Destination> list = new List<Destination>();
    
        list.Add(new Destination() { value = 1, text = "des1_" + Convert.ToString(SourceID) });
        list.Add(new Destination() { value = 2, text = "des2_" });
        list.Add(new Destination() { value = 3, text = "des3_" });
        list.Add(new Destination() { value = 4, text = "des4_" });
        list.Add(new Destination() { value = 5, text = "des5_" });
    
        return Json(list, JsonRequestBehavior.AllowGet);
    }
    

    Update 1: (Based on your editor I have updated jquery selector statement)

    function onGridEdit(arg) {
        var sourceDDL = $(arg.container).find("input[id^='sourcesDropDownList']").data("kendoDropDownList");
    }
    function onChange(arg) {
        var sourceid = $("input[id^='sourcesDropDownList']").data("kendoDropDownList").value(); 
        var destinationDDL = $("input[id^='destinationsDropDownList']").data("kendoDropDownList");  
    }
    

    Let me know if any concern.