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

Bug when sort on filtred data #289

Closed
MowWow opened this issue Apr 22, 2015 · 19 comments
Closed

Bug when sort on filtred data #289

MowWow opened this issue Apr 22, 2015 · 19 comments
Labels

Comments

@MowWow
Copy link

MowWow commented Apr 22, 2015

hi,

I have a table, containing some data. And i have two filters ont the data
example of table définition :
<table datatable dt-options="dtOptions" ng-repeat="x in accueils | filter:{annee:annee.id} | filter:myFilter as results" ng-if="$first">

So when i first load my page, i have 10 rows in my table, and the sort works good.
Then, i click on a filter button, so instead of having 10 rows, no i have 5 rows, then i click on any table header to sort the column, and then i have the problem as the number of rows become 10 again, the filtering is loosed, any idea how to keep the filter value ?

Thanks

@l-lin
Copy link
Owner

l-lin commented Apr 23, 2015

Can you provide your full example?
Should your ng-repeat not in the <table> tab, but in the <tr> tag instead?
Are you using the Angular renderer? If so, then don't forget to add the ng on the value of the attribute datatable.

@MowWow
Copy link
Author

MowWow commented Apr 23, 2015

Thanks for your answer
I edited the definition to datatable="ng", changed nothing for me.
The ng-repeat is also added in the table tag, cause when using the filters, sometimes i obtain no results, and when it happens, i want the table to be hidden, and on stackoverflow, the told me to do so.
I'm a beginner with angular and with datatables. I don't know what's an Angular Render, but i don't think i'm using one

I would like to show you my code too, but it's too long as i display 20 tables in a single html file. I can provide a zip file, but i don't see any attach file option :(

@MowWow
Copy link
Author

MowWow commented Apr 23, 2015

Ok here's a table example

var app = angular.module('mind', ['ngCookies', 'datatables']);
app.controller('deplacementsCtrl', function($scope, $http, DTOptionsBuilder) {
    $http.get("JSON_FEED_LINK")
        .success(function(response) {
        $scope.fraiss = response.fraiss;
        $scope.annees = response.annees;
        for (var i = 0; i < $scope.annees.length; i++) {
            if ($scope.annees[i].id == response.actannee) {
                actannee = $scope.annees[i];
            }
        }


        $scope.annee = actannee;
        $scope.clearFilter = function() {
            $scope.myFilter = {};
        };

        $scope.myFilter = {};
        $scope.updateFilter = function(key, val) {
            $scope.myFilter[key] = val;
        }

        $scope.dtOptions = DTOptionsBuilder.newOptions()
            .withOption("bPaginate", false)
            .withOption("bLengthChange", false)
            .withOption("bFilter", false)
            .withOption("bInfo", false)
            .withOption("bAutoWidth", false)
            .withOption("bSort", true)
            .withOption("aaSorting", []);

    });





});

then the html code

<div ng-app="mind" ng-controller="deplacementsCtrl" > 
    <div class="filtre">
        <form>
            <label for="selectannee6">Année financière</label>
            <select ng-model="annee" id="selectannee6" ng-options="annee.titre for annee in annees track by annee.id" >

            </select>

        </form> 
        <span class="trititle">Trimestre : </span><ul>
            <li ng-class="{true:'selected', false:''}[!myFilter.trimestre]"> 
                <span ng-if="!myFilter.trimestre">Année complète</span>
                <a ng-if="myFilter.trimestre>0" ng-click="clearFilter()" href="#">Année complète</a>
            </li>
            <li ng-class="{true:'selected', false:''}[myFilter.trimestre==1]">
                <span class="selected" ng-if="myFilter.trimestre==1">Avril - juin</span>
                <a ng-if="myFilter.trimestre !=1" ng-click="updateFilter('trimestre',1)" href="#">Avril - juin</a>
            </li>
            <li ng-class="{true:'selected', false:''}[myFilter.trimestre==2]">
                <span class="selected" ng-if="myFilter.trimestre==2">Juillet - septembre</span>
                <a  ng-if="myFilter.trimestre!=2" ng-click="updateFilter('trimestre',2)" href="#">Juillet - septembre</a> </li>
            <li ng-class="{true:'selected', false:''}[myFilter.trimestre==3]">
                <span class="selected" ng-if="myFilter.trimestre==3">Octobre - décembre</span>
                <a  ng-if="myFilter.trimestre!=3" ng-click="updateFilter('trimestre',3)" href="#">Octobre - décembre</a> 
            </li>
            <li ng-class="{true:'selected', false:''}[myFilter.trimestre==4]">
                <span class="selected" ng-if="myFilter.trimestre==4">Janvier - mars</span>
                <a  ng-if="myFilter.trimestre!=4"  ng-click="updateFilter('trimestre',4)" href="#">Janvier - mars</a> </li>
        </ul>
    </div>

    <table datatable="ng"  dt-options="dtOptions" ng-if="results.length > 0">
        <thead>
            <tr>
                <th>Col 1</th>
                <th>Col 2</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="x in fraiss | filter:{annee:annee.id} | filter:myFilter as results" > 
                <td ng-if="x.type==1">Personnel de l'organisme public</td>
                <td ng-if="x.type==2">Le personnel de cabinet du ministre {{x.ministre}}</td>
                <td><span ng-bind-html="x.montant  | to_trusted"></span>&nbsp;$</td>
            </tr>
        </tbody>
    </table>
    <div ng-if="results.length < 1" class="noresults">Aucune donnée à afficher pour la période visée</div>

</div>

As you can see, there are two filters. On by "annee", and the other (myFilter) is by a field "trimestre". The problem happens when i use the "trimestre" filter. For example, When i click on a "trimestre" choice, i got fewer results, then i click on a table header, the "trimestre" filter is loosed, and i got more results.
Please help me

@MowWow
Copy link
Author

MowWow commented Apr 24, 2015

When i first load the page, the filter "annee" has the value 3 by default. so all the data having the field "annee":"3" are shown. Then for example, if i change the filters values, i got new data displayed, and then i click on a table header, what happens is the data that was displayed when i first loaded the page are shown. Si i have to figure out, how to tell Datatables that the data displayed changed since i changed the filters, and that Datatables has to sort the filtered data, and not those displayed when the page is loaded.

Any hint ? please!

@MowWow
Copy link
Author

MowWow commented Apr 24, 2015

I used http://debug.datatables.net/ (Datatables debugger) to see what's going on, and indeed, the version sent to Datatables is the one when the page is loaded. Everytime the table changes, Datatables doesn't detect that.

Any idea on how we make it detect the change with angularjs please ?

Thanks

@l-lin
Copy link
Owner

l-lin commented Apr 24, 2015

Can you put your code in a plunker? It will be easier to debug your issue.

@fforres
Copy link

fforres commented Apr 26, 2015

Hey, i believe we are battling against a similar issue
#300

I've created a codepen http://codepen.io/forres/pen/WvbwPq?editors=101

@MowWow
Copy link
Author

MowWow commented Apr 26, 2015

Yep this looks to be exactly my problem.
I can't access my code right now, i'll try to post a plunker monday, but yes that's exactly my problem as datatables always consider rows displayed at the loading of the page

@fforres
Copy link

fforres commented Apr 26, 2015

I managed to isolate the issue
Created a different codepen for it
http://codepen.io/forres/pen/NqPrKQ?editors=101

The point is we where using $scope to save our different data & configurations, and I believe that by using "THIS" as the main variable, yo manage to keep the angular $digest working correctly.

I cant really say for sure, i'm not that much of an angular dev.
would love for @l-lin to enlighten us on this 😄

@MowWow
Copy link
Author

MowWow commented Apr 27, 2015

@l-lin ok you can see my bug here : http://codepen.io/anon/pen/RPNZXp?editors=101

When i first load the page, i have 4 rows, then i click on "Avril - Juin", i obtain 2 rows, then i try to sort =>back to 4 rows

@MowWow
Copy link
Author

MowWow commented Apr 28, 2015

Up

Do you think it's possible to fix this bug ? thanks

@l-lin
Copy link
Owner

l-lin commented Apr 28, 2015

You need to differenciate the sorting from Angular and from DataTables. When you update your filter, only the array in Angular is updated. However, the data stored in the DataTable is not updated.

So after you updated your data in your angular controller, you will need to rerender your datatables.
I updated your pen.

@MowWow
Copy link
Author

MowWow commented Apr 28, 2015

That's weird, your pen works perfectly, but when i use the same fixes in my code (where i have 20 tables), i got this error everytime instance.rerender(); is called :

Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

Gosh i hate it when i work with something i don't master ...

Thanks a lot l-lin

@MowWow
Copy link
Author

MowWow commented Apr 28, 2015

I'm trying to debug, and i noticed that the problem is caused by the presence of multiple tables in the same page.
The error is coming from this line in jquery.dataTables.js

orig.insertBefore( table, settings.nTableReinsertBefore );

This line is called when the line instance.rerender(); is called when i filter my data
So i tried to debug those two variables, table and settings.nTableReinsertBefore

the table variable isn't pointing the table on which i applied a filter. It points to another table (a hidden one) and everytime i try to filter data, this wrong table is deleted from the DOM

And settings.nTableReinsertBefore is pointing on this element :

<h3 class="dt-loading" style="display: none;">Loading...</h3>

And this element isn't placed near the table on wich i applied a filter neither!

I tried to add an id on each table. changed nothing.

Could this be a bug in Datatables ?

I put my whole code here (a zip file containing html and scripts ..) https://drive.google.com/file/d/0B2RwGZgU4S4YRjdRMlJLN0RLd0U/view?usp=sharing

I applied l-lin fixes only in one table : click "DÉPENSES DE L'ORGANISME PUBLIC" and then click "Frais de déplacement"

Thanks a lot

@MowWow
Copy link
Author

MowWow commented May 1, 2015

Here is a pen to see that the bugs is not really fixed when i have multiple tables on my page

http://codepen.io/anon/pen/eNNVgo?editors=101

When using filters on the first table it works, but when i use filter on the second table, and then i sort, nothing works. And when i tried debuggin on the jquery-datatables.js script, i noticed that the table passed to the function insertBefore is not the right one

@l-lin
Copy link
Owner

l-lin commented May 2, 2015

That's because the DTInstances.getLast() does not really work well with multiple tables. There is an issue about this #297.
However, I'm considering removing the DTInstances services and instead follow heliodor's advice.

So to answer your question, it won't work with multiple tables on the same page, yet.

@MowWow
Copy link
Author

MowWow commented May 2, 2015

Ok, i'll wait for the next version including the bug fix then.

Thanks a lot!

@l-lin l-lin added the wontfix label May 2, 2015
@l-lin l-lin closed this as completed May 2, 2015
@MowWow
Copy link
Author

MowWow commented May 8, 2015

I just tried the solution, with dtInstance, changed nothing for me http://codepen.io/anon/pen/eNNVgo?editors=101
Still have the same error, there's even js errors now :(

@l-lin
Copy link
Owner

l-lin commented May 8, 2015

I corrected your pen.
You don't need DTInstances anymore.

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