Skip to content

Commit

Permalink
Merge pull request #176 from grid-js/custom-global-search
Browse files Browse the repository at this point in the history
feat(serach): adding selector function
  • Loading branch information
afshinm authored Jul 24, 2020
2 parents da98b9d + ab53861 commit a682617
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 7 deletions.
19 changes: 13 additions & 6 deletions src/operator/search.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import Tabular from '../tabular';
import { VNode } from 'preact';
import { HTMLContentProps } from '../view/htmlElement';
import { TCell } from '../types';

export default function (keyword: string, tabular: Tabular): Tabular {
export default function (
keyword: string,
tabular: Tabular,
selector?: (cell: TCell, rowIndex: number, cellIndex: number) => string,
): Tabular {
// escape special regex chars
keyword = keyword.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');

return new Tabular(
tabular.rows.filter((row) =>
row.cells.some((cell) => {
if (!cell || !cell.data) {
tabular.rows.filter((row, rowIndex) =>
row.cells.some((cell, cellIndex) => {
if (!cell) {
return false;
}

let data = '';

if (typeof cell.data === 'object') {
if (typeof selector === 'function') {
data = selector(cell.data, rowIndex, cellIndex);
} else if (typeof cell.data === 'object') {
// HTMLContent element
const element = cell.data as VNode<HTMLContentProps>;
if (element.props && element.props.content) {
if (element && element.props && element.props.content) {
// TODO: we should only search in the content of the element. props.content is the entire HTML element
data = element.props.content;
}
Expand Down
8 changes: 7 additions & 1 deletion src/pipeline/filter/globalSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import {
PipelineProcessorProps,
ProcessorType,
} from '../processor';
import { TCell } from '../../types';

interface GlobalSearchFilterProps extends PipelineProcessorProps {
keyword: string;
selector?: (cell: TCell, rowIndex: number, cellIndex: number) => string;
}

class GlobalSearchFilter extends PipelineProcessor<
Expand All @@ -20,7 +22,11 @@ class GlobalSearchFilter extends PipelineProcessor<

_process(data: Tabular): Tabular {
if (this.props.keyword) {
return search(String(this.props.keyword).trim(), data);
return search(
String(this.props.keyword).trim(),
data,
this.props.selector,
);
}

return data;
Expand Down
3 changes: 3 additions & 0 deletions src/view/plugin/search/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { SearchStore, SearchStoreState } from './store';
import { SearchActions } from './actions';
import ServerGlobalSearchFilter from '../../../pipeline/filter/serverGlobalSearch';
import { debounce } from '../../../util/debounce';
import { TCell } from '../../../types';

export interface SearchConfig {
keyword?: string;
enabled?: boolean;
debounceTimeout?: number;
selector?: (cell: TCell, rowIndex: number, cellIndex: number) => string;
server?: {
url?: (prevUrl: string, keyword: string) => string;
body?: (prevBody: BodyInit, keyword: string) => BodyInit;
Expand Down Expand Up @@ -53,6 +55,7 @@ export class Search extends BaseComponent<SearchConfig & BaseProps, {}> {
} else {
searchProcessor = new GlobalSearchFilter({
keyword: props.keyword,
selector: props.selector,
});
}

Expand Down
16 changes: 16 additions & 0 deletions tests/operator/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,20 @@ describe('search', () => {
new Tabular([row3]).rows,
);
});

it('should use the selector with hardcoded string', () => {
expect(search('test', tabular, () => 'custom keyword').rows).toStrictEqual(
new Tabular([]).rows,
);
});

it('should use the selector with dynamic string', () => {
expect(
search(
'00',
tabular,
(_, rowIndex, cellIndex) => `${rowIndex}${cellIndex}`,
).rows,
).toStrictEqual(new Tabular([row1]).rows);
});
});

0 comments on commit a682617

Please sign in to comment.