Reputation: 2324
can someone help me with rowCallback. Problem is, I have a table, and you can click anywhere on table row for open info for clicked item. On first TD I set check box. But when I check checkbox, I don't want to open info. Here is image for better explanation
my code
var vm = this;
vm.selected = {};
vm.selectAll = false;
vm.toggleAll = toggleAll;
vm.toggleOne = toggleOne;
var titleHtml = '<input type="checkbox" ng-model="showCase.selectAll" ng-click="showCase.toggleAll(showCase.selectAll, showCase.selected)">';
function getUserTokenFromLocalStorage(localStorage) {
var authData = [];
for (key in localStorage) {
if (key == "ls.authorizationData") {
authData = localStorage[key];
}
}
var jsonObj = JSON.parse(authData);
return jsonObj.token;
};
var vm = this;
vm.message = '';
vm.someClickHandler = someClickHandler;
vm.dtOptions = DTOptionsBuilder.newOptions()
.withOption('ajax', {
// Either you specify the AjaxDataProp here
// dataSrc: 'data',
url: serviceBase + 'test',
type: 'POST',
headers: {
'xtoken': 'Bearer ' + getUserTokenFromLocalStorage(localStorage)
}
})
// or here
.withDataProp('data')
.withOption('processing', true)
.withOption('serverSide', true)
.withOption('rowCallback', rowCallback)
.withOption('createdRow', function(row, data, dataIndex) {
// Recompiling so we can bind Angular directive to the DT
$compile(angular.element(row).contents())($scope);
})
.withOption('headerCallback', function(header) {
if (!vm.headerCompiled) {
// Use this headerCompiled field to only compile header once
vm.headerCompiled = true;
$compile(angular.element(header).contents())($scope);
}
})
.withPaginationType('full_numbers')
vm.dtColumns = vm.dtColumns = [
DTColumnBuilder.newColumn(null).withTitle(titleHtml).notSortable()
.renderWith(function(data, type, full, meta) {
vm.selected[full.id] = false;
return '<input type="checkbox" ng-model="showCase.selected[' + data.id + ']" ng-click="showCase.toggleOne(showCase.selected)">';
}), //don't change state when click on this TD, only check checkbox.
DTColumnBuilder.newColumn('id').withTitle('ID'),
DTColumnBuilder.newColumn('type').withTitle('Type'),
DTColumnBuilder.newColumn('city').withTitle('City'),
DTColumnBuilder.newColumn('country').withTitle('Country'),
DTColumnBuilder.newColumn('last_report_dt').withTitle('Last report'),
DTColumnBuilder.newColumn('hardware_version').withTitle('HW version'),
DTColumnBuilder.newColumn('rpi_image_version').withTitle('Image version'),
DTColumnBuilder.newColumn('software_version').withTitle('Code version'),
DTColumnBuilder.newColumn('internal_note').withTitle('Internal note'),
DTColumnBuilder.newColumn(null).withTitle('Info').notSortable()
.renderWith(function(data, type, full, meta) {
vm.selected[full.id] = false;
return '<a class="btn btn-default" ng-href="info/' + data.id + '">Info</a>';
}),
];
function toggleAll(selectAll, selectedItems) {
for (var id in selectedItems) {
if (selectedItems.hasOwnProperty(id)) {
selectedItems[id] = selectAll;
}
}
}
function toggleOne(selectedItems) {
for (var id in selectedItems) {
if (selectedItems.hasOwnProperty(id)) {
if (!selectedItems[id]) {
vm.selectAll = false;
return;
}
}
}
vm.selectAll = true;
}
function someClickHandler(info) {
vm.message = info.id;
$location.path('info/' + info.id);
}
function rowCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
// Unbind first in order to avoid any duplicate handler (see https://github.com/l-lin/angular-datatables/issues/87)
$('td', nRow).unbind('click');
$('td', nRow).bind('click', function() {
$scope.$apply(function() {
vm.someClickHandler(aData);
});
});
return nRow;
}
}
Upvotes: 3
Views: 2780
Reputation: 85518
Have had this issue myself. I think your approach is a little bit backwards. You declare the td
click handler inside rowCallback
, just to be able to pass the id. Instead I will recommend this :
Add a no-click
class to the first column to prevent click :
DTColumnBuilder.newColumn(null).withTitle(titleHtml).notSortable()
.withClass('no-click')
.renderWith(function(data, type, full, meta) {
vm.selected[full.id] = false;
return '<input type="checkbox" ng-model="showCase.selected[' + data.id + ']" ng-click="showCase.toggleOne(showCase.selected)">';
}),
Change the rowCallback
to do nothing but injecting the id
as attribute to the row :
function rowCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$(nRow).attr('data-id', aData.id);
}
Create a delegated event handler on the td
's to replace both the event handler inside rowCallback
and your someClickHandler()
:
$('#tableid').on('click', 'tbody td:not(.no-click)', function() {
var id = $(this).parent().attr('data-id');
vm.message = id;
$location.path('info/' + id);
})
Upvotes: 3