This is a migrated thread and some comments may be shown as answers.

Creating a kendo-grid with reusable options using AngularJS

9 Answers 672 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Access
Top achievements
Rank 2
Access asked on 02 May 2014, 10:58 AM
How to create a kendo-grid with reusable options using AngularJS?

Besides the default settings, the grid must include a checkbox column dynamically with the option to select all rows. Methods to treat the selections should be part of the directive and, somehow, I should be able to access the rows selected in controller.

Another important behavior is to keep a reference to the grid:

// In the controller : $scope.grid
<div kendo-grid="grid" k-options="gridOptions"></div>

Below an initial path that I imagined, but it is not 100% working because AngularJS not compile information from checkbox column, so do not call the methods of the controller directive. At the same time I'm not sure where force $compile in this code.

myApp.directive('myApp', ['$compile', function ($compile) {
    var directive = {
        restrict: 'A',
        replace: true,
        template: '<div></div>',
        scope: {
            gridConfiguration: '='
        },
        controller: function ($scope) {
 
            $scope.gridIds = [];
            $scope.gridIdsSelected = [];
 
            var updateSelected = function (action, id) {
                if (action === 'add' && $scope.gridIdsSelected.indexOf(id) === -1) {
                    $scope.gridIdsSelected.push(id);
                }
                if (action === 'remove' && $scope.gridIdsSelected.indexOf(id) !== -1) {
                    $scope.gridIdsSelected.splice($scope.gridIdsSelected.indexOf(id), 1);
                }
            };
 
            $scope.updateSelection = function ($event, id) {
                var checkbox = $event.target;
                var action = (checkbox.checked ? 'add' : 'remove');
                updateSelected(action, id);
            };
 
            $scope.isSelected = function (id) {
                return $scope.gridIdsSelected.indexOf(id) >= 0;
            };
 
            $scope.selectAll = function ($event) {
                var checkbox = $event.target;
                var action = (checkbox.checked ? 'add' : 'remove');
                for (var i = 0; i < $scope.gridIds.length; i++) {
                    var id = $scope.gridIds[i];
                    updateSelected(action, id);
                }
            };
        },
        link: function ($scope, $element, $attrs) {
            var baseColumns = [
                {
                    headerTemplate: '<input type="checkbox" id="selectAll" ng-click="selectAll($event)" ng-checked="isSelectedAll()">',
                    template: '<input type="checkbox" name="selected" ng-checked="isSelected(#=Id#)" ng-click="updateSelection($event, #=Id#)">',
                    width: 28
                }
            ];
 
            for (var i = 0; i < $scope.gridConfiguration.columns.length; i++) {
                var column = $scope.gridConfiguration.columns[i];
                baseColumns.push(column);
            }
 
            var gridOptions = {...};
 
            var grid = $element.kendoGrid(gridOptions).data("kendoGrid");;
            $scope.$parent[$attrs[directive.name]] = grid;
        }
    };
 
    return directive;
}]);

9 Answers, 1 is accepted

Sort by
0
Mihai
Telerik team
answered on 05 May 2014, 08:34 AM
Hi Rodrigo,

Sorry for the late reply.

I created a sample directive for you, here's the working example: http://embed.plnkr.co/fQhNUGHJ3iAYiWTGI9mn/preview

To see the code, click "Code" in the top-right toolbar and look at script.js.

The directive activates on "my-grid" attribute and inserts a new column to the specified grid options.  In that column it adds one checkbox per each item, and a checkbox in the header to (un)select all.  The selected items get a "selected" property in the model, to find out which items are selected you can do something like this:

var selectedItems = $scope.grid.dataSource.data().filter(function(item){
    return item.selected;
});

Notice how we can use the dataItem variable in scope to access the current item from the column template.

Hope this helps.

Regards,
Mihai
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Access
Top achievements
Rank 2
answered on 06 May 2014, 11:37 AM
Mihai, the problem with this solution is that the default options are configured on the controller, and I can not reuse the grid settings, such as sortable, resizable, pageable, etc...
0
Mihai
Telerik team
answered on 06 May 2014, 11:55 AM
Hi,

Replied on GitHub.  Let's agree to continue the conversation only there. :-)

Regards,
Mihai
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Rajesh
Top achievements
Rank 1
answered on 23 Aug 2014, 07:37 AM
Hi Mihai,

This is exactly the directive I am looking for.

However I am creating my kendo grid slightly differently.

<div selectable-grid kendo-grid="availableDevicesGrid" k-options="availableDevicesKOptions"

                        k-data-source="availableDevicesKDataSource"
                        k-sortable="true"
                        k-pageable="true"
                        k-selectable="'multiple, row'"
                        k-columns="[

                            {
                                field: 'hostname',
                                title: 'Host Name',
                                width: '120px',
                            },

                            {
                                field: 'ipAddress',
                                title: 'Ip Address',
                                width: '120px'
                            },
                            {
                                field: 'Tags',
                                title: 'Tags',
                                width: '120px'
                            },
                            {
                                field: 'Apps',
                                title: 'Apps',
                                width: '120px'
                            }
                        ]"
                    ></div>

Notice how k-columns is not on the k-options as it is in your case.

I have slightly changed your directive to
app.directive('selectableGrid', ['$compile', function ($compile) {
    var directive = {
        restrict: 'A',
        scope: true,
        controller: function ($scope) {
            window.crap = $scope;
            $scope.toggleSelectAll = function(ev) {
                var grid = $(ev.target).closest("[kendo-grid]").data("kendoGrid");
                var items = grid.dataSource.data();
                items.forEach(function(item){
                    item.selected = ev.target.checked;
                });
            };
        },
        link: function ($scope, $element, $attrs) {
            var columns = angular.extend({}, $scope.$eval($attrs.kColumns));
            columns.unshift({
                template: "<input type='checkbox' ng-model='dataItem.selected' />",
                title: "<input type='checkbox' title='Select all' ng-click='toggleSelectAll($event)' />",
                width: 50
            });
        }
    };
    return directive;
}]);
I am running into an error that says TypeError: undefined is not a function
at directive.link (http://bgl-c3vm8:3333/appmgr/scripts/directives/angularKendoGridDirective.js:21:21)


Could you please tell me what changes I could do to use your component ? Thanks a ton in advance.

0
Rajesh
Top achievements
Rank 1
answered on 23 Aug 2014, 08:03 AM
Trust I need to share more details for I am using a rowTemplate here
$scope.availableDevicesKOptions = {

        headerTemplate:'<label><input type="checkbox" ng-model="selectedDevices.isSelectAllChecked"></label>',
        rowTemplate: "<tr data-uid='#: uid #'>" +
                        "<td>{{dataItem.hostname}}</td>" +
                        "<td>{{dataItem.ipAddress}}</td>" +
                        "<td>" +
                            "<div class='tag-input-ctn'>" +
                                "<div ng-repeat='(key, tag) in dataItem.tags' class='input-tag'>{{tag.name}}</div>" +
                            "</div>" +
                        "</td>" +
                        "<td>" +
                            "<div class='tag-input-ctn'>" +
                                "<div ng-repeat='(key, app) in dataItem.apps' class='input-tag'>{{app.name}}</div>" +
                            "</div>" +
                        "</td>" +
                     "</tr>",
        altRowTemplate: "<tr class='k-alt'>" +
                            "<td align='center'>{{dataItem.selectAll}} <input type='checkbox'></td>" +
                            "<td>{{dataItem.hostname}}</td>" +
                            "<td>{{dataItem.ipAddress}}</td>" +
                            "<td>" +
                                "<div class='tag-input-ctn'>" +
                                    "<div ng-repeat='(key, tag) in dataItem.tags' class='input-tag'>{{tag.name}}</div>" +
                                "</div>" +
                            "</td>" +
                            "<td>" +
                                "<div class='tag-input-ctn'>" +
                                    "<div ng-repeat='(key, app) in dataItem.apps' class='input-tag'>{{app.name}}</div>" +
                                "</div>" +
                            "</td>" +
                        "</tr>"
    };

with the following modifications. I have no errors in the directive creation but no new column gets added.
0
Rajesh
Top achievements
Rank 1
answered on 23 Aug 2014, 07:11 PM
I have this working without a directive now.

I had to move the k-columns into javascript to be able to add a checkbox to the template (How I wish I could have left it in the html)
I realize that in kendo-grid="grid", grid must already be defined as a scope variable.
0
Zedmed
Top achievements
Rank 1
answered on 29 Aug 2014, 06:10 AM
With reference to the example plunkr here:
http://plnkr.co/edit/uq62XqadunzBKJOrR9uT?p=preview

The checkbox selection is independent of the grid's row selections. How can you keep these two in sync, especially when multiple row selection is enabled on the grid?
0
Lilly
Top achievements
Rank 1
answered on 03 Feb 2016, 06:32 PM

hi Mihai,

Your directive is exactly what was looking for, but the "scope:true" directive made it inherits from the parent scope per my understanding.  This means that when I tried to use this directive more than once (in my case i used two times since I have two kendo grid on my view) in the same controller it doesn't work.  Somehow it created two columns/sets of the checkboxes.  I tried to change the "scope: true" to "scope: {}", but it didn't work.  Do you have any suggestions on how to update your directive to use isolated scope so I can use that directive more than once in the same controller?

 

0
T. Tsonev
Telerik team
answered on 09 Feb 2016, 07:27 AM
Hello,

Please accept my apologies for the delayed response.

The angular-kendo repo in the Kendo Labs is no longer maintained or supported.

I'd like to ask you to submit a separate support ticket if the problem is applicable to the official Kendo UI integration with Angular.

Regards,
T. Tsonev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
Grid
Asked by
Access
Top achievements
Rank 2
Answers by
Mihai
Telerik team
Access
Top achievements
Rank 2
Rajesh
Top achievements
Rank 1
Zedmed
Top achievements
Rank 1
Lilly
Top achievements
Rank 1
T. Tsonev
Telerik team
Share this question
or