ag-grid
Version:
Advanced Javascript Datagrid. Supports raw Javascript, AngularJS 1.x, AngularJS 2.0 and Web Components
267 lines (221 loc) • 9.69 kB
text/typescript
/// <reference path="../utils.ts" />
/// <reference path="../entities/colDef.ts" />
module ag.grid {
var _ = Utils;
export class SetFilterModel {
private colDef: ColDef;
private filterParams: SetFilterParameters;
private rowModel: any;
private valueGetter: any;
private allUniqueValues: any; // all values in the table
private availableUniqueValues: any; // all values not filtered by other rows
private displayedValues: any; // all values we are rendering on screen (ie after mini filter)
private miniFilter: any;
private selectedValuesCount: any;
private selectedValuesMap: any;
// so make code more readable, we work these out once, and
// then refer to each time. both are derived from the filterParams
private showingAvailableOnly: boolean;
private usingProvidedSet: boolean;
private doesRowPassOtherFilters: any;
constructor(colDef: ColDef, rowModel: any, valueGetter: any, doesRowPassOtherFilters: any) {
this.colDef = colDef;
this.rowModel = rowModel;
this.valueGetter = valueGetter;
this.doesRowPassOtherFilters = doesRowPassOtherFilters;
this.filterParams = <SetFilterParameters> this.colDef.filterParams;
this.usingProvidedSet = this.filterParams && this.filterParams.values;
this.showingAvailableOnly = this.filterParams && !this.filterParams.suppressRemoveEntries;
this.createAllUniqueValues();
this.createAvailableUniqueValues();
// by default, no filter, so we display everything
this.displayedValues = this.availableUniqueValues;
this.miniFilter = null;
// we use a map rather than an array for the selected values as the lookup
// for a map is much faster than the lookup for an array, especially when
// the length of the array is thousands of records long
this.selectedValuesMap = {};
this.selectEverything();
}
// if keepSelection not set will always select all filters
// if keepSelection set will keep current state of selected filters
// unless selectAll chosen in which case will select all
public refreshAfterNewRowsLoaded(keepSelection: any, isSelectAll: boolean) {
this.createAllUniqueValues();
this.createAvailableUniqueValues();
var oldModel = Object.keys(this.selectedValuesMap);
this.selectedValuesMap = {};
this.processMiniFilter();
if (keepSelection) {
this.setModel(oldModel, isSelectAll);
} else {
this.selectEverything();
}
}
public refreshAfterAnyFilterChanged() {
if (this.showingAvailableOnly) {
this.createAvailableUniqueValues();
this.processMiniFilter();
}
}
private createAllUniqueValues() {
if (this.usingProvidedSet) {
this.allUniqueValues = _.toStrings(this.filterParams.values);
} else {
this.allUniqueValues = _.toStrings(this.getUniqueValues(false));
}
if (this.colDef.comparator) {
this.allUniqueValues.sort(this.colDef.comparator);
} else {
this.allUniqueValues.sort(_.defaultComparator);
}
}
private createAvailableUniqueValues() {
var dontCheckAvailableValues = !this.showingAvailableOnly || this.usingProvidedSet;
if (dontCheckAvailableValues) {
this.availableUniqueValues = this.allUniqueValues;
return;
}
this.availableUniqueValues = _.toStrings(this.getUniqueValues(true));
if (this.colDef.comparator) {
this.availableUniqueValues.sort(this.colDef.comparator);
} else {
this.availableUniqueValues.sort(_.defaultComparator);
}
}
private getUniqueValues(filterOutNotAvailable: boolean): any[] {
var uniqueCheck = <any>{};
var result = <any>[];
this.rowModel.forEachNode( (node: any)=> {
if (!node.group) {
var value = this.valueGetter(node);
if (value === "" || value === undefined) {
value = null;
}
if (filterOutNotAvailable) {
if (!this.doesRowPassOtherFilters(node)) {
return;
}
}
if (value != null && Array.isArray(value)) {
for (var j = 0; j < value.length; j++) {
addUniqueValueIfMissing(value[j])
}
} else {
addUniqueValueIfMissing(value)
}
}
});
function addUniqueValueIfMissing(value: any) {
if (!uniqueCheck.hasOwnProperty(value)) {
result.push(value);
uniqueCheck[value] = 1;
}
}
return result;
}
//sets mini filter. returns true if it changed from last value, otherwise false
public setMiniFilter(newMiniFilter: any) {
newMiniFilter = _.makeNull(newMiniFilter);
if (this.miniFilter === newMiniFilter) {
//do nothing if filter has not changed
return false;
}
this.miniFilter = newMiniFilter;
this.processMiniFilter();
return true;
}
public getMiniFilter() {
return this.miniFilter;
}
private processMiniFilter() {
// if no filter, just use the unique values
if (this.miniFilter === null) {
this.displayedValues = this.availableUniqueValues;
return;
}
// if filter present, we filter down the list
this.displayedValues = [];
var miniFilterUpperCase = this.miniFilter.toUpperCase();
for (var i = 0, l = this.availableUniqueValues.length; i < l; i++) {
var filteredValue = this.availableUniqueValues[i];
if (filteredValue !== null && filteredValue.toString().toUpperCase().indexOf(miniFilterUpperCase) >= 0) {
this.displayedValues.push(filteredValue);
}
}
}
public getDisplayedValueCount() {
return this.displayedValues.length;
}
public getDisplayedValue(index: any) {
return this.displayedValues[index];
}
public selectEverything() {
var count = this.allUniqueValues.length;
for (var i = 0; i < count; i++) {
var value = this.allUniqueValues[i];
this.selectedValuesMap[value] = null;
}
this.selectedValuesCount = count;
}
public isFilterActive() {
return this.allUniqueValues.length !== this.selectedValuesCount;
}
public selectNothing() {
this.selectedValuesMap = {};
this.selectedValuesCount = 0;
}
public getUniqueValueCount() {
return this.allUniqueValues.length;
}
public getUniqueValue(index: any) {
return this.allUniqueValues[index];
}
public unselectValue(value: any) {
if (this.selectedValuesMap[value] !== undefined) {
delete this.selectedValuesMap[value];
this.selectedValuesCount--;
}
}
public selectValue(value: any) {
if (this.selectedValuesMap[value] === undefined) {
this.selectedValuesMap[value] = null;
this.selectedValuesCount++;
}
}
public isValueSelected(value: any) {
return this.selectedValuesMap[value] !== undefined;
}
public isEverythingSelected() {
return this.allUniqueValues.length === this.selectedValuesCount;
}
public isNothingSelected() {
return this.allUniqueValues.length === 0;
}
public getModel() {
if (!this.isFilterActive()) {
return null;
}
var selectedValues = <any>[];
_.iterateObject(this.selectedValuesMap, function (key: any) {
selectedValues.push(key);
});
return selectedValues;
}
public setModel(model: any, isSelectAll: boolean) {
if (model && !isSelectAll) {
this.selectNothing();
for (var i = 0; i < model.length; i++) {
var newValue = model[i];
if (this.allUniqueValues.indexOf(newValue) >= 0) {
this.selectValue(model[i]);
} else {
console.warn('Value ' + newValue + ' is not a valid value for filter');
}
}
} else {
this.selectEverything();
}
}
}
}