I am working on a module where I have to redesign some products. Following is the screenshot of how the products used to get displayed previously.
Now the products will be displayed inside accordion of their specific name. I am bound to use ui.bootstrap Version: 0.11.0 - 2014-05-01. Following is a sketch of how the products will be displayed now. In each accordion there will be a datatable of that particular product in which the columns will dynamically generate and we would be able to check the particular products we want.
Following is my html code:
<accordion>
<accordion-group ng-repeat="AllProduct in AllProducts">
<accordion-heading>
{{AllProduct.TypeName}}
</accordion-heading>
</accordion-group>
<table id="dtVoice" class="table manage-user-table offer-mgt-table" dt-options="dtOptions" dt-columns="dtColumns"></table>
</accordion>
The way i have dynamically created datatables are as follows:
dtColumns.push(DTColumnBuilder.newColumn(null).withTitle('').notSortable()
.renderWith(function(data, type, full, meta) {
return '<input type="checkbox" ng-model="showCase.selected[' + data.id + ']"/>';
}));
for (var key in $scope.VoiceProducts[0]) {
if (key == "ProductName" || key == "LongDistanceMinutes" || key == "IsCallWaiting") {
dtColumns.push(
DTColumnBuilder.newColumn(key).withTitle(key)
)
}
$scope.dtColumns = dtColumns;
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withOption('data', $scope.VoiceProducts)
.withOption('dataSrc', '')
angular.element('#dtVoice').attr('datatable', '')
}
$compile(angular.element('#dtVoice'))($scope);
Following is my json
[
{
"ProductList": [
{
"ProductName": "Voice",
"IsActive": false,
"IsDeleted": false,
"LongDistanceMinutes": "",
"IsCallWaiting": "",
"CallWaitingId": "",
"IsThreeWayCalling": "",
"IsCallerId": "",
"IsCallForwarding": "",
"IsCallRejection": "",
"ID": 552,
"OfferId": 0
}
],
"ID": 2,
"IsActive": false,
"IsDeleted": false,
"TypeName": "Voice"
}
]
How to put this datatable inside accordion? Because by doing whatever I'm, i'm unable to achieve it.
UPDATED: As per new information (using angular-datatable)
The solution now boils down to computing the columns and options per accordion-group.
Working Plunker with 2 accordion groups
As you can see in the HTML below the options and columns are computed per accordion.
<table datatable class="table manage-user-table offer-mgt-table" dt-options="getDtOptions(AllProduct)" dt-columns="getDtColumns(AllProduct)"></table>
Angular code showing getDtColumns and getDtOptions. I have kept the data very simple for demonstration purposes and copied the current dtColumns
code however you can customize it so that you can even have more than 1 type of table :
var app = angular.module('myApp', ['ui.bootstrap', 'datatables']);
app.controller('myCtrl', function($scope, DTColumnBuilder, DTOptionsBuilder, DTColumnDefBuilder, $timeout, AllProducts) {
$scope.AllProducts = AllProducts
$scope.getDtColumns = function(allProduct) {
var items = allProduct.ProductList;
if (allProduct.dtColumns) allProduct.dtColumns.length = 0;
allProduct.dtColumns = allProduct.dtColumns || [];
var dtColumns = allProduct.dtColumns;
dtColumns.push(DTColumnBuilder.newColumn('').withTitle('').notSortable()
.renderWith(function(data, type, full, meta) {
return '<input type="checkbox" ng-model="showCase.selected[' + full.id + ']"/>';
}));
for (var key in items[0]) {
if (key == "ProductName" || key == "LongDistanceMinutes" || key == "IsCallWaiting") {
dtColumns.push(
DTColumnBuilder.newColumn(key).withTitle(key).notSortable()
)
}
}
return dtColumns;
};
$scope.getDtOptions = function(allProduct) {
if (allProduct.options) return allProduct.options;
var items = allProduct.ProductList;
allProduct.options = allProduct.options || DTOptionsBuilder.newOptions().withOption('aaData', items);
return allProduct.options;
};
});
OLDER ANSWER without angular-datatable
First of all I do not recommend jQuery DataTable or any other jQuery component in AngularJS applications. I personally try not to bundle jQuery or perform DOM manipulation using jQuery.
However to get you going with what you have I suggest the following:-
Remove these two lines because simply adding those attributes datatable
dynamically is not going to trigger the DataTable binding:-
angular.element('#dtVoice').attr('datatable', '')
}
$compile(angular.element('#dtVoice'))($scope);
and try using something like this:-
$('#dtVoice').DataTable( {columnDefs: $scope.dtColumns });
Further more just to clean up a bit I create a new directive (just typing out loud):
app.directive('myDatatable`, function(){
return {
restrict: 'A',
scope: {
'dtColumns': '='
}
link: function($scope, elem, attr) {
$('#dtVoice').DataTable( {columnDefs: $scope.dtColumns});
}
};
});
and your table something like below:
<table id="dtVoice"
class="table manage-user-table offer-mgt-table"
dt-options="dtOptions"
dt-columns="dtColumns" my-datatable></table>
I had the same problem on the pass.
Please use ng-if as a flag to recreate the table when the accordion item is active. The accordion and tab components avoid the table to be shown.
The code below can help.Notice the ng-click and ng-if
<accordion>
<accordion-group ng-repeat="AllProduct in AllProducts">
<accordion-heading ng-click="setGroup('AllProduct.TypeName')">
{{AllProduct.TypeName}}
</accordion-heading>
<table id="dtVoice" ng-if="group=='AllProduct.TypeName'" class="table manage-user-table offer-mgt-table" dt-options="dtOptions" dt-columns="dtColumns"></table>
</accordion-group>
</accordion>