Skip to content

Commit

Permalink
feat(filters): option to ignore accent while filtering text, closes #470
Browse files Browse the repository at this point in the history


- closes #470
- add a Grid Option to filter text by ignoring any accent by normalizing the text, the option is set to false by default
  • Loading branch information
ghiscoding committed Sep 7, 2021
1 parent a7104f3 commit cba9a4e
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { OperatorString, OperatorType, SearchTerm } from '../enums/index';
import { FilterCondition, FilterConditionOption } from '../interfaces/index';
import { removeAccentFromText } from '../services/utilities';
import { testFilterCondition } from './filterUtilities';

/** Execute filter condition check on each cell */
Expand All @@ -14,12 +15,12 @@ export const executeStringFilterCondition: FilterCondition = ((options: FilterCo
options.cellValue = (options.cellValue === undefined || options.cellValue === null) ? '' : options.cellValue.toString();

// make both the cell value and search value lower for case insensitive comparison
const cellValue = options.cellValue.toLowerCase();
const cellValue = options?.ignoreAccentOnStringFilter ? removeAccentFromText(options.cellValue, true) : options.cellValue.toLowerCase();
if (typeof searchValue1 === 'string') {
searchValue1 = searchValue1.toLowerCase();
searchValue1 = options?.ignoreAccentOnStringFilter ? removeAccentFromText(searchValue1, true) : searchValue1.toLowerCase();
}
if (typeof searchValue2 === 'string') {
searchValue2 = searchValue2.toLowerCase();
searchValue2 = options?.ignoreAccentOnStringFilter ? removeAccentFromText(searchValue2, true) : searchValue2.toLowerCase();
}

if (searchValue1 !== undefined && searchValue2 !== undefined) {
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/global-grid-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export const GlobalGridOptions: GridOption = {
hideFreezeColumnsCommand: true, // opt-in command
hideSortCommands: false
},
ignoreAccentOnStringFilter: false,
multiColumnSort: true,
numberedMultiColumnSort: true,
tristateMultiColumnSort: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export interface FilterConditionOption {
/** filter search field type */
filterSearchType?: typeof FieldType[keyof typeof FieldType];

/** should we ignore any accent while filtering text? */
ignoreAccentOnStringFilter?: any;

/**
* Parsed Search Terms is similar to SearchTerms but is already parsed in the correct format,
* for example on a date field the searchTerms might be in string format but their respective parsedSearchTerms will be of type Date
Expand Down
6 changes: 6 additions & 0 deletions packages/common/src/interfaces/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ export interface GridOption {
/** Header menu options */
headerMenu?: HeaderMenu;

/**
* Defaults to false, should we ignore any accent while filtering text?
* For example if our text is "José" and we type "Jose" then it won't return unless we use this flag because "é" is not equal to "e"
*/
ignoreAccentOnStringFilter?: boolean;

/**
* When using custom Locales (that is when user is NOT using a Translate Service, this property does nothing when used with Translate Service),
* This is useful so that every component of the lib knows the locale.
Expand Down
23 changes: 23 additions & 0 deletions packages/common/src/services/__tests__/utilities.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
mapOperatorType,
parseBoolean,
parseUtcDate,
removeAccentFromText,
sanitizeHtmlToText,
sanitizeTextByAvailableSanitizer,
setDeepValue,
Expand Down Expand Up @@ -1242,6 +1243,28 @@ describe('Service/Utilies', () => {
});
});

describe('removeAccentFromText method', () => {
it('should return a normalized string without accent', () => {
const input1 = 'José';
const input2 = 'Chêvre';
const input3 = 'áàãāăǎäéèêëěíìîïǐĩóòôöǒõ';

expect(removeAccentFromText(input1)).toBe('Jose');
expect(removeAccentFromText(input2)).toBe('Chevre');
expect(removeAccentFromText(input3)).toBe('aaaaaaaeeeeeiiiiiioooooo');
});

it('should return a normalized string without accent and lowercase when specified', () => {
const input1 = 'José';
const input2 = 'Chêvre';
const input3 = 'ÁÀÃĀĂǍÄÉÈÊËĚÍÌÎÏǏĨÓÒÔÖǑÕ';

expect(removeAccentFromText(input1, true)).toBe('jose');
expect(removeAccentFromText(input2, true)).toBe('chevre');
expect(removeAccentFromText(input3, true)).toBe('aaaaaaaeeeeeiiiiiioooooo');
});
});

describe('sanitizeHtmlToText method', () => {
it('should return original value when input does not include any HTML tags', () => {
const input = 'foo bar';
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/services/filter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ export class FilterService {
operator: operator as OperatorString,
searchInputLastChar: columnFilter.searchInputLastChar,
filterSearchType: columnDef.filterSearchType,
ignoreAccentOnStringFilter: this._gridOptions.ignoreAccentOnStringFilter ?? false,
defaultFilterRangeOperator: this._gridOptions.defaultFilterRangeOperator,
} as FilterConditionOption;
}
Expand Down
11 changes: 11 additions & 0 deletions packages/common/src/services/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,17 @@ export function parseUtcDate(inputDateString: any, useUtc?: boolean): string {
return date;
}

/**
* Remove any accents from a string by normalizing it
* @param {String} text - input text
* @param {Boolean} shouldLowerCase - should we also lowercase the string output?
* @returns
*/
export function removeAccentFromText(text: string, shouldLowerCase = false) {
const normalizedText = text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
return shouldLowerCase ? normalizedText.toLowerCase() : normalizedText;
}

/**
* Sanitize, return only the text without HTML tags
* @input htmlString
Expand Down

0 comments on commit cba9a4e

Please sign in to comment.