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);
                }
            });
        }
    }
})
2

5 Answers 5

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);
     });
Sign up to request clarification or add additional context in comments.

2 Comments

glad to hear that. but at this point I'm more leaning toward the angularWay instead of "dtColumnDefs". l-lin.github.io/angular-datatables/#/angularWay
thanks i was missing the compile in FnRowCallback. solved my problem
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);
}

1 Comment

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.
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!

1 Comment

I tried this but I'm getting a particularly nasty infinite loop
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.

Comments

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);
            },  

1 Comment

where's the angular ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.