12

I wrote a dataTables directive for AngularJS. Its working fine except that i trying to add an button to the row that removes an row with an ng-click.

In my opinion is that the problem occurs because the table row doesn't now the scope.

Can somebody help me out solving this problem.

jsFiddle Example: http://jsfiddle.net/A5Zvh/7/

My directive looks like this.

angular.module('DataTables', [])
.directive('datatable', function() {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        require: 'ngModel',
        template: '<table></table>',
        link: function(scope, element, attrs, model) {
            var dataTable = null,
                options;

            var buttons = jQuery.parseJSON(attrs['buttons']) || null;

            options  = {
                    "bJQueryUI": false,
                    "sDom": "<'row-fluid'<'span4'l><'span8 filter' <'pull-right'T> <'pull-right'f>>r>t<'row-fluid'<'span6'i><'span6'p>>",
                    "sPaginationType": "bootstrap",
                    "oTableTools": {
                    }
                };

            if(_.has(attrs, 'datatableOptions')) {
                jQuery.extend(true, options, scope.$eval(attrs['datatableOptions']));
            }

            scope.$watch(attrs.ngModel, function(data) {
                if(data && _.size(data.aaData) > 0 && _.size(data.aoColumns) > 0) {

                    _.extend(options, scope.$eval(attrs.ngModel))
                    dataTable = $(element).dataTable(options);
                    dataTable.fnClearTable();
                    dataTable.fnAddData(data.aaData);
                }
            });
        }
    }
})
user1266573
  • 251
  • 1
  • 3
  • 10

5 Answers5

23

I'm using Angular-datatbles, and I was trying to dynamically add, Edit & Remove links to the datatble rows and display modal on ng-click;

This was the solution for my case;

$scope.dtOptions.withOption('fnRowCallback',
     function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
        $compile(nRow)($scope);
     });

All the datatable binding code;

$scope.reloadData = function () {
    $scope.dtOptions.reloadData();
};

$scope.dtColumnDefs = [

    DTColumnDefBuilder.newColumnDef(2).renderWith(function (data, type, row) {
        var html = '<a href="" class="txt-color-blue pull-left" ng-click="editModal()"><i class="fa fa-pencil hidden-xs"></i> Edit</a>' +
                   '<a href="" class="txt-color-red padding-top-15" ng-click="removeModal()"><i class="fa fa-times hidden-xs"></i> Remove</a>';
        return html;
    })
];

$scope.dtColumns = [
    DTColumnBuilder.newColumn('name').withTitle('Name'),
    DTColumnBuilder.newColumn('type').withTitle('Type'),
    DTColumnBuilder.newColumn('id').withTitle(''),
];

$scope.dtOptions.withOption('fnRowCallback',
     function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
        $compile(nRow)($scope);
     });
Nabil.A
  • 581
  • 4
  • 16
  • glad to hear that. but at this point I'm more leaning toward the angularWay instead of "dtColumnDefs". http://l-lin.github.io/angular-datatables/#/angularWay – Nabil.A Sep 19 '14 at 17:04
  • thanks i was missing the compile in FnRowCallback. solved my problem – ufk Jan 30 '16 at 10:57
5

I solved this by going through each td and calling $compile. Using the datatable row callback function. Hope this helps.

options.fnCreatedCell =  function (nTd, sData, oData, iRow, iCol) {
    $compile(nTd)($scope);
}

//or row

options.fnCreatedRow = function( nRow, aData, iDataIndex ) {
    $compile(nRow)($scope);
}
viphak
  • 106
  • 1
  • 4
  • I've been smashing my head to the wall with this issue. Have you got the code to make it work? Yours seems to be on the right path but dunno how to call it from within datatable. Thanks. – coffekid Oct 23 '13 at 01:51
3

The delete function in your controller isn't called because AngularJS doesn't know anything about DataTables's insertion of those elements to the DOM, thus ngClick directive within those elements isn't compiled and linked. So change:

dataTable.fnAddData(data.aaData);

To

dataTable.fnAddData(data.aaData);
$compile(element)(scope);

And to inject $compile service:

.directive('datatable', function () {

To

.directive('datatable', function ($compile) {

And your delete function is broken in the jsFiddle, hope that's not the case in your actual project!

Dan
  • 41
  • 2
0

You might want to give a look at the first couple of Zdam's post on this Google Groups thread, especially to his/her two linked jsFiddles. I basically copied them and they work at a basic level. I have not tried yet to get some action starting from a click on a row.

I see that you implemented a slightly different approach, recreating the <table> HTML node altogether. Not sure if this is causing issues.

By the way, on the scope.$watch call I had to make sure there was a third parameter set to true, in order to make value comparison (instead of reference comparison) on the returned resource$ object. Not sure why you don't need that.

superjos
  • 12,189
  • 6
  • 89
  • 134
0

fnCreatedCell be supplied in aoColumns or fnCreatedRow supplied to mRender

1 )fnCreatedCell is column based

ex :

tableElement.dataTable({
                "bDestroy": true,
                oLanguage : {
                       sLengthMenu : '_MENU_ records per page'
                },
               aoColumnDefs: [
         {
               bSortable: false,
               aTargets: [ -1,-2,-3 ],
               "fnCreatedCell": function (nTd, sData, oData, iRow, iCol)         
                         {  
                            $compile(nTd)($scope)
                          }
          }
        ],

2 ) fnCreatedRow is a 'top level' callback

tableElement.dataTable({
                "bDestroy": true,
                oLanguage : {
                       sLengthMenu : '_MENU_ records per page'
                },
        aoColumnDefs: [
        {
          bSortable: false,
          aTargets: [ -1,-2,-3 ]
         }
         ],
         "fnCreatedRow": function( nRow, aData, iDataIndex ){
                    compile(nRow)(scope);
            },  
AKA
  • 41
  • 4