lorraine batol
lorraine batol

Reputation: 6281

datatable buttons - data from angular

I'm using JQuery Datatables buttons for presenting the data on my page (as it has functions for items like Copy to Clipboard /Export to CSV / Print. Then, for the retrieval of data from the server, I'm using angular js.

The issue is that the data rendered from angular ng-repeat won't appear when invoking datatable buttons like copy/csv/print/etc, but these items appeared just fine on the page. But for the static dummy data that I have included, it is being processed by the buttons.

Below are the code snippets:

excerpt from page:

                            <table id="datatable-buttons" class="table table-striped table-bordered ng-cloak">
                                <thead>
                                <tr>
                                    <th>First Name</th>
                                    <th>Last Name</th>
                                    <th>Job</th>
                                    <th>Location</th>
                                    <th>Age</th>
                                    <th>Date Hired</th>
                                    <th>Email</th>
                                </tr>
                                </thead>
                                <tbody>
                                <tr>
                                    <td>Donna</td>
                                    <td>Snider</td>
                                    <td>Customer Support</td>
                                    <td>New York</td>
                                    <td>27</td>
                                    <td>2011/01/25</td>
                                    <td>[email protected]</td>
                                </tr>
                                <tr ng-repeat="person in persons">
                                    <td>{{person.fname}}</td>
                                    <td>{{person.lname}}</td>
                                    <td>{{person.job}}</td>
                                    <td>{{person.location}}</td>
                                    <td>{{person.age}}</td>
                                    <td>{{person.date_hired}}</td>
                                    <td>
                                        <div ng-show="person.email == null">N/A</div>
                                        <div ng-show="person.email != null">{{person.email}}</div>
                                    </td>
                                </tr>
                                </tbody>
                            </table>

...

<script>
    $(document).ready(function() {
        var handleDataTableButtons = function() {
            if ($("#datatable-buttons").length) {
                $("#datatable-buttons").DataTable({
                    dom: "Bfrtip",
                    buttons: [
                        {
                            extend: "copy",
                            className: "btn-sm"
                        },
                        {
                            extend: "csv",
                            className: "btn-sm"
                        },
                        {
                            extend: "excel",
                            className: "btn-sm"
                        },
                        {
                            extend: "pdfHtml5",
                            className: "btn-sm"
                        },
                        {
                            extend: "print",
                            className: "btn-sm"
                        },
                    ],
                    responsive: true
                });
            }
        };

        TableManageButtons = function() {
            "use strict";
            return {
                init: function() {
                    handleDataTableButtons();
                }
            };
        }();

        $('#datatable').dataTable();

        $('#datatable-keytable').DataTable({
            keys: true
        });

        $('#datatable-responsive').DataTable();

//        $('#datatable-scroller').DataTable({
//            ajax: "js/datatables/json/scroller-demo.json",
//            deferRender: true,
//            scrollY: 380,
//            scrollCollapse: true,
//            scroller: true
//        });

        $('#datatable-fixed-header').DataTable({
            fixedHeader: true
        });

        var $datatable = $('#datatable-checkbox');

        $datatable.dataTable({
            'order': [[ 1, 'asc' ]],
            'columnDefs': [
                { orderable: false, targets: [0] }
            ]
        });
        $datatable.on('draw.dt', function() {
            $('input').iCheck({
                checkboxClass: 'icheckbox_flat-green'
            });
        });

        TableManageButtons.init();
    });
</script>

Any help would be appreciated. TIA

Upvotes: 1

Views: 891

Answers (1)

davidkonrad
davidkonrad

Reputation: 85578

The code above seems to be overcooked to the extreme :) Why on earth all those contortions? The mix of jQuery and angular is general a very bad idea. There is race issues and you cannot rely on any of your $(document).ready's at all. In fact, $(document).ready() will be fired more or less the exact same time as angular is going to take care of its business - like processing the ng-repeat's ...

The real solution for you would be to use the angular directives for dataTables.

The short term solution is to skip the ingenious flow of readys and sanity checks :

$(document).ready(function() {
    var handleDataTableButtons = function() {
        if ($("#datatable-buttons").length) {
            $("#datatable-buttons").DataTable({

Is just bad coding, in a jQuery context as well - no offense, have been there :) Use a $timeout instead, that will ensure that the table is initialised in a later digest, that will be when the table is rendered by ng-repeat :

$timeout(function() {
   $("#datatable-buttons").DataTable({
   ...
   })
})

Will work.

Upvotes: 2

Related Questions