Reputation: 125
I am trying to handle a selection event from a KendoUI Grid in AngularJS.
I have got my code working as per below. However it feels like a really nasty way of having to get the data for the selected row. Especially using _data. Is there a better way of doing this? Have I got the wrong approach?
<div kendo-grid k-data-source="recipes" k-selectable="true" k-sortable="true" k-pageable="{'refresh': true, 'pageSizes': true}"
k-columns='[{field: "name", title: "Name", filterable: false, sortable: true},
{field: "style", title: "Style", filterable: true, sortable: true}]' k-on-change="onSelection(kendoEvent)">
</div>
$scope.onSelection = function(e) {
console.log(e.sender._data[0].id);
}
Upvotes: 10
Views: 14527
Reputation: 1152
I would suggest to use like this, I was also getting undefined when I upgraded my application from angular 7 to 15. Now I get event details like this
public selectedRowChangeAction(event:any): void {
console.log(event.selectedRows[0].dataItem.Id); }
event has selected Row at its 0 index and you can have dataItem as first object and then you can have all object details whatever you have for example Id, Name,Product details whatever you want to select, Something like you can see in picture
Upvotes: 0
Reputation: 10638
Directive for two-way binding to selected row. Should be put on the same element as kendo-grid directive.
Typescript version:
interface KendoGridSelectedRowsScope extends ng.IScope {
row: any[];
}
// Directive is registered as gridSelectedRow
export function kendoGridSelectedRowsDirective(): ng.IDirective {
return {
link($scope: KendoGridSelectedRowsScope, element: ng.IAugmentedJQuery) {
var unregister = $scope.$parent.$on("kendoWidgetCreated", (event, grid) => {
if (unregister)
unregister();
// Set selected rows on selection
grid.bind("change", function (e) {
var selectedRows = this.select();
var selectedDataItems = [];
for (var i = 0; i < selectedRows.length; i++) {
var dataItem = this.dataItem(selectedRows[i]);
selectedDataItems.push(dataItem);
}
if ($scope.row != selectedDataItems[0]) {
$scope.row = selectedDataItems[0];
$scope.$root.$$phase || $scope.$root.$digest();
}
});
// Reset selection on page change
grid.bind("dataBound", () => {
$scope.row = null;
$scope.$root.$$phase || $scope.$root.$digest();
});
$scope.$watch(
() => $scope.row,
(newValue, oldValue) => {
if (newValue !== undefined && newValue != oldValue) {
if (newValue == null)
grid.clearSelection();
else {
var index = grid.dataSource.indexOf(newValue);
if (index >= 0)
grid.select(grid.element.find("tr:eq(" + (index + 1) + ")"));
else
grid.clearSelection();
}
}
});
});
},
scope: {
row: "=gridSelectedRow"
}
};
}
Javascript version
function kendoGridSelectedRowsDirective() {
return {
link: function ($scope, element) {
var unregister = $scope.$parent.$on("kendoWidgetCreated", function (event, grid) {
if (unregister)
unregister();
// Set selected rows on selection
grid.bind("change", function (e) {
var selectedRows = this.select();
var selectedDataItems = [];
for (var i = 0; i < selectedRows.length; i++) {
var dataItem = this.dataItem(selectedRows[i]);
selectedDataItems.push(dataItem);
}
if ($scope.row != selectedDataItems[0]) {
$scope.row = selectedDataItems[0];
$scope.$root.$$phase || $scope.$root.$digest();
}
});
// Reset selection on page change
grid.bind("dataBound", function () {
$scope.row = null;
$scope.$root.$$phase || $scope.$root.$digest();
});
$scope.$watch(function () { return $scope.row; }, function (newValue, oldValue) {
if (newValue !== undefined && newValue != oldValue) {
if (newValue == null)
grid.clearSelection();
else {
var index = grid.dataSource.indexOf(newValue);
if (index >= 0)
grid.select(grid.element.find("tr:eq(" + (index + 1) + ")"));
else
grid.clearSelection();
}
}
});
});
},
scope: {
row: "=gridSelectedRow"
}
};
}
Upvotes: 1
Reputation: 59
A quick example of how to do this with an angular directive.
Note here that I'm getting the reference to the underlying kendo grid through the click event and the DOM handle.
//this is a custom directive to bind a kendo grid's row selection to a model
var lgSelectedRow = MainController.directive('lgSelectedRow', function () {
return {
scope: {
//optional isolate scope aka one way binding
rowData: "=?"
},
link: function (scope, element, attributes) {
//binds the click event and the row data of the selected grid to our isolate scope
element.bind("click", function(e) {
scope.$apply(function () {
//get the grid from the click handler in the DOM
var grid = $(e.target).closest("div").parent().data("kendoGrid");
var selectedData = grid.dataItem(grid.select());
scope.rowData = selectedData;
});
});
}
};
});
Upvotes: 0
Reputation: 516
Joining the party rather late, there is a direct way to do it without reaching for the grid object:
on the markup:
k-on-change="onSelection(data)"
in the code:
$scope.onSelection = function(data) {
// no need to reach the for the sender
}
note that you may still send selected
, dataItem
, kendoEvent
or columns
if needed.
consult this link for more details.
Upvotes: 5
Reputation: 1294
please try the following:
$scope.onSelection = function(kendoEvent) { var grid = kendoEvent.sender; var selectedData = grid.dataItem(grid.select()); console.log(selectedData.id); }
Upvotes: 13