Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.

I am using jQuery DataTable directive with angularJS which is working fine. The problem I am facing is adding javascript function to "TR" dynamically with "ng-click" which is not working. It seem's like dynamically added elements are not recognized by angular.

Can somebody help me out solving this problem.

Directive :

angular.module('ngdemo.directives', []).directive('myTable', function() {
    return function(scope, element, attrs) {

        // apply DataTable options, use defaults if none specified by user
        var options = {};
        if (attrs.myTable.length > 0) {
            options = scope.$eval(attrs.myTable);
        } else {
            options = {
                "bStateSave": true,
                "iCookieDuration": 2419200, /* 1 month */
                "bJQueryUI": true,
                "bPaginate": false,
                "bLengthChange": false,
                "bFilter": false,
                "bInfo": false,
                "bDestroy": true
            };
        }

        // Tell the dataTables plugin what columns to use
        // We can either derive them from the dom, or use setup from the controller           
        var explicitColumns = [];
        element.find('th').each(function(index, elem) {
            explicitColumns.push($(elem).text());
        });
        if (explicitColumns.length > 0) {
            options["aoColumns"] = explicitColumns;
        } else if (attrs.aoColumns) {
            options["aoColumns"] = scope.$eval(attrs.aoColumns);
        }

        // aoColumnDefs is dataTables way of providing fine control over column config
        if (attrs.aoColumnDefs) {
            options["aoColumnDefs"] = scope.$eval(attrs.aoColumnDefs);
        }

        if (attrs.fnRowCallback) {
            options["fnRowCallback"] = scope.$eval(attrs.fnRowCallback);
        }

        // apply the plugin
        var dataTable = element.dataTable(options);



        // watch for any changes to our data, rebuild the DataTable
        scope.$watch(attrs.aaData, function(value) {
            var val = value || null;
            if (val) {
                dataTable.fnClearTable();
                dataTable.fnAddData(scope.$eval(attrs.aaData));
            }
        });
    };
});

In My Controller:

app.controller('SourceCtrl', ['$scope', 'SharedFactory','$location','$compile', function ($scope, SharedFactory,$location,$compile) {
    $scope.columnDefs = [ 
         { 
             "mDataProp": "desc", 
             "aTargets":[0],
         },
         { "mDataProp": "name", "aTargets":[1] },
         { "mDataProp": "desc", "aTargets":[2] }
    ];

    $scope.overrideOptions = {
             "bServerSide": true,
             "iDisplayLength": 2,
             "sAjaxSource": "ajaxCall",
             "aaSorting": [[ 0, "desc" ]],
             "fnServerData": function ( sSource, aoData, fnCallback,oSettings ) {
                      var startIndex = SharedFactory.fnGetKey(aoData, "iDisplayStart");
                      var length = SharedFactory.fnGetKey(aoData, "iDisplayLength");
                      var sortAttr = 'sourceType';//fnGetKey(aoData,"iSortCol_0");
                      var sortDir = 'DESC';//fnGetKey(aoData,"sSortDir_0");
                      sSource="ajaxCall";
                      $.getJSON(sSource, function (aoData) { 
                          aoData.iTotalRecords = aoData.size;
                          aoData.iTotalDisplayRecords = aoData.size;
                          fnCallback(aoData);
                      });
            },
            "sAjaxDataProp": "aaData",
            "fnCreatedRow": function( nRow, aData, iDataIndex ) {
                $(nRow).attr('ng-click','selectRow()');
             }
     };

    $scope.selectRow = function() {
        alert("");
    };
}]);
share|improve this question
    
Hi, Is there a working example that Salman or Alexander can point to.. I have the same problem. Thanks –  satya on rails Sep 28 '14 at 0:45

1 Answer 1

up vote 2 down vote accepted

Well, dynamically created stuff (especially jquery ui) doesn't know anything about angular. That's because angular make compilation of the nodes when processing. So there are few options there:

1) Before adding some dynamic content you can compile it. In this case angular can know about it and all feature like directives, binding etc. can work.

row.push($compile(content)($scope)[0].innerHTML);

In this sample we added compiled content to the row (cell). And the content can have any number of angular directives. But you should carefully pass on the correct scope to have the directives working as you expected.

Another way is just to deal with pure js. In this case you can just declare onclick handlers and inside of them make finding of the necessary scope and call the method on it:

angular.element('item').scope().handleClick(row);

And as the code is called from non-angular part you should wrap it into $scope.$apply:

$scope.handleClick = function(row) {
    $scope.$apply(function() {
        ... place handling logic here
    });
}

But I would better recommend to migrate to angular data grids (like ngGrid)

share|improve this answer
    
Thanks Alex that was really helpful. It actually solved my problem. Is there any problem to use datatable and not ngGrid ? –  Salman Raza Mar 30 '14 at 6:46
    
No special problem with that. I just prefer to use clean angularjs stuff which is more flexible when integrating in your application. If you need you can use datatable (we used it too but then we decided to migrate to an angularjs grid directives). Another alternatives: ng-table, smart-table etc. –  Alexander Kalinovski Mar 30 '14 at 6:54
    
Alex, I am using jQuery also with angular JS in my project. Such as toggle the class, hide show the divs. So is it a good approach to use jquery like this with angularJS ? –  Salman Raza Mar 31 '14 at 10:47
    
All of this is supported in AngularJS. So instead of jquery you can use ng-show, ng-hide, ng-class, ng-style etc. But for some time you may still need to handle this manually (for ex. inside of the directives) but they are rare cases. –  Alexander Kalinovski Mar 31 '14 at 12:50
1  
what is row.push()? –  Ankita Aug 21 at 11:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.