How to Have Select Filter in Ngtable

ng-table Filter via select drop down menu

First things first: a warning, you're loading Angular twice. Get rid of one of the <script> tags pointing to Angular.


1) How do i get rid of the pagination created as a result of the filter menu? I only need one pagination.

You see two pagination controls because you've created two ng-tables. You need to get rid of the table for the filter and use a normal select HTML element for that.

  <select ng-model="demo.tableParams.filter()['name']">
<option value="">All</option>
<option value="teste1">->teste1</option>
<option value="teste2">->teste2</option>
<option value="teste3">->teste3</option>
<option value="teste4">->teste4</option>
<option value="teste5">->teste5</option>
</select>

2) The default filter menu is blank which shows ALL data. This is great. How do i change the blank field to "ALL" text field?

As shown above, just add an option with value="". This will make all the items in the dataset a match.

3) Instead of straight away filtering, can i add a submit button before invoking the filter function?

Check out NgTable samples - change filter values programmatically.

Working demo here.

    angular.module("uCloud", ["ngTable"])  .controller("myController", myController);
myController.$inject = ["NgTableParams"];
function myController(NgTableParams) {
this.tableParams = new NgTableParams({}, { dataset: [{ name: "teste1", description: "testando1" }, { name: "teste2", description: "testando2" }, { name: "teste3", description: "testando3" }, { name: "teste4", description: "testando4" }], });}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><script src='https://unpkg.com/ng-table/bundles/ng-table.min.js'></script><script src="index.js"></script><!DOCTYPE html><html ><head>    <meta charset="UTF-8">    <title>ng-table - Select Filter</title>    <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet prefetch' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css'></head>
<body><div ng-app="uCloud" class="container-fluid"> <div class="row"><div class="col-md-3" ng-controller="myController as demo"> <h3>ngTable</h3> <table ng-table="demo.tableParams" class="table table-condensed table-bordered table-striped"> <tr ng-repeat="row in $data"> <td data-title="'Name'" filter-data="demo.nameFilter">{{row.name}} </td> <td data-title="'Description'" filter-data="demo.descriptionFilter">{{row.description}} </td> </tr> </table> <select ng-model="demo.tableParams.filter()['name']"> <option value="">All</option> <option value="teste1">->teste1</option> <option value="teste2">->teste2</option> <option value="teste3">->teste3</option> <option value="teste4">->teste4</option> <option value="teste5">->teste5</option> </select></div> </div></div>

</body></html>

How to populate select filters on ng-table from async call

I had a similar but slightly more complex issue. I wanted to be able to update the list of filters dynamically which seemed totally doable since they should just in a $scope variable anyway. Basically, I expected that, if I have $scope.filterOptions = []; then I could set filter-data="filterOptions" and any update to that list would be automatically reflected. I was wrong.

But I found a solution that I think is pretty good. First, you need to override the ngTable select filter template (in case you don't know how to do this, it involves using $templateCache and the key you need to override is 'ng-table/filters/select.html').

In the normal template, you'll find something like this ng-options="data.id as data.title for data in $column.data" and the problem with that is that $column.data is a fixed value that won't change when we update $scope.filterOptions.

My solution is to pass only the $scope key as filter-data instead of passing the whole list of options. So, instead of filter-data="filterOptions", I'll pass filter-data="'filterOptions'" and then, put a small change in the template like: ng-options="data.id as data.title for data in {{$column.data}}".

Obviously, this is a significant change to how the select filter works. In my case, it was for a very small app that only had one table but you may be concerned that a change like this will break your other selects. If that's the case, you may want to build this solution into a custom filter instead of just overriding 'select'.

ngTable select all filtered data

Okay, I got it to work. I just added a tableData object to the $scope so I can store the filtered data there. That's what I used for checking the selected items.

let sampleData = [{id: 1, name: 'John Doe', gender: 'Male'},
{id: 2, name: 'Jane Doe', gender: 'Female'},
{id: 3, name: 'Mary Jane', gender: 'Female'},
{id: 4, name: 'Mary Poppins', gender: 'Female'}];

$scope.tableData = {
filteredData: [],
checkboxes: {
checked: false,
items: {}
}
};

$scope.tableParams = new NgTableParams({
page: 1,
count: 10
}, {
total: data.length;
getData: ($defer, params) => {
let filter = params.filter();
let count = params.count();
let page = params.page();
let filteredData = filter ? $filter('filter')(data, filter) : data;

params.total(filteredData.length);
$scope.tableData.filteredData = filteredData;

$defer.resolve(filteredData.slice((page - 1) * count, page * count));
}
});

$scope.$watch(() => {
return $scope.tableData.checkboxes.checked;
}, (value) => {
$scope.tableData.filteredData.map((item) => {
$scope.tableData.checkboxes.items[item].id = value;
});
});

$scope.$watch(() => {
return $scope.tableData.checkboxes.items;
}, () => {
let checked = 0;
let unchecked = 0;
let data = $scope.tableData.filteredData;
let total = data.length;
let checkboxes = $scope.tableData.checkboxes;

data.map((item) => {
if (checkboxes.items[item].id) {
checked++;
} else {
unchecked++;
}
});

if (unchecked === 0 || checked === 0) {
checkboxes.checked = checked === total;
}

angular.element($element[0].getElementsByClassName('select-all')).prop('indeterminate', (checked != 0 && unchecked != 0));
});

Not really sure if this is the best way to go about it. Also, this doesn't change the select all checkbox's state to indeterminate when you filter > select all > clear filter.

Ng-table select filtering issue

As I can see from the expression in ngOptions attribute:

ng-options="data.id as data.title for data in $selectData"

The format of the option should be {id: ..., title: ...}. So I think you can change your angular.forEach block with something like this:

  var titles = data.map(function(obj) { return obj.title; });
$scope.names = titles.filter(function(title, i) { return titles.indexOf(title) === i; })
.map(function(title) { return {title: title, id: title}; });

This is not the fastest method to generate this array (added this just to illustrate the structure). More performant ways to do this could be found here.

Working fiddle.

How to use select filter with static values on async (server-side) ngTable

Your select is not populated because you're not waiting for the promise to resolve.

Here's a plunker that I stumbled upon when I faced this issue a few months ago:

plnkr.co/edit/XJo9rp?p=preview

Try something like that:

function getData() {
return $q.when([{role: 'admin'},...]);
}
var promise = getData();

Which is the short version for:

function getData() {
var def = $q.defer();
var docType = [{role: 'admin'},...];
def.resolve(docType);
return def;
}
var promise = getData();

and your scope function:

$scope.roles = function(column) {
var select = promise.then(function(results) {
return results;
})
return select;
};


Related Topics



Leave a reply



Submit