1
votes

I have a ui-grid table which has been implemented with Server-side filtering, now i have a scenario that i am passing the filtering term in my api from another page and coming to the ui-grid page with the filtered data for the grid but the selection of the filter for that column is not applied.

Code:

$scope.gridOptions = {
                enableSelectAll: false,
                exporterCsvFilename: fileNm,
                exporterMenuPdf: false,
                enableFiltering: true,
                showGridFooter: true,
                paginationPageSizes: [25, 50, 75],
                paginationPageSize: 25,
                useExternalPagination: true,
                enableGridMenu: true,
..
..
.

Sample columnDef

var sparableColumn =  {
                        name: 'sparable', displayName: 'Sparable', headerCellClass: $scope.highlightFilteredHeader,

                        filter: {
                            type: uiGridConstants.filter.SELECT,
                            selectOptions: $scope.sparableFilter
                        },

                        cellTemplate:'<div ng-if="row.entity.sparable" class="tcenter">{{row.entity.sparable}}</div><div ng-if="!row.entity.sparable"></div>',
                        cellClass: function (grid, row, col) {
                            if (grid.getCellValue(row, col) === 'NO') {
                                return 'red tcenter';
                            } 
                            if(grid.getCellValue(row, col) === 'YES') {
                                return 'green tcenter';
                            } 
                            return 'tcenter';
                        }
             };

Server side filter inside onRegisterApi:

onRegisterApi: function (gridApi) {
                    $scope.gridApi = gridApi;

                    $scope.gridApi.core.on.filterChanged( $scope, function() {
                         var grid = this.grid;
                         $scope.serversideFilters = [];
                        angular.forEach(grid.columns, function(value, key) {
                            if(value.filters[0].term) {
                                var dummy = {};
                                console.log('FILTER TERM FOR ' + value.colDef.name + ' = ' + value.filters[0].term);
                                dummy['k'] = value.colDef.name;
                                dummy['v'] = value.filters[0].term;
                                $scope.serversideFilters.push(dummy);
                            }
                        });
                        getPage();
                    });

I know we need to populate or select it via grid.columns.filters but how and where to put the code to activate the filtered column selection is the question.

Thanks in advance!

1
ui-grid is using $$hashkey to keep track of the selected items. Once you do a server-side filtering, you will get new $$hashkey so selections will lose.Charlie Ng
Any other way to track it and apply it post getting the filtered dataGOK
Stash the filters using this: ui-grid.info/docs/#/tutorial/208_save_state. You should be able to build the state as well, once you are comfortable with the format. I wish I still had the code, but had built a function to allow users to save their filters, columns, etc to a backend service. Could do that or store it in the session, depending on where you want the "weight" to be.Brian

1 Answers

0
votes

I've put together a plnkr to outline what I think you are looking for. It is based off of the ui-grid tutorial on Saving State, but shrinks the amount of data you are storing down to the columns array (where each column object contains the filters). To test, add some filter content to the filter headers, and save state. 'X' the filters out, hit restore, and the filters are back.

Down below, I've outlined some ideas on "what to do" with this array.

JS

This code comes from the above mentioned tutorial, with slight modifications to avoid storing the extra data.

Note that $scope.gridOptions.saveFilter = true. The save* options have been set to false to avoid any extra data handling.

// ensure
var app = angular.module('app', ['ui.grid', 'ui.grid.saveState']);

// left out extra code for brevity

var columns = [];
  $scope.saveState = function() {
    var saved = $scope.gridApi.saveState.save();
    columns = saved.columns;
    console.log('columns', columns);
  };

  $scope.restoreState = function() {
    $scope.gridApi.saveState.restore($scope, {
      columns: columns
    });
  };

HTML

Directives are "listed" to ensure they stand out.

  <div class="grid" ui-grid="gridOptions" ui-grid-save-state>

  <button id="save" type="button" class="btn btn-success"
      ng-click="saveState()">Save</button>
  <button id="restore" type="button" class="btn btn-success"
      ng-click="restoreState()">Restore</button>

Stashing the Array

Depending on how you are handling navigation, you could watch for $routeChangeStart, and call saveState():

$scope.$on('$routeChangeStart', function(next, current) {
   // Serialize, post/put, etc here
});

When loading the the second page, you can retrieve the data doing something like this:

// app.config
$routeProvider.
      when('/page2', {
        templateUrl: 'page_2.tpl.htm',
        controller: 'Page2Controller',
        resolve: {
          gridFilters: function($http){
            // We must return something with a promise. $http already does that, so does $resource.
            // See: https://docs.angularjs.org/api/ng/service/$q
            return $http({
              method: 'GET',
              url: '/api/resource/with/grid/settings'
            })
          }
        }
      })

Local Storage

A second approach would be keeping the data locally using a service. The answer provided in passing-data-between-controllers-in-angular-js sums this pattern up perfectly, so it need not be replicated here.