Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a basic data grid with Kendo UI and AngularJS

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.

like image 368
Node Newbie Avatar asked Oct 17 '13 15:10

Node Newbie


People also ask

What is Kendo UI for Angular?

Kendo UI for Angular is a separate suite of native Angular 2 UI components. The Kendo UI for Angular Roadmap page provides information about the development plans of the team with regard to new components and features. The Telerik blogs are an additional source for the latest updates on Kendo UI for Angular.

Which grid is best for Angular?

Generic UI Data Grid is one of the best free grid library. It offers many built-in features that work out of the box: editing, sorting, pagination, theming, summaries, column configuration, and many more.


2 Answers

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);
            }
        });
    });
like image 186
LeLong37 Avatar answered Sep 18 '22 16:09

LeLong37


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

like image 34
Atanas Korchev Avatar answered Sep 21 '22 16:09

Atanas Korchev