2

I want to create dynamic elements with can fire an ng-click event and want to do this with DataTables where the rows are obtained through AJAX and are dynamically created. The problem is that ng-click isn't fired on those row elements. I have recreated the problem in JSBin with another situation (the DataTables part doesn't really matter).

Html

<div id="elements" ng-controller="TestController as controller">
  <button ng-click='doSomething()'>This button will work</button>
  </div>

  <button class="click">Create element</button>

When the Create element button is clicked, a button is added to the DOM in the #elements div. The button within that div is clicked, the console will output something. It does what it has to do when you click the already created button in the #elements div but doesn't with a dynamically created button.

JS

app.controller('TestController', ['$http', '$scope', function ($http, $scope) {
  //The NG function.
  $scope.doSomething = function(){
    console.log('Function fired!');
  };
}]);                                

//Create new element in the #elements div.                                  
(function(){
  $(".click").on("click", function(){
    var element = "<button ng-click='doSomething()'>This will not work</button>";
    $("#elements").append(element);
  });
})();

http://jsbin.com/hakibocabe/edit?html,js,console,output

What am I doing wrong? Am I missing something?

Moduo
  • 623
  • 6
  • 17
  • 1
    this is definitely not the angular way to do things, you are using JQuery, and still thinking in the method of JQuery, programming for the DOM rather than programming for the DATA. – Claies Jul 05 '15 at 21:01
  • @Claies thanks for notifying this is the wrong way of thinking. What would be the Angular way to do this? – Moduo Jul 05 '15 at 21:20
  • I think Radmer's answer would be pretty close, without seeing the data that you are trying to use this button with, though, it's hard to know for certain. – Claies Jul 05 '15 at 21:25
  • 1
    In angular, you should always strive to be interacting with your data in JavaScript, and really shouldn't modify the DOM from the JavaScript unless you have no other choice in the matter. Angular does a great job of managing the DOM through templates, Directives, `ng-repeat`, `ng-if`, `ng-show` / `ng-hide`, etc... – Claies Jul 05 '15 at 21:28
  • 1
    since you mention DataTables in one of the comments, I'll just leave this here. Are you using the Angular Directives written for DataTables? http://l-lin.github.io/angular-datatables/#/gettingStarted – Claies Jul 05 '15 at 21:42
  • I am gonna check that one out. Thanks for your effort in helping me. I think the Angular DataTables will be the solution to my problem. – Moduo Jul 05 '15 at 21:54

3 Answers3

2

As I understand it, you want to add buttons to a div when another button is clicked and have each button in the div use the doSomething function.

So for a pure angular answer you want something like this:

HTML:

<div ng-controller="TestController">
  <div ng-repeat="button in buttons">
    <button ng-click="doSomething()">Button</button>
  </div>
  <button ng-click="addButton()">Add</button>
</div>

JS:

app.controller('TestController', ['$http', '$scope', function ($http, $scope) {
  $scope.buttons = [];

  $scope.doSomething = function(){
    console.log('Function fired!');
  };

  $scope.addButton = function(){
    $scope.buttons.push($scope.buttons.length)//or whatever content
  };
}]); 
  • I see how this would work, but the problem is that the real scenario is using table rows that are dynamically added to the DOM and are assigned the `ng-click` attribute after creation (puts a little twist on the story right?) through `jQuery` with the `elem.attr('ng-click', 'myFunc()');` method. – Moduo Jul 05 '15 at 21:28
  • @tom why couldn't you use `ng-click = myObject.myfunc` and assign the function to the object in the controller? again, think in terms of representing your data, rather than representing your DOM. – Claies Jul 05 '15 at 21:31
  • @Claies Because the `ng-click` is simply ignored. When the `DataTables` loads it is assigning the attribute to the row after creation with the `fnCreatedRow: function (nRow, aData, iDataIndex)` function of `DataTables`. – Moduo Jul 05 '15 at 21:37
  • eh. you never mentioned DataTables before now... I think I saw a method in DataTables specifically for what you are trying to do; then again, even if there weren't, I still wouldn't expect to drop to JQuery.... – Claies Jul 05 '15 at 21:38
  • I actually am using the DataTables jQuery plug-in from http://datatables.net/. I think it would be better to drop it because it just doesn't fit the Angular way of doing think. – Moduo Jul 05 '15 at 21:44
  • @Tom see my comment to the original question body. – Claies Jul 05 '15 at 21:48
1

Although @Radmer van der Heyde's answer pretty much explains how to Angular way of adding buttons to the DOM work (which I'm really thankfull of), @Claies suggested me to use Angular DataTables instead of using the normal jQuery DataTables and pointed out some points on how to do this the Angular way.

I have reviewed the Angular DataTables and am now working with it which pretty much solved my problem. So if you are having the same problem as I had, use Angular DataTables: http://l-lin.github.io/angular-datatables/#/welcome

Moduo
  • 623
  • 6
  • 17
0

I think you need to use $compile service as you can see in this other answer:

ng-click not working from dynamically generated HTML

Hope it helps!

Community
  • 1
  • 1
Xavis
  • 99
  • 2
  • 9