How to filter my data? (ng-grid)
Asked Answered
K

3

26

I think this is most likely very simple but I cannot find any clear documentation on how to add a filter outside of the 'filterText' that is shown on their website. What I am trying to do is something as simple as this:

$scope.filterOptions = {
    filter: $scope.myFilter,  // <- How to do something like this? 
    useExternalFilter: true
}

$scope.gridOptions = {
        data: 'entries',
        enableColumnResize: false,
        multiSelect: false,
        enableSorting: false,
        selectedItems: $scope.selectedEntries,
        filterOptions: $scope.filterOptions
}

$scope.lowerLimit = 50;
// My Filter
$scope.myFilter = function(entry) { 
    if (entry < $scope.lowerLimit) {
        return false; 
    }
    return true;
 }

Edit: Or maybe if I could filter the datasource somehow? I tried this:

$scope.gridOptions = {
        data: 'entries | filter: myFilter',
        enableColumnResize: false,
        multiSelect: false,
        enableSorting: false,
        selectedItems: $scope.selectedEntries,
}

But it is throwing quite a few errors.

Kuopio answered 31/7, 2013 at 18:14 Comment(7)
Take a look at this. github.com/angular-ui/ng-grid/issues/165Declinatory
I did see this in my searching but this is again for matching some or part of a string, I want to filter based on returning true or false from a custom function.Kuopio
I was hoping a CUSTOM_FILTER on this <div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD CUSTOM_FILTERS}}</span></div> would work, but that only filters a value, not the array. Code is from: angular-ui.github.io/ng-gridWoehick
Same problem with columnDefs cellFilter option. It only filters a single value, not the array.Woehick
There is a good answer here: github.com/angular-ui/ng-grid/issues/165. And the plunker which displays the answer: plnkr.co/edit/PHdBhF?p=previewWoehick
You do realized that @c0bra is one of main contributors, and at this time most active of ng-grid? His solution is correct, please accept the answer.Acarpous
@StephenPatten c0bra's answer - although it has been a while since I asked this question so I may be wrong - seems to correspond with what is on the basic ng-grid website and I remember not being able to apply the filter I wanted: (i.e. filter: ColumnVals < someLimit) which is what this question is about. I did however find a way and that is in my answer, his does not appear to give the same functionality - if it does, I would happily give the answer to him if he was a little more explicit about it :)Kuopio
K
6

I have found a way that updates instantly. Basically I hold a hidden set of all my data, and upon receiving new data or changing my filter - I apply this filter to the full data set and hand the grid the filtered version.

This lets me use comparators (i.e. age >= 50) in my filter, which is the purpose of this question.

// Full unfiltered data set
$scope.entries = []; // Updated and pushed to

$scope.gridOptions = {
    // The grids already filtered data set
    data: 'filteredEntries',
    enableColumnResize: false,
    multiSelect: false,
    enableSorting: false,
    selectedItems: $scope.selectedEntries,
}

 $scope.$on("updateEntries", function(data) {
     // My table is filled by socket pushes, this is where it is updated.
     $scope.updateFilters();
 }

 $scope.$on("newFilter", function(newFilter) {
     // This is where I update my filter
     $scope.updateFilters();
 }

 $scope.updateFilters = function() {
     // Filters the full set and hands the result to the grid. 
     $scope.filteredEntries = $filter('filter')($scope.entries, $scope.myFilter);
     $scope.$digest();
 }         

 // A modifiable limit, modify through newFilter so data is refiltered
 $scope.lowerLimit = 50;

 // My Filter
 $scope.myFilter = function(entry) { 
     if (entry < $scope.lowerLimit) {
        return false; 
     }
     return true;
 }
Kuopio answered 31/7, 2013 at 19:55 Comment(0)
R
22

You can use angular to bind to the filterOptions.filterText variable. There's a plunker here to demonstrate: http://plnkr.co/edit/PHdBhF?p=preview

I'll post the same code below:

    // main.js
    var app = angular.module('myApp', ['ngGrid']);
    app.controller('MyCtrl', function($scope) {
      $scope.filterOptions = {
        filterText: ''
      };

      $scope.myData = [{name: "Moroni", age: 50},
                       {name: "Tiancum", age: 43},
                       {name: "Jacob", age: 27},
                       {name: "Nephi", age: 29},
                       {name: "Enos", age: 34}];

      $scope.gridOptions = {
        data: 'myData',
        filterOptions: $scope.filterOptions
      };
    });

The above should be about identical to the plunkers on the docs page.

    <!DOCTYPE html>
    <html ng-app="myApp">
        <head lang="en">
            <meta charset="utf-8">
            <title>Custom Plunker</title>  
            <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
            <link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
            <link rel="stylesheet" type="text/css" href="style.css" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
            <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
            <script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
            <script type="text/javascript" src="main.js"></script>
        </head>
        <body ng-controller="MyCtrl">
          <strong>Filter:</strong><input type="text" ng-model="filterOptions.filterText" />
          <br/>
          <br/>
          <div class="gridStyle" ng-grid="gridOptions"></div>
        </body>
    </html>

Notice ng-model="filterOptions.filterText" on the <input ...>. That's all it takes!

Ragin answered 20/9, 2013 at 20:49 Comment(2)
This doesn't do the numeric comparison that the question is asking about.Labret
@Labret for that you will actually need to create your own external filter that alters the data before it makes it to the grid. Check this plunker: plnkr.co/edit/4aptwJ?p=previewRagin
K
6

I have found a way that updates instantly. Basically I hold a hidden set of all my data, and upon receiving new data or changing my filter - I apply this filter to the full data set and hand the grid the filtered version.

This lets me use comparators (i.e. age >= 50) in my filter, which is the purpose of this question.

// Full unfiltered data set
$scope.entries = []; // Updated and pushed to

$scope.gridOptions = {
    // The grids already filtered data set
    data: 'filteredEntries',
    enableColumnResize: false,
    multiSelect: false,
    enableSorting: false,
    selectedItems: $scope.selectedEntries,
}

 $scope.$on("updateEntries", function(data) {
     // My table is filled by socket pushes, this is where it is updated.
     $scope.updateFilters();
 }

 $scope.$on("newFilter", function(newFilter) {
     // This is where I update my filter
     $scope.updateFilters();
 }

 $scope.updateFilters = function() {
     // Filters the full set and hands the result to the grid. 
     $scope.filteredEntries = $filter('filter')($scope.entries, $scope.myFilter);
     $scope.$digest();
 }         

 // A modifiable limit, modify through newFilter so data is refiltered
 $scope.lowerLimit = 50;

 // My Filter
 $scope.myFilter = function(entry) { 
     if (entry < $scope.lowerLimit) {
        return false; 
     }
     return true;
 }
Kuopio answered 31/7, 2013 at 19:55 Comment(0)
N
0

This is my solution!!

It found with ng-grid in html:

<input type="text" ng-model="miinput" placeholder="Filter text"/>
<div class="gridStyles" ng-grid="gridOpciones">
</div>

in js:

//pagination
$scope.filterOptions = {
    filterText: $scope.miinput,
    useExternalFilter: true
}; 
$scope.totalServerItems = 0;
$scope.pagingOptions = {
    pageSizes: [10, 25, 50],
    pageSize: 10,
    currentPage: 1
};  
$scope.setPagingData = function(data, page, pageSize){  
    var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
    $scope.vocabulario = pagedData;
    $scope.totalServerItems = data.length;
    if (!$scope.$$phase) {
        $scope.$apply();
    }
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
    setTimeout(function () {
        var data;
        if (searchText) {
            var ft = searchText.toLowerCase();
            $http.get('http://localhost:9000/json/voc.json').success(function (largeLoad) {     
                data = largeLoad.filter(function(item) {
                    return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
                });
                $scope.setPagingData(data,page,pageSize);
            });            
        } else {
            $http.get('http://localhost:9000/json/voc.json').success(function (largeLoad) {
                $scope.setPagingData(largeLoad,page,pageSize);
            });
        }
    }, 100);
};

$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);

$scope.$watch('pagingOptions', function (newVal, oldVal) {
    if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
        $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
    }
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
    if (newVal !== oldVal) {
        $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
    }
}, true);

//cada vez que escribo en el input
$scope.$watch('miinput', function () {
    if ($scope.miinput !== "") {
        $scope.pagingOptions.currentPage=1;
        $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.miinput);
    }else{
        $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
    }
}, true);


 //
 $scope.gridOpciones = { 
    data: 'vocabulario',
    showGroupPanel: true,
    enableCellSelection: true,
    enableRowSelection: true,
    enableCellEdit: true,
    enablePaging: true,
    showFooter: true,
    totalServerItems: 'totalServerItems',
    pagingOptions: $scope.pagingOptions,
    filterOptions: $scope.filterOptions,
    columnDefs: [
    {field:'I', displayName:'Id', width:60,resizable: true}, 
    {field:'T', displayName:'Type',visible:false,resizable: true},
    {field:'N', displayName:'Level',width:60},
    {field:'L', displayName:'List',width:100},
    {field:'P', displayName:'English',minWidth: 400},
    {field:'R', displayName:'Spanish', minWidth: 400}]
 };

//JSON

 [
{"I": "3001", "T": "F", "N": "3", "L": "01 a", "P": "HE IDO ALL\u00cd DOS VECES ESTA SEMANA", "R": "I'VE GONE THERE TWICE THIS WEEK"},
{"I": "3002", "T": "F", "N": "3", "L": "01 a", "P": "\u00c9L ME HA LLAMADO VARIAS VECES HOY", "R": "HE'S CALLED ME SEVERAL TIMES TODAY"},
 {"I": "3003", "T": "F", "N": "3", "L": "01 a", "P": "HEMOS LLEGADO A UNA CONCLUSI\u00d3N", "R": "WE'VE REACHED A CONCLUSION"},
 {"I": "3004", "T": "F", "N": "3", "L": "01 a", "P": "HEMOS DECIDIDO CANCELAR EL PROYECTO", "R": "WE'VE DECIDED TO CANCEL THE PROJECT"},
 {"I": "3005", "T": "F", "N": "3", "L": "01 a", "P": "NO HAN HECHO NADA", "R": "THEY HAVEN'T DONE ANYTHING"},
 {"I": "3006", "T": "F", "N": "3", "L": "01 a", "P": "HE PROBADO MUCHAS DIFERENTES PROFESIONES", "R": "I'VE TRIED MANY DIFFERENT PROFESSIONS"},
 {"I": "3007", "T": "F", "N": "3", "L": "01 a", "P": "\u00c9L HA PERDIDO LA VOZ", "R": "HE'S LOST HIS VOICE"}, 
{"I": "3008", "T": "F", "N": "3", "L": "01 a", "P": "ELLA NO HA VENIDO POR AQU\u00cd \u00daLTIMAMENTE"}
]
Nola answered 12/11, 2014 at 22:18 Comment(1)
Do you have a working sample? In jsfiddle or plunkr? It would help a lotRaffle

© 2022 - 2024 — McMap. All rights reserved.