Creating a basic data grid with Kendo UI and AngularJS

All we need is an easy explanation of the problem, so here it is.

I’m experimenting with AngularJS. I want to show a basic Kendo Grid. I’m trying to do this using pure directives. With that in mind, I’ve looked at the Kendo UI / Angular JS project (https://github.com/kendo-labs/angular-kendo). Unfortunately, my

index.html:

<div>Products: {{products.length}}</div>
<div kendo-grid k-data-source="products" k-selectable="'row'"
  k-pageable='{ "refresh": true, "pageSizes": true }'
  k-columns='[
    { "field": "Name", "title": "Name"},
    { "field": "Department", "title": "Department"},
    { "field": "LastShipment", "title": "Last Shipment" }
  ]'>
</div>

controllers.js

function myController($scope) {
    console.log("initializing controller...");
    $scope.products = [
        { id:1, name:'Tennis Balls', department:'Sports', lastShipment:'10/01/2013' },
        { id:2, name:'Basket Balls', department:'Sports', lastShipment:'10/02/2013' },
        { id:3, name:'Oil', department:'Auto', lastShipment:'10/01/2013' },
        { id:4, name:'Filters', department:'Auto', lastShipment:'10/01/2013' },
        { id:5, name:'Dresser', department:'Home Furnishings', lastShipment:'10/01/2013' }
    ];
}

I’ve verified that I’ve wired up the controller properly. The activity count shows properly. However, the grid does not appear. I can’t figure out what I’m doing incorrectly.

Thank you for your help.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You can also setup a Kendo DataSource as an AngularJS Service using the Factory method and inject this into your Controller to conform to AngularJS best practices and patterns.

Full source code and live demo: http://goo.gl/6Z9jop

Customer.cshtml

@{
   ViewBag.Title = "Index";
}

<div>
   <h2 ng-cloak>{{title}}</h2>
   <div>
       <div class="demo-section">
           <div class="k-content" style="width: 100%">
               <div kendo-grid="grid"
                    k-sortable="true"
                    k-pageable="true"
                    k-filterable="true"
                    k-editable="'inline'"
                    k-selectable="true"
                    k-columns='[
                       { field: "CustomerID", title: "ID", width: "75px" },
                       { field: "CompanyName", title: "Company"},
                       { field: "ContactName", title: "Contact" },
                       { field: "ContactTitle", title: "Title" },
                       { field: "Address" },
                       { field: "City" },
                       { field: "PostalCode" },
                       { field: "Country" },
                       { field: "Phone" },
                       { field: "Fax" }]'
>
               </div>
               <style scoped>
                   .toolbar { padding: 15px; float: right; }
               </style>
           </div>
       </div>

       <script type="text/x-kendo-template" id="toolbar">
           <div>
               <div class="toolbar">
                   <button kendo-button ng-click="edit(this)"><span class="k-icon k-i-tick"></span>Edit</button>
                   <button kendo-button ng-click="destroy(this)"><span class="k-icon k-i-tick"></span>Delete</button>
                   <button kendo-button ng-click="details(this)"><span class="k-icon k-i-tick"></span>Edit Details</button>
               </div>
               <div class="toolbar" style="display:none">
                   <button kendo-button ng-click="save(this)"><span class="k-icon k-i-tick"></span>Save</button>
                   <button kendo-button ng-click="cancel(this)"><span class="k-icon k-i-tick"></span>Cancel</button>
               </div>
           </div>
       </script>
   </div>
</div>

customerController.js

'use strict';

northwindApp.controller('customerController',
    function ($scope, $rootScope, $location, customerDataSource)
    {
        customerDataSource.filter({}); // reset filter on dataSource everytime view is loaded

        var onClick = function (event, delegate)
        {
            var grid = event.grid;
            var selectedRow = grid.select();
            var dataItem = grid.dataItem(selectedRow);

            if (selectedRow.length > 0)
            {
                delegate(grid, selectedRow, dataItem);
            }
            else
            {
                alert("Please select a row.");
            }
        };

        $scope.toolbarTemplate = kendo.template($("#toolbar").html());

        $scope.save = function (e)
        {
            onClick(e, function (grid)
            {
                grid.saveRow();
                $(".toolbar").toggle();
            });
        };

        $scope.cancel = function (e)
        {
            onClick(e, function (grid)
            {
                grid.cancelRow();
                $(".toolbar").toggle();
            });
        },

        $scope.details = function (e)
        {
            onClick(e, function (grid, row, dataItem)
            {
                $location.url('/customer/edit/' + dataItem.CustomerID);
            });
        },

        $scope.edit = function (e)
        {
            onClick(e, function (grid, row)
            {
                grid.editRow(row);
                $(".toolbar").toggle();
            });
        },

        $scope.destroy = function (e)
        {
            onClick(e, function (grid, row, dataItem)
            {
                grid.dataSource.remove(dataItem);
                grid.dataSource.sync();
            });
        },

        $scope.onChange = function (e)
        {
            var grid = e.sender;

            $rootScope.lastSelectedDataItem = grid.dataItem(grid.select());
        },

        $scope.dataSource = customerDataSource;

        $scope.onDataBound = function (e)
        {
            // check if there was a row that was selected
            if ($rootScope.lastSelectedDataItem == null)
            {
                return;
            }

            var view = this.dataSource.view(); // get all the rows

            for (var i = 0; i < view.length; i++)
            {
                // iterate through rows
                if (view[i].CustomerID == $rootScope.lastSelectedDataItem.CustomerID)
                {
                    // find row with the lastSelectedProductd
                    var grid = e.sender; // get the grid

                    grid.select(grid.table.find("tr[data-uid='" + view[i].uid + "']")); // set the selected row
                    break;
                }
            }
        };
    });

customerDataSource.js

'use strict';

northwindApp.factory('customerDataSource',
    function (customerModel)
    {
        var crudServiceBaseUrl = "/odata/Customer";

        return new kendo.data.DataSource({
            type: "odata",
            transport: {
                read: {
                    async: false,
                    url: crudServiceBaseUrl,
                    dataType: "json"
                },
                update: {
                    url: function (data)
                    {
                        return crudServiceBaseUrl + "(" + data.CustomerID + ")";
                    },
                    type: "put",
                    dataType: "json"
                },
                destroy: {
                    url: function (data)
                    {
                        return crudServiceBaseUrl + "(" + data.CustomerID + ")";
                    },
                    dataType: "json"
                }
            },
            batch: false,
            serverPaging: true,
            serverSorting: true,
            serverFiltering: true,
            pageSize: 10,
            schema: {
                data: function (data) { return data.value; },
                total: function (data) { return data["odata.count"]; },
                model: customerModel
            },
            error: function (e)
            {
                alert(e.xhr.responseText);
            }
        });
    });

Method 2

It looks as if the field names are spelled wrong. The following works for me:

<div kendo-grid k-data-source="products" k-selectable="'row'"
k-pageable='{ "pageSize": 2, "refresh": true, "pageSizes": true }'
  k-columns='[
    { "field": "name", "title": "Name"},
    { "field": "department", "title": "Department"},
    { "field": "lastShipment", "title": "Last Shipment" }
  ]'>
</div>

Here is a live demo: http://jsbin.com/odeQAfI/2/edit

To avoid the NaN message in the pager you need to make the products field to be a Kendo DataSource:

function MyController($scope) {
   $scope.products = new kendo.data.DataSource({ 
     data: [
        { id:1, name:'Tennis Balls', department:'Sports', lastShipment:'10/01/2013' },
        { id:2, name:'Basket Balls', department:'Sports', lastShipment:'10/02/2013' },
        { id:3, name:'Oil', department:'Auto', lastShipment:'10/01/2013' },
        { id:4, name:'Filters', department:'Auto', lastShipment:'10/01/2013' },
        { id:5, name:'Dresser', department:'Home Furnishings', lastShipment:'10/01/2013' }
    ],
     pageSize: 2
  });
}

Here is a live demo: http://jsbin.com/ODElUfO/2/edit

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply