Reputation: 624
I am trying to use the Table Charts component in an AngularJS 1.2.10 app.
I wrote a wrapper directive, which brings table chart into an AngularJS context.
angular.module('my.charts.table', [])
.directive('myTableChart', [function() {
return {
restrict : 'E',
scope : {
columns : '=',
rows : '='
},
templateUrl : 'my.charts.table/myTableChart.tmpl.html',
link : function(scope, element) {
var data = new google.visualization.DataTable();
// add columns
var table = new google.visualization.Table(element[0].childNodes[0]);
table.draw(data, { allowHtml : true });
}
};
}
]);
For given columns and rows the data table is initialized and drawn.
What I want to do is to add a column, which holds a button with AngularJS directives.
<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="testLog()">Test</button>
You can assume that the testLog() method is defined on the current scope.
The table chart component allows the direct insertion of HTML as cell values. However, this lies outside of the AngularJS lifecycle and, therefore, simply inserting the above HTML snippet won't work.
Now, I tried to compile and link the button manually.
var btn = $compile('<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="testLog()">Test</button>')(scope);
I can append the button manually.
element.append(btn);
However, the table chart expects HTML, not a DOM element. If I pass btn[0].outerHTML, the ngClick directive won't trigger.
Is there a way to solve this problem?
Here is the complete code snippet:
google.load('visualization', '1', {
packages: ['corechart', 'table']
});
google.setOnLoadCallback(function() {
angular.bootstrap(document, ['my.app']);
});
angular.module('my.app', [])
.directive('myTableChart', function() {
return {
restrict: 'E',
scope: {
columns: '=',
rows: '='
},
template: '<div></div>',
link: function(scope, element) {
var data = new google.visualization.DataTable();
for (var i = 0; i < scope.columns.length; i++) {
data.addColumn(scope.columns[i].type, scope.columns[i].name);
}
data.addRows(scope.rows);
var table = new google.visualization.Table(element[0].childNodes[0]);
table.draw(data, {
width: '100%',
allowHtml: true
});
}
};
})
.directive('myTestTable', ['$compile',
function($compile) {
return {
restrict: 'E',
scope: {},
template: '<my-table-chart ng-if="curRows != null" columns="curCols" rows="curRows"></my-table-chart>',
link: function(scope, element) {
scope.curCols = [{
type: 'string',
name: 'Test'
}, {
type: 'string',
name: ''
}];
scope.curRows = [];
scope.testLog = function() {
alert('Works too');
};
var btn = $compile('<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="testLog()">Test</button>')(scope);
var btnHtml = btn[0].outerHTML;
element.append(btn);
scope.curRows.push(['test entry', btnHtml]);
}
};
}
]);
<my-test-table></my-test-table>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="https://www.google.com/jsapi"></script>
Upvotes: 0
Views: 1136
Reputation: 59328
Better late than never, the following solution allows to trigger testLog
event via ng-click
directive:
google.visualization.Table
does not support
adding DOM elements, move compilation from myTestTable
to
myTableChart
testLog
function from myTableChart
directive scope, change the declaration to ng-click="$parent.testLog()"
perform compilation once the chart is rendered:
google.visualization.events.addListener(table, 'ready', function() {
var table_div = table.getContainer();
$compile(table_div)(scope);
});
Example
google.load('visualization', '1', {
packages: ['corechart', 'table']
});
google.setOnLoadCallback(function() {
angular.bootstrap(document, ['my.app']);
});
angular.module('my.app', [])
.directive('myTableChart', function($compile) {
return {
restrict: 'E',
scope: {
columns: '=',
rows: '='
},
template: '<div></div>',
link: function(scope, element) {
var data = new google.visualization.DataTable();
for (var i = 0; i < scope.columns.length; i++) {
data.addColumn(scope.columns[i].type, scope.columns[i].name);
}
data.addRows(scope.rows);
var table = new google.visualization.Table(element[0].childNodes[0]);
google.visualization.events.addListener(table, 'ready', function() {
var table_div = table.getContainer();
$compile(table_div)(scope);
});
table.draw(data, {
width: '100%',
allowHtml: true
});
}
};
})
.directive('myTestTable', ['$compile',
function($compile) {
return {
restrict: 'E',
scope: {},
template: '<my-table-chart ng-if="curRows != null" columns="curCols" rows="curRows"></my-table-chart>',
link: function(scope, element) {
scope.curCols = [{
type: 'string',
name: 'Test'
}, {
type: 'string',
name: ''
}];
scope.curRows = [];
scope.testLog = function() {
alert('Works too');
};
var btnHtml = '<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="$parent.testLog()">Test</button>';
scope.curRows.push(['test entry', btnHtml]);
}
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="https://www.google.com/jsapi"></script>
<my-test-table></my-test-table>
Upvotes: 1