Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

Reload datatable when changing dtOptions #225

Closed
pidupuis opened this issue Feb 18, 2015 · 11 comments
Closed

Reload datatable when changing dtOptions #225

pidupuis opened this issue Feb 18, 2015 · 11 comments
Labels

Comments

@pidupuis
Copy link

In my context, I have a search form. When you submit this form, the client will send an ajax request to retrieve result rows. Once this rows are client-side, I create a datatable and I'm playing around with the rows inside fnServerData.

Basically I have something like this:

self.searchButtonClick = function() {
    myService.getData(myCriteria).then(function(rows) {
        self.dtColumnDefs = [ ... ];
        self.dtOptions = DTOptionsBuilder.newOptions()
            .withOption('fnServerData', function (sSource, aoData, fnCallback) {
                // Do some work with rows and aoData
                fnCallBack(json);
        });
    }
}

The first search works great. When I submit a second time, I retrieve well the result rows from the server, but rewrite dtOptions is not enough to update the datatable content.

I would like to erase and recreate the datatable each time the user submit the form.

I tried to do it using this link but I don't understand it well.

@l-lin
Copy link
Owner

l-lin commented Feb 18, 2015

The API reloadData and rerender are from the DTInstance.
For example:

var self = this; // I suppose
var dtInstance;

self.searchButtonClick = function() {
    myService.getData(myCriteria).then(function(rows) {
        self.dtColumnDefs = [ ... ];
        self.dtOptions = DTOptionsBuilder.newOptions()
            .withOption('fnServerData', function (sSource, aoData, fnCallback) {
                // Do some work with rows and aoData
                fnCallBack(json);
        });
    }
}

self.doSomething = function() {
    // ...

    // This will resend the data to the server
    dtInstance.reloadData();
    // If you want to rerender your table, you can use the following.
    // This will redraw completly. This does not necessarly resend the data.
    dtInstance.rerender();
};

DTInstances.getLast().then(function(inst) {
    dtInstance = inst;
});

@pidupuis
Copy link
Author

Thanks, it works!

Final code:

var self = this;
var dtInstance;

self.searchButtonClick = function() {
    myService.getData(myCriteria).then(function(rows) {
        self.dtColumnDefs = [ ... ];
        self.dtOptions = DTOptionsBuilder.newOptions()
            .withOption('fnServerData', function (sSource, aoData, fnCallback) {
                // Do some work with rows and aoData
                fnCallBack(json);
        });
        if(dtInstance) {dtInstance.rerender();}
    }
}

DTInstances.getLast().then(function(inst) {
    dtInstance = inst;
});

@pidupuis
Copy link
Author

I'm not able to rerender two different datatables in the same time.

From the previous code, I would like to do something like this:

var self = this;
var dtInstance1;
var dtInstance2;
DTInstances.getLast().then(function(inst) {
    dtInstance1 = inst;
});
// how to retrieve dtInstance2 ?

self.searchButtonClick = function() {
    myService.getData(myCriteria).then(function(rows) {
        self.dtColumnDefs1 = [ ... ];
        self.dtOptions1 = DTOptionsBuilder.newOptions()
            .withOption('fnServerData', function (sSource, aoData, fnCallback) {
                // Do some work with rows and aoData
                fnCallBack(json);
        });
        self.dtColumnDefs2 = [ ... ];
        self.dtOptions2 = ...;

        if(dtInstance1) {dtInstance1.rerender();}
        if(dtInstance2) {dtInstance2.rerender();}
    }
}

The getLast() method returns only one of the two tables. I tried to use getList() as following:

DTInstances.getList().then(function(instances) {
    dtInstance1 = instances[0];
    dtInstance2 = instances[1];
});

But I obtained the following error "Error: _dtInstances is null

@l-lin
Copy link
Owner

l-lin commented Mar 20, 2015

DTInstances.getList() does not return an array but an object:

DTInstances.getList().then(function(dtInstances) {
    /*
     * dtInstances === {
     *      "foobar": {"id": "foobar", "DataTable": oTable, "dataTable": $oTable},
     *      "foobar2": {"id": "foobar2", "DataTable": oTable, "dataTable": $oTable}
     * }
     */
});

@pidupuis
Copy link
Author

Ok, that's good to know.

But the fact is I obtain the error before the variable manipulation.

For instance:

DTInstances.getList().then(function(dtInstances) {
});

triggers the exact same error "Error: _dtInstances is null.

I am using angular 1.3.6 and angular-datatables ~0.4.0.

@l-lin
Copy link
Owner

l-lin commented Mar 20, 2015

Yes, it's a bug from v0.4.0 (see issue #198).
Use a newer version of angular-datatables.

@pidupuis
Copy link
Author

Ok thanks!

@pidupuis
Copy link
Author

I'm still having trouble updating two datatables.

var self = this;
var dtInstance1;
var dtInstance2;
DTInstances.getList().then(function(dtInstances) {
    dtInstance1 = dtInstances.datatable1;
    dtInstance2 = dtInstances.datatable2;
});

self.searchButtonClick = function() {
    myService.getData(myCriteria).then(function(rows) {
        self.dtColumnDefs1 = [ ... ];
        self.dtOptions1 = DTOptionsBuilder.newOptions()
            .withOption('fnServerData', function (sSource, aoData, fnCallback) {
                // Do some work with rows and aoData
                fnCallBack(json);
        });
        self.dtColumnDefs2 = [ ... ];
        self.dtOptions2 = ...;

        if(dtInstance1) {dtInstance1.rerender();}
        if(dtInstance2) {dtInstance2.rerender();}
    }
}

At the end of this code, when I put only one of the two rerender, the corresponding table is well updated (no matter it is datatable1 or datatable2).

But when I put the two rerender calls (no matter the order), there is some unexpecting results. I obtain the message Error: Node was not found and the datatable2 disapears. The datatable1 is well updated. But then I try again, and datatable1 disapears as well (with the same error message).

The error stack trace is:

Error: Node was not found
@http://localhost:3000/bower_components/datatables/media/js/jquery.dataTables.js:9034:4
_Api.prototype.iterator@http://localhost:3000/bower_components/datatables/media/js/jquery.dataTables.js:6827:11
@http://localhost:3000/bower_components/datatables/media/js/jquery.dataTables.js:8967:0
_Api.extend/methodScoping/<@http://localhost:3000/bower_components/datatables/media/js/jquery.dataTables.js:6990:15
rerender@http://localhost:3000/bower_components/angular-datatables/dist/angular-datatables.js:828:12
rerender@http://localhost:3000/bower_components/angular-datatables/dist/angular-datatables.js:492:8
self.search/</</<@http://localhost:3000/scripts/controllers/search.js:390:20

@pidupuis
Copy link
Author

I could not reproduce this error in my plunker, and I solved it in a strange way, see this post.

This exception does not occur anymore but I found a kind of bug. The datatable is not rerendered if the column defs are not changed.

See my plunkr: only the second table will be rerendered because the first one keeps the same header.

@l-lin
Copy link
Owner

l-lin commented Apr 14, 2015

I created a new issue #275. Thanks for noticing this issue. 👍

@l-lin l-lin closed this as completed Apr 14, 2015
@atulbaldaniya
Copy link

atulbaldaniya commented May 11, 2018

In controller:

DTInstances.getLast().then(function(inst) {
        $scope.dtInstancePermission = inst;
});

In View :

<table datatable="" dt-options="dtOptionPermission" dt-columns="dtColumnPermission"  dt-instance="dtInstancePermission" dt-column-defs="dtColumnPermissionDefs" class="m-datatable__table" cellspacing="0" width="100%" data-height="auto"></table>

Thanks, @l-lin
This is work like the charm!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants