DataTables inside bootstrap accordion in angularjs

2019-04-11 18:20发布

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.

enter image description here

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.

enter image description here

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.

2条回答
贼婆χ
2楼-- · 2019-04-11 18:46

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>
查看更多
不美不萌又怎样
3楼-- · 2019-04-11 19:00

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>
查看更多
登录 后发表回答