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

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'.


You can achieve that with a custom filter:

The code for the standard select filter on ngtable says:

<select ng-options="data.id as data.title for data in column.data"    ng-model="params.filter()[name]"    ng-show="filter == 'select'"    class="filter filter-select form-control" name="{{column.filterName}}"></select>

When you call this data you pass: filter-data="names($column)" and ngtable takes care of getting the data for you. I don't know why this does not work with an external resource. I bet it has something to do with the $column and the promise, as you pointed out.

I did a quick workaround in my code to avoid that. Writing my own select filter template like:

<select id="filterTest" class="form-control"     ng-model="tableParams.filter()['test']"     ng-options="e.id as e.title for e in externaldata"></select>

You fetch this externaldata in your controller:

$scope.externaldata = Api.query(); // Your custom api call

It works perfectly, but I do have an id on my data, so no need of the name function.

I understand this solution is not optimal. Let's see if somebody writes here more than this 'workaround' and enlightens us. Even esvit is here sometimes ;)


This works for me:

HTML:

<td data-title="'Doc type'" filter="{ 'doc_types': 'select' }" filter-data="docTypes()" sortable="'doc_types'">    {{task.doc_type}}</td>

AngularJS:

$scope.docTypes = function ($scope) {    var def = $q.defer();    //var docType = [    //    {'id':'4', 'title':'Whatever 1'},    //    {'id':'9', 'title':'Whatever 2'},    //    {'id':'11', 'title':'Whatever 3'}    //];    // Or get data from API.    // Format should be same as above.    var docType = $http.get('http://whatever.dev', {        params: { param1: data1 }    });    //Or with Restangular     var docType = Restangular.all('/api/doctype').getList();    def.resolve(docType);    return def;};