Search code examples
javascriptangularjsangular-ui-gridng-grid

Ng-grid filter with 2 condition


I have requirement to filter table based on

  1. single column and
  2. across column comparison.

I am using ng-grid to populate table. It gives feature to filter based on single column.

For across column comparison I am using grid.refresh() function. this function calls grid.registerRowsProcessor( $scope.columnComparionFilter, 200 )function. I have prepared columnComparionFilter function that returns renderableRows based on filter. Below is sample code:

// function to filter two column based on condition
$scope.columnComparionFilter= function(renderableRows){
    // if filter option selection changed
    if($scope.change){
        if($scope.column1 == undefined)
            return renderableRows;
        if($scope.column2 == undefined)
            return renderableRows;
        if($scope.column1 == $scope.column2){
            console.log('columns for comparision should be different.')
            return renderableRows;
        }
        if($scope.selectedFilter.name == 'compare'){
            renderableRows.forEach( function( row ) {
                if(row.entity[$scope.column1.field] == row.entity[$scope.column2.field])
                    row.visible = true;
                else
                    row.visible = false;
            });
        }else if($scope.selectedFilter.name == 'distinct'){
            renderableRows.forEach( function( row ) {
                if(row.entity[$scope.column1.field] != row.entity[$scope.column2.field])
                    row.visible = true;
                else
                    row.visible = false;
            });
        }
    }
    return renderableRows;
};

Both filter works fine alone. But when I tries working both together. It filters based on by default single filter only. It eliminates across column filter.

Can any one help me to solve this?


Solution

  • Actually grid.registerRowsProcessor() is core function used by single column filter of ng-grid. So when I tried to use same function for across filtering, It lead synchronization problem and single column filter over ruled my customised function.

    I have used an alternative for modifying ng-grid data. I have solved it using notifyDataChange() function. inside external filter function columnComparionFilter I am preparing subset of data based on filter and then I am changing gridOptions.data to subset data. See below code:

    // function to filter two column based on condition
    $scope.columnComparionFilter= function(renderableRows){
        // if filter option selection changed
        if($scope.change){
            if($scope.column1 == undefined){
                console.log('Please select first column to compare.')
                return;
            }
            if($scope.column2 == undefined){
                console.log('Please select second column to compare.')
                return;
            }
            if($scope.column1 == $scope.column2){
                console.log('columns for comparision should be different.')
                return;
            }
            if($scope.selectedFilter.name == 'compare'){
                renderableRows.forEach( function( row ) {                
                    if(row[$scope.column1.field] == row[$scope.column2.field])
                        filterData.push(row)
                });
            }else if($scope.selectedFilter.name == 'distinct'){
                renderableRows.forEach( function( row ) {
                    if(row[$scope.column1.field] != row[$scope.column2.field])
                        filterData.push(row)
                });
            }
            $scope.gridOptions.data = angular.copy(filterData);
            $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL);
            return;
        }
    };