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.

0

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

9 Comments

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
stay blessed dude.. very nice explanation.
@davidkonrad can you elaborate how we can use search and sort functionality using directive? because in my case those are also not working
@NullPointer, yes - use the angular datatables directives really easy to use and support all functionality, here is an example -> 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.
@NullPointer - Fork the plunkr and let me see your code that is not working.
|
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>

2 Comments

Thanks so much, all I needed was this ==> datatable="ng"
nice one. its helped me a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.