2

Following is a kendo grid sample with detailInit:

enter image description here

My requirement is that on sorting a column in a particular sub-grid(detailInit), its header i.e. FirstName field should be changed like shown below:

enter image description here

Just that particular sub-grid's header should be changed. I have tried by registering onclick event in databound function of detailInit but unable to find the column header and change it :

$("th[role='columnheader']").on("click", function (ev) {

// access clicked column in sub- grid
// change master row's title
    };

Please someone suggest me a solution as I am new to kendo grid, js, HTML, so not aware of many functions.

Any help would be much appreciated.

Please find my code below :

 <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css" />
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css" />
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css" />
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css" />

    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script>
</head>
<body>

    <div id="grid"></div>
    <script>

        var element = $("#grid").kendoGrid({
            dataSource: {
                type: "odata",
                transport: {
                    read: "http://demos.kendoui.com/service/Northwind.svc/Employees"
                },
                pageSize: 6,
                serverPaging: true,
                serverSorting: true
            },
            height: 450,
            sortable: true,
            pageable: true,
            detailInit: detailInit,
            dataBound: function () {
                this.expandRow(this.tbody.find("tr.k-master-row").first());
            },
            columns: [
              {
                  field: "FirstName",
                  title: " "
              }
            ]
        }).on("click", ".btn-refresh", function (e) {
            debugger;
            var childGrid = $(e.target).closest(".k-grid").data("kendoGrid");
            childGrid.dataSource.read();
        });

        function detailInit(e) {
            $("<div/>").appendTo(e.detailCell).kendoGrid({
                dataSource: {
                    type: "odata",
                    transport: {
                        read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
                    },
                    serverPaging: true,
                    serverSorting: true,
                    serverFiltering: true,
                    pageSize: 6,
                    filter: { field: "EmployeeID", operator: "eq", value: e.data.EmployeeID }
                },
                scrollable: false,
                sortable: true,
                pageable: true,
                toolbar: [{ text: "Refresh", className: "btn-refresh" }],
                columns: [
                  { field: "OrderID", width: 70 },
                  { field: "ShipCountry", title: "Ship Country", width: 100 },
                  { field: "ShipAddress", title: "Ship Address" },
                  {
                      field: "ShipName", title: "Ship Name", width: 200
                  }
                ]
            });
        }
    </script>
</body>
</html>
user2091061
  • 879
  • 3
  • 10
  • 32

1 Answers1

1

There are, at least, two main ways to do this. However, I didn't understand if you want to:

a) Clear all the "updated" texts, letting only the last clicked with it

b) Keep all them tracked, putting the text as the user sorts the grids

Anyway, let's see both strategies.

Using jQuery only

a)

element.on('click', "th[role='columnheader']", function(e) {
    // always remove all, to put again in the right place
    $("strong[attr-id=updated]").remove(); 

    var firstNameCell = $(this)
        .closest("tr.k-detail-row") // Finds the closest detail row ...
        .prev("tr.k-master-row") // ... in order to get the first previous row of class "k-master-row" (which stores the FirstName)
        .find("td[role='gridcell']"); // and, then, get the td gridcell

    firstNameCell.append("<strong attr-id='updated'> - Address updated</strong>");
});

b)

element.on('click', "th[role='columnheader']", function(e) {
    var firstNameCell = $(this)
        .closest("tr.k-detail-row")
        .prev("tr.k-master-row")
        .find("td[role='gridcell']");

    // Check if the msg already exits, to not duplicate it
    if (!(firstNameCell).find('strong[attr-id=updated]').length) {
        firstNameCell.append("<strong attr-id='updated'> - Address updated</strong>");
    }
});

The attr-id helps to identify the text element along the page, once it's not a good practice using id (only once per page).

Using KendoUI JavaScript objects

That's not the best way, since you cannot append HTML like we did with jQuery approach. Also, you'll have to refresh the whole table every time a sort is made.

That's why I'll show only case b)

element.on('click', "th[role='columnheader']", function(e) {
    var masterRow = $(this)
        .closest("tr.k-detail-row")
        .prev("tr.k-master-row"); // Finds the closest master row ...

    var rowIndex = $("tr.k-master-row").index(masterRow); // ... gets the index of it among all the others
    kendoGrid = element.data('kendoGrid');
    var firstName = kendoGrid.dataSource._data[rowIndex].FirstName; // gets current name based on the index

    if (!firstName.includes('Address updated')) {
        selectedCell = rowIndex; // sets the index to be used when grid refreshes
        kendoGrid.dataSource._data[rowIndex].FirstName = firstName + " - Address updated";
        kendoGrid.refresh(); // refreshed the whole grid
    }
});

Still, in order to make KendoUI to expand the right row every time its grids are refreshed, you have to create the global variable selectedCell and check at dataBound function whether it has a value or not:

dataBound: function () {
    if (selectedCell) {
        this.expandRow(this.tbody.find("tr.k-master-row:eq(" + selectedCell + ")"));
    } else {
        this.expandRow(this.tbody.find("tr.k-master-row").first());
    }
},

Here, you can see more about Kendo Grid refreshing: Reloading/refreshing Kendo Grid

Hope it helps! :)

Community
  • 1
  • 1
diogo
  • 3,769
  • 1
  • 24
  • 30