Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Substring Search in SearchInput #1089

Merged
merged 10 commits into from
Jul 1, 2020
34 changes: 23 additions & 11 deletions src/SearchInput/SearchInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ class SearchInput extends PureComponent {
}

filterList = (list, query) => {
return list.filter((item) => item.text.toLowerCase().startsWith(query.toLowerCase()));
return this.props.subStringSearch ? list.filter((item) => {
return item.text.toLowerCase().includes(query.toLowerCase());
}) : list.filter((item) => item.text.toLowerCase().startsWith(query.toLowerCase()));
}

handleKeyPress = event => {
Expand Down Expand Up @@ -104,6 +106,7 @@ class SearchInput extends PureComponent {
inShellbar,
onEnter,
searchList,
subStringSearch,
onChange,
onSelect,
noSearchBtn,
Expand Down Expand Up @@ -135,14 +138,21 @@ class SearchInput extends PureComponent {
{filteredResult && filteredResult.length > 0 ? (
filteredResult.map((item, index) => {
return (
<Menu.Item
subStringSearch ? (<Menu.Item
key={index}
onClick={(e) => this.handleListItemClick(e, item)}>
<strong>{this.state.value}</strong>
{this.state.value && this.state.value.length
? item.text.substring(this.state.value.length)
: item.text}
</Menu.Item>
{item.text}
</Menu.Item>) :
(
<Menu.Item
key={index}
onClick={(e) => this.handleListItemClick(e, item)}>
<strong>{this.state.value}</strong>
{this.state.value && this.state.value.length
? item.text.substring(this.state.value.length)
: item.text}
</Menu.Item>
)
);
})
) : (
Expand All @@ -159,10 +169,10 @@ class SearchInput extends PureComponent {
body={
(<>
{validationState &&
<FormMessage
type={validationState.state}>
{validationState.text}
</FormMessage>
<FormMessage
type={validationState.state}>
{validationState.text}
</FormMessage>
}
{popoverBody}
</>)}
Expand Down Expand Up @@ -231,6 +241,8 @@ SearchInput.propTypes = {
callback: PropTypes.func
})
),
/** enable substring search */
subStringSearch: PropTypes.bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about keeping the capitalization consistent with JavaScript's substring method?
subStringSearch -> substringSearch

/** An object identifying a validation message. The object will include properties for `state` and `text`; _e.g._, \`{ state: \'warning\', text: \'This is your last warning\' }\` */
validationState: PropTypes.shape({
/** State of validation: 'error', 'warning', 'information', 'success' */
Expand Down
32 changes: 32 additions & 0 deletions src/SearchInput/SearchInput.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ describe('<SearchInput />', () => {
{ text: 'pear', callback: jest.fn() }
];

const substringSearchData = [
{ text: 'who is a supplier user?', callback: jest.fn() },
{ text: 'who is a buyer user?', callback: jest.fn() },
{ text: 'who is a worker user?', callback: jest.fn() },
{ text: 'how to change the pin?', callback: jest.fn() },
{ text: 'how to set the pin?', callback: jest.fn() }
];

const defaultSearchInput = (
<SearchInput
className='blue'
Expand All @@ -48,6 +56,15 @@ describe('<SearchInput />', () => {
placeholder='Enter a fruit' />
);

const searchOnChangeForSubstringSearch = (
<SearchInput
onChange={term => getInputValue(term)}
onEnter={term => getInputValue(term)}
placeholder='Enter a value'
searchList={substringSearchData}
subStringSearch />
);

describe('onChange handler', () => {
test('calling parent onChange event', () => {
const wrapper = mount(searchOnChange);
Expand All @@ -70,6 +87,21 @@ describe('<SearchInput />', () => {

expect(f).toHaveBeenCalledTimes(1);
});

test('subString Search', () => {
const wrapper = mount(searchOnChangeForSubstringSearch);

expect(wrapper.find(SearchInput).prop('subStringSearch')).toBe(true);

wrapper
.find(searchInput)
.simulate('change', { target: { value: 'supp' } });

let rows = wrapper.find('li');

expect(rows).toHaveLength(1);

});
});

test('check for enter key press on search input', () => {
Expand Down