ng-click not working from dynamically generated HTML
HTML
<table data-ng-table="tableParams" class="table table-bordered table-hover " style="border-collapse:collapse" data-ng-init="host.editSave = false" >
<tr id="newTransaction">
</tr>
<tr data-ng-repeat="host in hosts|filter:search:strict" >
<td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostCd}}</td>
<td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostName}}</td>
</tr>
</table>
Jquery
$('#newTransaction').append(
'<td contenteditable><input type="text" class="editBox" value=""/></td>'+
'<td contenteditable><input type="text" class="editBox" value=""/></td>'+
'<td>'+
'<span>'+
'<button id="createHost" class="btn btn-mini btn-success" data-ng-click="create()"><b>Create</b></button>'+
'</span>'+
'</td>'
);
Angular Script
$scope.create = function() {
alert("Hi");
};
Here the function called in the controller part of the AngularJS is not getting trigger from the ng-click event. The Html is getting appended successfully, but the ng-click is not working. Tell me solutions to make it work
Not a perfect fix, still!!! - just to show how dynamic compilation can be done
app.controller('AppController', function ($scope, $compile) {
var $el = $('<td contenteditable><input type="text" class="editBox" value=""/></td>' +
'<td contenteditable><input type="text" class="editBox" value=""/></td>' +
'<td>' +
'<span>' +
'<button id="createHost" class="btn btn-mini btn-success" data-ng-click="create()"><b>Create</b></button>' +
'</span>' +
'</td>').appendTo('#newTransaction');
$compile($el)($scope);
$scope.create = function(){
console.log('clicked')
}
})
Demo: Fiddle
Don't use controller for dom manipulation - it has to be done with the help of directives
To make ng-click
to work we need to compile this source by using $compile
service. Angular should know about new generated HTML and therefore this HTML should be included to digest cycle in order to trigger ng-click
and other events.
See Fiddle
Create "compilator":
.directive( 'compileData', function ( $compile ) {
return {
scope: true,
link: function ( scope, element, attrs ) {
var elmnt;
attrs.$observe( 'template', function ( myTemplate ) {
if ( angular.isDefined( myTemplate ) ) {
// compile the provided template against the current scope
elmnt = $compile( myTemplate )( scope );
element.html(""); // dummy "clear"
element.append( elmnt );
}
});
}
};
});
after, create dummy factory
that simulates your append:
.factory( 'tempService', function () {
return function () {
return '<td contenteditable><input type="text" class="editBox" value=""/></td>'+
'<td contenteditable><input type="text" class="editBox" value=""/></td>'+
'<td>'+
'<span>'+
'<button id="createHost" class="btn btn-mini btn-success" data-ng-click="create()"><b>Create</b></button>'+
'</span>'+
'</td>';
};
});
And finally call it like:
<div compile-data template="{{mainPage}}"></div>
in Controller:
$scope.newTransaction= tempService();
For your example should be something like:
<table data-ng-table="tableParams" class="table table-bordered table-hover " style="border-collapse:collapse" data-ng-init="host.editSave = false" >
<tr compile-data template="{{newTransaction}}">
</tr>
<tr data-ng-repeat="host in hosts|filter:search:strict" >
<td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostCd}}</td>
<td class="hostTableCols" data-ng-hide="host.editSave">{{host.hostName}}</td>
</tr>
</table>
BTW, for now you can use the same directive over your code and compile any dynamic HTML.
you can use angular.element(this).scope()
without use of ng-click
and change
'<button id="createHost" class="btn btn-mini btn-success" data-ng-click="create()"><b>Create</b></button>'
To
'<button id="createHost" class="btn btn-mini btn-success" onclick="angular.element(this).scope().create()"><b>Create</b></button>'
is good