l-lin / angular-datatables

DataTables with Angular
https://l-lin.github.io/angular-datatables/
MIT License
1.57k stars 486 forks source link

Multiple Instances with different options #210

Closed Gbeschbacher closed 8 years ago

Gbeschbacher commented 9 years ago

Heyo,

I am using datatables in 2 different locations with 2 different controllers and options. Nevertheless the second table doesn't work at all as expected. Following is my code and afterwards my issue explained:


//Controller 1 with Options set
angular.module('app.controllers').controller("PatientAddCtrl", ["$scope", "DTOptionsBuilder", "DTColumnDefBuilder", "$translate",
    function($scope, DTOptionsBuilder, DTColumnDefBuilder, $translate){

        //set options for datatable in patientAdd (responsive, bootstrap, i18n)

        $scope.dtOptions = DTOptionsBuilder.newOptions().withBootstrap().withOption('responsive', true).withLanguageSource("static/languages/" + $translate.use() +".json");

        //- make column 1,2,3,10 un-sortable
        $scope.dtColumnDefs = [
            DTColumnDefBuilder.newColumnDef(0).notSortable(),
            DTColumnDefBuilder.newColumnDef(2).notSortable(),
            DTColumnDefBuilder.newColumnDef(3).notSortable(),
            DTColumnDefBuilder.newColumnDef(4).notSortable(),
            DTColumnDefBuilder.newColumnDef(5).notSortable()
        ];
    }
]);

//Controller 2 with Options set
angular.module('app.controllers').controller("PatientOverviewCtrl", ["$scope", "DTOptionsBuilder", "DTColumnDefBuilder", "$translate",
    function($scope, DTOptionsBuilder, DTColumnDefBuilder, $translate){

        //set options for datatable in patientOverview (responsive, bootstrap, i18n)
        $scope.dtOptions = DTOptionsBuilder.newOptions().withBootstrap().withOption('responsive', true).withLanguageSource("static/languages/" + $translate.use() +".json");

        //- make column 1,2,3,10 un-sortable
        $scope.dtColumnDefs = [
            DTColumnDefBuilder.newColumnDef(0).notSortable(),
            DTColumnDefBuilder.newColumnDef(1).notSortable(),
            DTColumnDefBuilder.newColumnDef(2).notSortable(),
            DTColumnDefBuilder.newColumnDef(9).notSortable()
        ];
    }
]);

Following are my 2 different HTML Files (in Jade) with the datatables

//- Jade file 1
table.no-wrap.table-bordered.dt-responsive(datatable="drugs", dt-options="dtOptions", dt-column-defs="dtColumnDefs", width="100%")
    thead
        tr.gradient-orange.white
            th.sorting_disabled
                i.fa.fa-thumbs-o-up.fa-2x
            th {{ 'DRUGS' | translate}}
            th {{ 'DOSAGE' | translate}}
            th {{ 'PRESCRIBED-F' | translate}}
            th {{ 'PRESCRIBED-T' | translate}}
            th {{ 'EDIT' | translate}}
    tbody
        tr
            td
                color-circle(data-perc="{{medVal}}")
            td temp name of a drug
            td 1-2-1
            td 1. Okt. 2014
            td 12. Okt. 2014
            td
                a(href="#")
                    i.fa.fa-arrow-right.fa-2x

//- Jade file 2
table.no-wrap.table-bordered(datatable="overview", dt-options="dtOptions", dt-column-defs="dtColumnDefs", width="100%")
    thead
        tr.gradient-orange.white
            th.sorting_disabled
                i.fa.fa-thumbs-o-up.fa-2x
            th.sorting_disabled
                i.fa.fa-exclamation-triangle.fa-2x
            th.sorting_disabled
                i.fa.fa-check-circle.fa-2x
            th {{ 'NAME' | translate}}
            th {{ 'SURNAME' | translate}}
            th {{ 'BIRTHDAY' | translate}}
            th {{ 'SSN' | translate}}
            th {{ 'ACTIVATION' | translate}}
            th {{ 'LAST_EDITED' | translate}}
            th.sorting_disabled {{'EDIT' | translate}}
    tbody
        tr
            td
                color-circle(data-perc="{{val.like}}")
            td
                color-circle(data-perc="{{val.warning}}")
            td
                color-circle(data-perc="{{val.check}}")
            td Thomas
            td Mustermann
            td 1.1.1987
            td 2222
            td 2014-01-01
            td 2014-01-01
            td
                a(href="#")
                    i.fa.fa-arrow-right.fa-2x

And in case it helps for any advices or solutions, here is my app.js file of angular

var app = angular.module("app", [
    "ngRoute",
    "app.controllers",
    "app.directives",
    "pascalprecht.translate",
    "ng-breadcrumbs"
    ]
);

// Controller-Definition with Deps
angular.module("app.controllers", ["datatables", "datatables.bootstrap", "pascalprecht.translate", "ui.bootstrap", "ng-breadcrumbs"]);

// Directive-Definition with Deps
angular.module("app.directives", []);

// Main App-Configs with Deps
app.config(["$routeProvider", "$locationProvider", "$translateProvider",
    function($routeProvider, $locationProvider, $translateProvider){

        //HTML history api
        $locationProvider.html5Mode(true);

        //Route Definitions
        $routeProvider
        .when("/patients", {templateUrl: "partials/patientOverview", controller: "PatientOverviewCtrl", label: "Patients Overview"})
        .when("/patients/add-patient", {templateUrl: "partials/patientAdd", controller: "PatientAddCtrl", label: "Add Patient"})
        .when("/details", {templateUrl: "partials/patientDetails", controller: "PatientDetailsCtrl"})
        .otherwise({redirectTo: "/patients"});

        //I18N
        $translateProvider.preferredLanguage('de');
        $translateProvider.useStaticFilesLoader({
            prefix: 'static/languages/',
            suffix: '.json'
        });
    }
]);

This code produces following issue: The first table is rendering as expected with working responsive and bootstrap and un-sortable columns etc. The second table is not responsive anymore at all but still uses bootstrap and set the specified columns as un-sortable including the correct language. An interesting thing now is, that if i completly leave out the options and column-defs for the second table, it is still responsive and keeps the columns un-sortable which i specified for table 1 but bootstrap and language-settings are completly missing.

Am i doing something wrong here? Please help! Every advice or possible solution is appreciated

l-lin commented 9 years ago

Are those two tables in different views (if you are using router) or in the same view? Are they in different tabs but in the same view?

Gbeschbacher commented 9 years ago

i don't know if i can fully understand your point but these are 2 completly seperated views with no knowledge of each other actually.

any more code needed which would help you to understand my problem?

thanks already for the very fast reply!

EDIT1: sorry - just saw that the router still said patientAdd and patientOverview and the jade files have been file 1 and file 2 - they correspond to either one

l-lin commented 9 years ago

Mmmh maybe you might need to set the attribute autoWidth to false. See this plnkr for example.

Gbeschbacher commented 9 years ago

no difference - anything else i could try out?

EDIT1: if it helps i could send you a collaboration invitation to my private-repository

Saabertooth commented 9 years ago

I believe I have the same issue as described above. It seems that the wrong (previous) instance of datatables is being used. If I manually run DTInstances.getLast() after the table has been initialized, I do get the correct instance but it is being set as the previous upon initial load

EDIT: I have implemented a workaround for the time being by creating a recursive function that grabs the latest DTInstance upon controller initialization (or in my case after the datatables directive has had a chance to initialize)

function getDTInstance(newVal) {
            $timeout(function () {
                DTInstances.getLast().then(function (dtInstance) {
                    if (newVal == dtInstance) {
                        $scope.dtData.dtInstance = dtInstance; //or whatever
                    }
                    else {
                        getDTInstance(dtInstance);
                    }
                });
            });
        }

In my case, I have an ngIf directive on the datatables directive and so this function is called after the ngIf condition is set to true. Typically, the first time it executes newVal is undefined, the second time newVal is equal to the datatables instance from the previous controller that implemented a datatable, and the third is typically the correct instance.

I imagine that if any of these DTInstances functions are executed upon controller initialization that we may indeed get a previous instance as well even without using ngIf on the directive

mfields106 commented 9 years ago

Can you explain why you closed this? We are also getting the same issue.

l-lin commented 9 years ago

Because I do not reproduce this issue and I do really know where the issue is really. As for the comment of @Saabertooth, it should be fixed with the newest versions as DTInstance.getLast is replaced by providing the object/callback directly in the HTML. For @Gbeschbacher's project, unfortunately, I do not really use jade and I couldn't really run his application.

But you are right, I'll keep it open and it will be better if there is a plnkr or something alike that reproduces the issue.

LuciferZhang commented 8 years ago

I also met the same question! two datatable instances in one view(two tab-pages). I set the width on tr th with 10%, but it didnt work. And I had try to set .withOption('autoWidth', false) .withOption('responsive', true); It had been solved!