5

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.

2 Answers 2

11

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://genericunitofworkandrepositories.codeplex.com/

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);
            }
        });
    });
Sign up to request clarification or add additional context in comments.

Comments

6

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

2 Comments

How do I update the data using an AngularJS $http request? I prefer to use AngularJS remote calls because of the testing / mocking support they provide.
@MikeHopper: See the documentation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.