Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

Commit

Permalink
Case-insensitive option for filters
Browse files Browse the repository at this point in the history
  • Loading branch information
dmt0 committed Oct 1, 2019
1 parent cd9c3e1 commit 7a12196
Show file tree
Hide file tree
Showing 14 changed files with 381 additions and 54 deletions.
1 change: 1 addition & 0 deletions src/core/syntax-tree/lexicon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface IUnboundedLexeme {
resolve?: (target: any, tree: ISyntaxTree) => any;
subType?: string;
type: string;
case?: string;
nesting?: number;
priority?: number;
regexp: RegExp;
Expand Down
17 changes: 10 additions & 7 deletions src/dash-table/components/FilterFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import memoizerCache from 'core/cache/memoizer';
import { memoizeOne } from 'core/memoizer';

import ColumnFilter from 'dash-table/components/Filter/Column';
import { ColumnId, IColumn, TableAction, IFilterFactoryProps, SetFilter } from 'dash-table/components/Table/props';
import { ColumnId, IColumn, TableAction, IFilterFactoryProps, SetFilter, Case } from 'dash-table/components/Table/props';
import derivedFilterStyles, { derivedFilterOpStyles } from 'dash-table/derived/filter/wrapperStyles';
import derivedHeaderOperations from 'dash-table/derived/header/operations';
import { derivedRelevantFilterStyles } from 'dash-table/derived/style';
Expand All @@ -32,19 +32,20 @@ export default class FilterFactory {

}

private onChange = (column: IColumn, map: Map<string, SingleColumnSyntaxTree>, setFilter: SetFilter, ev: any) => {
private onChange = (column: IColumn, map: Map<string, SingleColumnSyntaxTree>, setFilter: SetFilter, filter_case: Case, ev: any) => {
Logger.debug('Filter -- onChange', column.id, ev.target.value && ev.target.value.trim());

const value = ev.target.value.trim();

updateColumnFilter(map, column, value, setFilter);
updateColumnFilter(map, column, value, setFilter, filter_case);
}

private filter = memoizerCache<[ColumnId, number]>()((
column: IColumn,
index: number,
map: Map<string, SingleColumnSyntaxTree>,
setFilter: SetFilter
setFilter: SetFilter,
filter_case: Case
) => {
const ast = map.get(column.id.toString());

Expand All @@ -53,7 +54,7 @@ export default class FilterFactory {
classes={`dash-filter column-${index}`}
columnId={column.id}
isValid={!ast || ast.isValid}
setFilter={this.onChange.bind(this, column, map, setFilter)}
setFilter={this.onChange.bind(this, column, map, setFilter, filter_case)}
value={ast && ast.query}
/>);
});
Expand Down Expand Up @@ -83,7 +84,8 @@ export default class FilterFactory {
style_cell_conditional,
style_filter,
style_filter_conditional,
visibleColumns
visibleColumns,
filter_case
} = this.props;

if (filter_action === TableAction.None) {
Expand Down Expand Up @@ -113,7 +115,8 @@ export default class FilterFactory {
column,
index,
map,
setFilter
setFilter,
filter_case
);
}, visibleColumns);

Expand Down
6 changes: 4 additions & 2 deletions src/dash-table/components/HeaderFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export default class HeaderFactory {
style_cell_conditional,
style_header,
style_header_conditional,
visibleColumns
visibleColumns,
filter_case
} = props;

const labelsAndIndices = this.labelsAndIndices(columns, visibleColumns, merge_duplicate_headers);
Expand Down Expand Up @@ -109,7 +110,8 @@ export default class HeaderFactory {
page_action,
setFilter,
setProps,
merge_duplicate_headers
merge_duplicate_headers,
filter_case
);

const ops = this.getHeaderOpCells(
Expand Down
6 changes: 4 additions & 2 deletions src/dash-table/components/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export default class Table extends Component<SanitizedAndDerivedProps, Standalon
map: this.filterMap(
new Map<string, SingleColumnSyntaxTree>(),
props.filter_query,
props.visibleColumns
props.visibleColumns,
props.filter_case
)
},
rawFilterQuery: '',
Expand All @@ -60,7 +61,8 @@ export default class Table extends Component<SanitizedAndDerivedProps, Standalon
const map = this.filterMap(
currentMap,
nextProps.filter_query,
nextProps.visibleColumns
nextProps.visibleColumns,
nextProps.filter_case
);

return map !== currentMap ? { workFilter: { map, value} } : null;
Expand Down
11 changes: 11 additions & 0 deletions src/dash-table/components/Table/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export enum SortMode {
Multi = 'multi'
}

export enum Case {
Sensitive = 'sensitive',
Insensitive = 'insensitive',
Default = 'default'
}

export enum TableAction {
Custom = 'custom',
Native = 'native',
Expand Down Expand Up @@ -177,6 +183,8 @@ export interface IBaseColumn {
hideable?: boolean | boolean[] | 'first' | 'last';
renamable?: boolean | boolean[] | 'first' | 'last';
selectable?: boolean | boolean[] | 'first' | 'last';
filter_case_sensitive?: boolean;
filter_case_insensitive?: boolean;
sort_as_null: SortAsNull;
id: ColumnId;
name: string | string[];
Expand Down Expand Up @@ -298,6 +306,7 @@ export interface IProps {
fill_width?: boolean;
filter_query?: string;
filter_action?: TableAction;
filter_case?: Case;
hidden_columns?: string[];
include_headers_on_copy_paste?: boolean;
locale_format: INumberLocale;
Expand Down Expand Up @@ -351,6 +360,7 @@ interface IDefaultProps {
fill_width: boolean;
filter_query: string;
filter_action: TableAction;
filter_case: Case;
include_headers_on_copy_paste: boolean;
merge_duplicate_headers: boolean;
fixed_columns: Fixed;
Expand Down Expand Up @@ -441,6 +451,7 @@ export type SetFilter = (
export interface IFilterFactoryProps {
filter_query: string;
filter_action: TableAction;
filter_case: Case;
id: string;
map: Map<string, SingleColumnSyntaxTree>;
rawFilterQuery: string;
Expand Down
39 changes: 30 additions & 9 deletions src/dash-table/dash/DataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const defaultProps = {
css: [],
filter_query: '',
filter_action: 'none',
filter_case: 'sensitive',
sort_as_null: [],
sort_action: 'none',
sort_mode: 'single',
Expand Down Expand Up @@ -249,14 +250,25 @@ export const propTypes = {
* will select *all* of the merged columns associated with it.
* The table-level prop `column_selectable` is used to determine the type of column
* selection to use.
*
*/
selectable: PropTypes.oneOfType([
PropTypes.oneOf(['first', 'last']),
PropTypes.bool,
PropTypes.arrayOf(PropTypes.bool)
]),

/**
* If true, the filter on the column will override the table setting and always be
* case-sensitive, unless a case-insensitive operator is used.
*/
filter_case_sensitive: PropTypes.bool,

/**
* If true, the filter on the column will override the table setting and will always be
* case-insensitive, nless a case-sensitive operator is used.
*/
filter_case_insensitive: PropTypes.bool,

/**
* The formatting applied to the column's data.
* This prop is derived from the [d3-format](https://github.com/d3/d3-format) library specification. Apart from
Expand Down Expand Up @@ -944,13 +956,6 @@ export const propTypes = {
*/
tooltip_duration: PropTypes.number,

/**
* If `filter_action` is enabled, then the current filtering
* string is represented in this `filter_query`
* property.
*/
filter_query: PropTypes.string,

/**
* The `filter_action` property controls the behavior of the `filtering` UI.
* If `'none'`, then the filtering UI is not displayed.
Expand All @@ -964,6 +969,22 @@ export const propTypes = {
*/
filter_action: PropTypes.oneOf(['custom', 'native', 'none']),

/**
* If `filter_action` is enabled, then the current filtering
* string is represented in this `filter_query`
* property.
*/
filter_query: PropTypes.string,

/**
* If `filter_action` is enabled, the `filter_case` property controls the case-sensitivity of
* the filters.
* If `'sensitive'`, filtering on all columns will be case-sensitive (default behavior).
* If `'insensitive'`, filtering on all columns will be case-insensitive.
* This setting can be overridden per column.
*/
filter_case: PropTypes.oneOf(['sensitive', 'insensitive']),

/**
* The `sort_action` property enables data to be
* sorted on a per-column basis.
Expand Down Expand Up @@ -1131,7 +1152,7 @@ export const propTypes = {
* subType (string; optional):
* 'open-block': '()',
* 'logical-operator': '&&', '||',
* 'relational-operator': '=', '>=', '>', '<=', '<', '!=', 'contains',
* 'relational-operator': '=', '>=', '>', '<=', '<', '!=', 'contains', 'i=', 'i>=', 'i>', 'i<=', 'i<', 'i!=', 'icontains', 's=', 's>=', 's>', 's<=', 's<', 's!=', 'scontains',
* 'unary-operator': '!', 'is bool', 'is even', 'is nil', 'is num', 'is object', 'is odd', 'is prime', 'is str',
* 'expression': 'value', 'field';
* value (any):
Expand Down
21 changes: 12 additions & 9 deletions src/dash-table/derived/filter/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as R from 'ramda';

import { memoizeOneFactory } from 'core/memoizer';

import { Columns, IColumn, SetFilter } from 'dash-table/components/Table/props';
import { Columns, IColumn, SetFilter, Case } from 'dash-table/components/Table/props';
import { SingleColumnSyntaxTree, MultiColumnsSyntaxTree, getMultiColumnQueryString, getSingleColumnMap } from 'dash-table/syntax-tree';

const cloneIf = (
Expand All @@ -13,10 +13,11 @@ const cloneIf = (
export default memoizeOneFactory((
map: Map<string, SingleColumnSyntaxTree>,
query: string,
columns: Columns
columns: Columns,
filter_case: Case
): Map<string, SingleColumnSyntaxTree> => {
const multiQuery = new MultiColumnsSyntaxTree(query);
const reversedMap = getSingleColumnMap(multiQuery, columns);
const reversedMap = getSingleColumnMap(multiQuery, columns, filter_case);

/*
* Couldn't process the query, just use the previous value.
Expand Down Expand Up @@ -61,12 +62,12 @@ export default memoizeOneFactory((
return newMap;
});

function updateMap(map: Map<string, SingleColumnSyntaxTree>, column: IColumn, value: any) {
function updateMap(map: Map<string, SingleColumnSyntaxTree>, column: IColumn, value: any, filter_case: Case) {
const id = column.id.toString();
const newMap = new Map<string, SingleColumnSyntaxTree>(map);

if (value && value.length) {
newMap.set(id, new SingleColumnSyntaxTree(value, column));
newMap.set(id, new SingleColumnSyntaxTree(value, column, filter_case));
} else {
newMap.delete(id);
}
Expand All @@ -90,19 +91,21 @@ export const updateColumnFilter = (
map: Map<string, SingleColumnSyntaxTree>,
column: IColumn,
value: any,
setFilter: SetFilter
setFilter: SetFilter,
filter_case: Case
) => {
map = updateMap(map, column, value);
map = updateMap(map, column, value, filter_case);
updateState(map, setFilter);
};

export const clearColumnsFilter = (
map: Map<string, SingleColumnSyntaxTree>,
columns: Columns,
setFilter: SetFilter
setFilter: SetFilter,
filter_case: Case
) => {
R.forEach(column => {
map = updateMap(map, column, '');
map = updateMap(map, column, '', filter_case);
}, columns);

updateState(map, setFilter);
Expand Down
15 changes: 9 additions & 6 deletions src/dash-table/derived/header/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
SetFilter,
SetProps,
SortMode,
TableAction
TableAction,
Case
} from 'dash-table/components/Table/props';
import getColumnFlag from 'dash-table/derived/header/columnFlag';
import * as actions from 'dash-table/utils/actions';
Expand All @@ -40,7 +41,8 @@ const doAction = (
setFilter: SetFilter,
setProps: SetProps,
map: Map<string, SingleColumnSyntaxTree>,
data: Data
data: Data,
filter_case: Case
) => () => {
const props = action(column, columns, visibleColumns, columnRowIndex, mergeDuplicateHeaders, data);

Expand All @@ -64,7 +66,7 @@ const doAction = (
}
}, affectedColumIds);

clearColumnsFilter(map, affectedColumns, setFilter);
clearColumnsFilter(map, affectedColumns, setFilter, filter_case);
};

function doSort(columnId: ColumnId, sortBy: SortBy, mode: SortMode, setProps: SetProps) {
Expand Down Expand Up @@ -165,7 +167,8 @@ function getter(
paginationMode: TableAction,
setFilter: SetFilter,
setProps: SetProps,
mergeDuplicateHeaders: boolean
mergeDuplicateHeaders: boolean,
filter_case: Case
): JSX.Element[][] {
return R.addIndex<R.KeyValuePair<any[], number[]>, JSX.Element[]>(R.map)(
([labels, indices], headerRowIndex) => {
Expand Down Expand Up @@ -263,7 +266,7 @@ function getter(
null :
(<span
className='column-header--clear'
onClick={doAction(actions.clearColumn, selected_columns, column, columns, visibleColumns, headerRowIndex, mergeDuplicateHeaders, setFilter, setProps, map, data)}
onClick={doAction(actions.clearColumn, selected_columns, column, columns, visibleColumns, headerRowIndex, mergeDuplicateHeaders, setFilter, setProps, map, data, filter_case)}
>
<FontAwesomeIcon icon='eraser' />
</span>)
Expand All @@ -275,7 +278,7 @@ function getter(
className={'column-header--delete' + (spansAllColumns ? ' disabled' : '')}
onClick={spansAllColumns ?
undefined :
doAction(actions.deleteColumn, selected_columns, column, columns, visibleColumns, headerRowIndex, mergeDuplicateHeaders, setFilter, setProps, map, data)
doAction(actions.deleteColumn, selected_columns, column, columns, visibleColumns, headerRowIndex, mergeDuplicateHeaders, setFilter, setProps, map, data, filter_case)
}
>
<FontAwesomeIcon icon={['far', 'trash-alt']} />
Expand Down
Loading

0 comments on commit 7a12196

Please sign in to comment.