Jonathan
Jonathan

Reputation: 1981

Kendo grid events not working with delegates

I have a page that may create several grids at any time. I am trying to set a single event handler for all of them by adding a delegate for the groupor dataBoundevent but it never triggers.

I am trying this

$(document).on('dataBound', 'div.k-grid', onGridDataBound);

Is it possible to do this without hooking on to each individual grid's settings when it is being created or without having to bind the event per grid?

Upvotes: 2

Views: 1419

Answers (3)

dimodi
dimodi

Reputation: 4139

I can suggest you two alternatives:

  1. Override the Grid prototype (before creating any Grids) and inject the event handler(s) directly there:

    function onGridDataBound(e) {
       alert(e.sender.wrapper.attr("id") + " was databound");
    }
    
    kendo.ui.Grid.fn.options.dataBound = onGridDataBound;
    

Here is a full example:

<!DOCTYPE html>
<html>
  <head>
    <base href="http://demos.telerik.com/kendo-ui/grid/remote-data-binding">
    <style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
    <title></title>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common.min.css" />
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.default.min.css" />

    <script src="https://kendo.cdn.telerik.com/2017.2.621/js/jquery.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
  </head>
  <body>

    <p>Grid 1</p>
    <div id="grid1"></div>
    
    <p>Grid 2</p>
    <div id="grid2"></div>

    <script>
      
      function onGridDataBound(e) {
        alert(e.sender.wrapper.attr("id") + " was databound");
      }
      
      $(function() {
        
        kendo.ui.Grid.fn.options.dataBound = onGridDataBound;

        var gridOptions = {
          dataSource: {
            type: "odata",
            transport: {
              read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
            },
            pageSize: 5,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
          },
          height: 200,
          pageable: true,
          columns: [{
            field:"OrderID",
            filterable: false
          }, {
            field: "ShipName",
            title: "Ship Name"
          }, {
            field: "ShipCity",
            title: "Ship City"
          }]
        };

        $("#grid1").kendoGrid(gridOptions);
        $("#grid2").kendoGrid(gridOptions);

      });
    </script>

  </body>
</html>

  1. Create a custom Kendo UI widget that has the desired event handlers attached initially.

      (function($) {
        var kendo = window.kendo,
            ui = kendo.ui,
            Grid = ui.Grid
    
        var MyGrid = Grid.extend({
          init: function(element, options) {
    
            Grid.fn.init.call(this, element, options);
    
            this.bind("dataBound", onGridDataBound);
    
          },
    
          options: {
            name: "MyGrid"
          }
        });
    
        ui.plugin(MyGrid);
    
      })(jQuery);
    
      function onGridDataBound(e) {
        alert(e.sender.wrapper.attr("id") + " was databound");
      }
    

Here is a full example:

<!DOCTYPE html>
<html>
  <head>
    <base href="http://demos.telerik.com/kendo-ui/grid/remote-data-binding">
    <style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
    <title>Kendo UI default event handlers via prototype</title>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common.min.css" />
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.default.min.css" />

    <script src="https://kendo.cdn.telerik.com/2017.2.621/js/jquery.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
  </head>
  <body>

    <p>Grid 1</p>
    <div id="grid1"></div>

    <p>Grid 2</p>
    <div id="grid2"></div>

    <script>

      (function($) {
        var kendo = window.kendo,
            ui = kendo.ui,
            Grid = ui.Grid

        var MyGrid = Grid.extend({
          init: function(element, options) {

            Grid.fn.init.call(this, element, options);

            this.bind("dataBound", onGridDataBound);

          },

          options: {
            name: "MyGrid"
          }
        });

        ui.plugin(MyGrid);

      })(jQuery);

      function onGridDataBound(e) {
        alert(e.sender.wrapper.attr("id") + " was databound");
      }

      $(function() {

        var gridOptions = {
          dataSource: {
            type: "odata",
            transport: {
              read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
            },
            pageSize: 5,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
          },
          height: 200,
          pageable: true,
          columns: [{
            field:"OrderID",
            filterable: false
          }, {
            field: "ShipName",
            title: "Ship Name"
          }, {
            field: "ShipCity",
            title: "Ship City"
          }]
        };

        $("#grid1").kendoMyGrid(gridOptions);
        $("#grid2").kendoMyGrid(gridOptions);

      });
    </script>

  </body>
</html>

Upvotes: 1

Jonathan
Jonathan

Reputation: 1981

So I ended up doing something really inefficient to get this done. Since only the default browser events seem to be delegated, I ended up adding a binder for mousedown on any of the grid headers. The handler for that would then bind to the group event for that grid since then it is guaranteed to be on the page.

var boundGrids = [];
function onGridGroup(e) {
    //Grid group code
};

function onGridHeaderClick(e) {
    var grid = $(this).closest('.k-grid').data('kendoGrid');
    if (!grid._attachedGroup) {
        grid._attachedGroup = true;
        boundGrids.push(grid);
        grid.bind('group', onGridGroup);
    }
};

$(document).on('mousedown', '.k-grid th a.k-link', onGridHeaderClick);

Upvotes: 1

Alag
Alag

Reputation: 1408

Check this thread. Only difference is that in your case you got multiple grids. Due that I would do something like:

var grids = $('div.k-grid');
grids.each(function(e) {
    var grid = $(this).data('kendoGrid');
    grid.bind("dataBound", function () {
        alert('Databounded');
    });
});

Upvotes: 0

Related Questions