Skip to content

Commit

Permalink
Add onChange callback to search config object. (#469)
Browse files Browse the repository at this point in the history
* Add onChange callback to search config object.
* Let consumer allow in-memory searching to proceed normally.
  • Loading branch information
cjcenizal authored Mar 7, 2018
1 parent f6c88cd commit ef3738f
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 2 deletions.
137 changes: 137 additions & 0 deletions src-docs/src/views/tables/in_memory/in_memory_search_callback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React, { Fragment } from 'react';
import { formatDate } from '../../../../../src/services/format';
import { createDataStore } from '../data_store';
import {
EuiInMemoryTable,
EuiLink,
EuiHealth,
EuiSpacer,
EuiSwitch,
EuiFlexGroup,
EuiFlexItem
} from '../../../../../src/components';

/*
Example user object:
{
id: '1',
firstName: 'john',
lastName: 'doe',
github: 'johndoe',
dateOfBirth: Date.now(),
nationality: 'NL',
online: true
}
Example country object:
{
code: 'NL',
name: 'Netherlands',
flag: '🇳🇱'
}
*/

let debounceTimeoutId;
let requestTimeoutId;
const store = createDataStore();

export class Table extends React.Component {

constructor(props) {
super(props);

this.state = {
items: store.users,
isLoading: false,
};
}

onQueryChange = query => {
clearTimeout(debounceTimeoutId);
clearTimeout(requestTimeoutId);

debounceTimeoutId = setTimeout(() => {
this.setState({
isLoading: true,
});

requestTimeoutId = setTimeout(() => {
const items = store.users.filter(user => {
const normalizedName = `${user.firstName} ${user.lastName}`.toLowerCase();
const normalizedQuery = query.text.toLowerCase();
return normalizedName.indexOf(normalizedQuery) !== -1;
});

this.setState({
isLoading: false,
items,
})
}, 1000);
}, 300);
};

render() {
const search = {
onChange: this.onQueryChange,
box: {
incremental: true,
},
};

return (
<EuiInMemoryTable
items={this.state.items}
loading={this.state.isLoading}
columns={[
{
field: 'firstName',
name: 'First Name',
sortable: true
},
{
field: 'lastName',
name: 'Last Name'
},
{
field: 'github',
name: 'Github',
render: (username) => (
<EuiLink href={`https://github.com/${username}`} target="_blank">{username}</EuiLink>
)
},
{
field: 'dateOfBirth',
name: 'Date of Birth',
dataType: 'date',
render: (date) => formatDate(date, 'dobLong'),
sortable: true
},
{
field: 'nationality',
name: 'Nationality',
render: (countryCode) => {
const country = store.getCountry(countryCode);
return `${country.flag} ${country.name}`;
}
},
{
field: 'online',
name: 'Online',
dataType: 'boolean',
render: (online) => {
const color = online ? 'success' : 'danger';
const label = online ? 'Online' : 'Offline';
return <EuiHealth color={color}>{label}</EuiHealth>;
},
sortable: true
}
]}
search={search}
pagination={true}
sorting={true}
/>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import {
EuiCode
} from '../../../../../src/components';
import { GuideSectionTypes } from '../../../components';
import { renderToHtml } from '../../../services';

import { Table } from './in_memory_search_callback';
import { propsInfo } from './props_info';

const source = require('!!raw-loader!./in_memory_search_callback');
const html = renderToHtml(Table);

export const searchCallbackSection = {
title: 'In-Memory Table - With Search Callback',
source: [
{
type: GuideSectionTypes.JS,
code: source,
}, {
type: GuideSectionTypes.HTML,
code: html,
}
],
text: (
<div>
<p>
The example shows how to configure <EuiCode>EuiInMemoryTable</EuiCode> to display a search bar
and intercept the search value when it changes so you can perform your own search logic.
</p>
</div>
),
props: propsInfo,
demo: <Table/>
};
1 change: 1 addition & 0 deletions src-docs/src/views/tables/in_memory/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { section } from './in_memory_section';
export { selectionSection } from './in_memory_selection_section';
export { searchSection } from './in_memory_search_section';
export { searchCallbackSection } from './in_memory_search_callback_section';
5 changes: 5 additions & 0 deletions src-docs/src/views/tables/in_memory/props_info.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export const propsInfo = {
description: 'Configures the search filters of the search bar ',
required: false,
type: { name: '#SearchFilters' }
},
onChange: {
description: 'Callback for when the search bar value changes. By default this will prevent in-memory searching. Return `true` to allow in-memory searching.',
required: false,
type: { name: 'function' }
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src-docs/src/views/tables/tables_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { section as actionsSection } from './actions';
import {
section as inMemorySection,
selectionSection as inMemorySelectionSection,
searchSection as inMemorySearchSection
searchSection as inMemorySearchSection,
searchCallbackSection as inMemorySearchCallbackSection,
} from './in_memory';
import { section as customSection } from './custom';

Expand Down Expand Up @@ -53,6 +54,7 @@ export const TableExample = {
inMemorySection,
inMemorySelectionSection,
inMemorySearchSection,
inMemorySearchCallbackSection,
customSection,
],
};
13 changes: 12 additions & 1 deletion src/components/basic_table/in_memory_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const InMemoryTablePropTypes = {
defaultQuery: QueryType,
box: PropTypes.shape(SearchBoxConfigPropTypes),
filters: SearchFiltersFiltersType,
onChange: PropTypes.func,
})]),
pagination: PropTypes.oneOfType([
PropTypes.bool,
Expand Down Expand Up @@ -112,6 +113,12 @@ export class EuiInMemoryTable extends React.Component {
}

onQueryChange(query) {
if (this.props.search.onChange) {
const shouldQueryInMemory = this.props.search.onChange(query);

if (!shouldQueryInMemory) return;
}

this.setState(prevState => ({
query,
data: this.computeData(this.props.items, prevState.criteria, query)
Expand Down Expand Up @@ -162,7 +169,11 @@ export class EuiInMemoryTable extends React.Component {
resolveSearchBar() {
const { search } = this.props;
if (search) {
const searchBarProps = isBoolean(search) ? {} : search;
const {
onChange, // eslint-disable-line no-unused-vars
...searchBarProps
} = isBoolean(search) ? {} : search;

return (
<EuiSearchBar
onChange={this.onQueryChange.bind(this)}
Expand Down

0 comments on commit ef3738f

Please sign in to comment.