8

I'm very new to AngularJs and datatables. I have a requirement to populate the data in table rows using ng-repeat. Iam able to populate the rows and enabling the sorting for the first time. When i click on the arrows to sort ascend or descend the row data wiping off.

Here is my table data

<table datatable="ng" id="example" class="display" cellspacing="0"    width="100%">
                <thead>
                    <tr>
                        <th class="col1">Campaign Name</th>
                        <th class="col4">Description</th>
                        <th class="col5">Activate/Deactivate</th>
                        <th class="col5">edit</th>
                        <!-- <th class="col5">status</th> -->
                        <!-- <th class="col5">Details</th> -->
                    </tr>
                </thead>
                <tbody >
                    <tr ng-repeat="campaign in campaignListData">
                             <td>{{campaign.campaignObject.campaignName}}</td>
                             <td>{{campaign.campaignObject.campaignMessage}}</td>
                            <td><button type="button" class="pay-amount pending" style="margin-top:-10px;margin-right:17px;width:128px;height:34px"
                            value = "{{ campaign.campaignObject.label }}" title="ACTIVATE" ng-click="updateCampaignStatus(campaign.campaignObject.id)">
                                <span style="margin-left:-10px;margin-right:17px;width:128px;height:34px">{{ campaign.campaignObject.label }}</span>
                                </button>
                            </td>
                            <td><a href="<c:url value="${contextPath}/merchant/manageCampaign/editCampaignConfiguration"/>?campaignId={{ campaign.campaignObject.id }}">
                                <img class="tableImage" style="margin-left:-8px;margin-top:-10px;" src="<c:url value="/resources/images/setting.png" />" ></a>
                            </td>
                    </tr>
                </tbody>
            </table> 

Here is my sorting javascript code

<script type="text/javascript">
    $(document).ready(function() {
        $("#noCampaignData").hide();
        //$("#example_paginate").hide();
        var rowCount = $("#example tr").length;
        console.log("Row count value is"+rowCount);
        if (rowCount >= 0) {
            console.log("Entered into Sorting");
            $("#example").dataTable({
                "pagingType" : "full_numbers",
                "order" : [ [ 2, "desc" ] ]
            });
        }
    });
</script>

I'm getting rowcount for tr is 1

I have the js file included at the bottom of the page

<script src="<c:url value="/resources/js/CampaignListController.js" />"></script>
<script src="<c:url value="/resources/js/jquery.dataTables.min.js" />"></script>

When Im loading data its fine loading with ng-repeat. But when i click on header to sort ascending or descending, rows are wiped off.

Please advise me where i'm doing wrong? I'm unable to sort the data ascending, descending and pagination is not at all working.

Sorry for my English.

herbert
  • 307
  • 1
  • 3
  • 15
chetan
  • 83
  • 1
  • 6

2 Answers2

9

No offense, but this is a typical mix-up of jQuery and Angular thinking, or a lack of understanding how Angular works. Here an attempt to wrap some jQuery logic into the angular digest loop. Read a great answer to the question “Thinking in AngularJS” if I have a jQuery background?

You cannot ever combine $(document).ready(function() { and Angular. In fact, you can be very sure that your ready() is executed long before Angular has finished its ng-repeat business. And thats why you always get 1 for the row count (the header) and why the rows are dissappearing when you click on the headers. At the time you get row count there is not inserted any rows, and at the time you instantiate the dataTable(), no rows have been inserted.

You can use $timeout to force delay of the code, or force it into the next digest loop :

$scope.initDataTable = function() {
   $timeout(function() {
      $("#noCampaignData").hide();
      //$("#example_paginate").hide();
      var rowCount = $("#example tr").length;
      console.log("Row count value is"+rowCount);
      if (rowCount >= 0) {
         console.log("Entered into Sorting");
         $("#example").dataTable({
            "pagingType" : "full_numbers",
            "order" : [ [ 2, "desc" ] ]
         });
      }
   }, 200)
}

or create a directive that instantiates the dataTable once the data is populated by ng-repeat, as demonstrated in multiple answers for ng-repeat finish event :

.directive('repeatDone', function() {
    return function(scope, element, attrs) {
        if (scope.$last) { // all are rendered
            scope.$eval(attrs.repeatDone);
        }
    }
})

...

<tr ng-repeat="campaign in campaignListData" repeat-done="initDataTable">

...

$scope.initDataTable = function() {
      $("#noCampaignData").hide();
      $("#example").dataTable({
         ...
      });
}

Hope this will help you out.

Community
  • 1
  • 1
davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • Thanks... Its Awesome explanation you have given and 90% functionality is working... I'm able to show the headers, arrows and able to populate data in rows and able to paginate also. One thing missing is the sorting... When i click on the arrows its freezing and rows are not sorted either in ascending order or descending order. Any Suggestions? @davidkonrad – chetan Jun 20 '15 at 06:01
  • 1
    stay blessed dude.. very nice explanation. – Naila Akbar Aug 15 '16 at 11:50
  • @davidkonrad can you elaborate how we can use search and sort functionality using directive? because in my case those are also not working – Naila Akbar Aug 15 '16 at 12:11
  • 1
    @NullPointer, yes - use the [angular datatables directives](https://l-lin.github.io/angular-datatables/) really easy to use and support all functionality, here is an example -> http://plnkr.co/edit/nBtzURQxSgKIqFvGMkWC?p=preview In fact I do not think there is so much choice if you really want to use dataTables features, you can have dataTable to work as shown above, but going further you will eventually experience real headaches. – davidkonrad Aug 15 '16 at 12:19
  • I tried that too. but it gives me error with 'datatables.directive', that it is missing or either i misspelled the spellings – Naila Akbar Aug 15 '16 at 12:47
  • hey @NullPointer, you need to include `datatables` in your module and include `DTOptionsBuilder` / `DTColumnBuilder` in the controller. See this plnkr that is using AJAX and try insert your own code -> http://plnkr.co/edit/o0Ig866BI3cYWAltNoFA?p=preview – davidkonrad Aug 15 '16 at 12:54
  • yes i did exactly same but it continuously giving error – Naila Akbar Aug 15 '16 at 13:10
  • 1
    @NullPointer - Fork the plunkr and let me see your code that is not working. – davidkonrad Aug 15 '16 at 13:16
  • finally it worked out. Issue was in js file.. thankyou – Naila Akbar Aug 15 '16 at 15:08
7

The example below uses AngularJs and Datatable. The filtering, pagination and sorting are working good.

Download angular-datatable and put angular-datatables.min.js file in your project as I do in the line <script src="angular-datatables/dist/angular-datatables.min.js"></script>

Hope this can help you.

<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
        <script src="http://cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
        <script src="angular-datatables/dist/angular-datatables.min.js"></script>   
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <link rel="stylesheet" href="http://cdn.datatables.net/1.10.7/css/jquery.dataTables.css">
    </head>
    <body>
        <div ng-app="AngularWayApp" ng-controller="AngularWayCtrl">
            <table datatable="ng" class="table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>City</th>
                        <th>Country</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="name in names" ng-click="testingClick(name)">
                        <td>{{name.Name}}</td>
                        <td>{{name.City}}</td>
                        <td>{{name.Country}}</td>
                      </tr>
                </tbody>
            </table>

            <script>
                var app = angular.module('AngularWayApp', ['datatables']);

                app.controller('AngularWayCtrl', function($scope, $http)
                {
                    $http.get("http://www.w3schools.com/angular/customers_mysql.php").success(function (response)
                    {
                        $scope.names = response.records;
                    });

                    $scope.testingClick = function(name)
                    {
                        console.log(name);
                    };
                });
            </script>
        </div>
    </body>
</html>
herbert
  • 307
  • 1
  • 3
  • 15