Skip to content

Commit

Permalink
Fixed #1245 - Implement filterBy and filterMatchMode for ListBox
Browse files Browse the repository at this point in the history
  • Loading branch information
cagataycivici committed Mar 10, 2020
1 parent 9cafbc8 commit f8f03fa
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/components/listbox/ListBox.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ interface ListBoxProps {
multiple?: boolean;
metaKeySelection?: boolean;
filter?: boolean;
filterBy?: string;
filterMatchMode?: string;
filterPlaceholder?: string;
tabIndex?:string;
tooltip?: any;
Expand Down
39 changes: 22 additions & 17 deletions src/components/listbox/ListBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import ObjectUtils from '../utils/ObjectUtils';
import FilterUtils from '../utils/ObjectUtils';
import {ListBoxItem} from './ListBoxItem';
import {ListBoxHeader} from './ListBoxHeader';
import Tooltip from "../tooltip/Tooltip";
Expand All @@ -23,6 +24,8 @@ export class ListBox extends Component {
multiple: false,
metaKeySelection: false,
filter: false,
filterBy: null,
filterMatchMode: 'contains',
filterPlaceholder: null,
tabIndex: '0',
tooltip: null,
Expand All @@ -45,6 +48,8 @@ export class ListBox extends Component {
multiple: PropTypes.bool,
metaKeySelection: PropTypes.bool,
filter: PropTypes.bool,
filterBy: PropTypes.string,
filterMatchMode: PropTypes.string,
filterPlaceholder: PropTypes.string,
tabIndex: PropTypes.string,
tooltip: PropTypes.string,
Expand Down Expand Up @@ -107,7 +112,7 @@ export class ListBox extends Component {
}

onOptionTouchEnd() {
if(this.props.disabled) {
if (this.props.disabled) {
return;
}

Expand All @@ -120,11 +125,11 @@ export class ListBox extends Component {
let value = null;
let metaSelection = this.optionTouched ? false : this.props.metaKeySelection;

if(metaSelection) {
if (metaSelection) {
let metaKey = (event.metaKey || event.ctrlKey);

if(selected) {
if(metaKey) {
if (selected) {
if (metaKey) {
value = null;
valueChanged = true;
}
Expand All @@ -139,7 +144,7 @@ export class ListBox extends Component {
valueChanged = true;
}

if(valueChanged) {
if (valueChanged) {
this.updateModel(event, value);
}
}
Expand All @@ -150,11 +155,11 @@ export class ListBox extends Component {
let value = null;
let metaSelection = this.optionTouched ? false : this.props.metaKeySelection;

if(metaSelection) {
if (metaSelection) {
let metaKey = (event.metaKey || event.ctrlKey);

if(selected) {
if(metaKey)
if (selected) {
if (metaKey)
value = this.removeOption(option);
else
value = [this.getOptionValue(option)];
Expand All @@ -168,15 +173,15 @@ export class ListBox extends Component {
}
}
else {
if(selected)
if (selected)
value = this.removeOption(option);
else
value = [...this.props.value || [], this.getOptionValue(option)];

valueChanged = true;
}

if(valueChanged) {
if (valueChanged) {
this.props.onChange({
originalEvent: event,
value: value,
Expand All @@ -196,7 +201,7 @@ export class ListBox extends Component {
}

updateModel(event, value) {
if(this.props.onChange) {
if (this.props.onChange) {
this.props.onChange({
originalEvent: event,
value: value,
Expand Down Expand Up @@ -262,11 +267,11 @@ export class ListBox extends Component {
let items = this.props.options;
let header;

if(this.props.options) {
if(this.hasFilter()) {
items = items.filter((option) => {
return this.filter(option);
});
if (this.props.options) {
if (this.hasFilter()) {
let filterValue = this.state.filter.trim().toLowerCase();
let searchFields = this.props.filterBy ? this.props.filterBy.split(',') : [this.props.optionLabel || 'label'];
items = FilterUtils.filter(items, searchFields, filterValue, this.props.filterMatchMode);
}

items = items.map((option, index) => {
Expand All @@ -279,7 +284,7 @@ export class ListBox extends Component {
});
}

if(this.props.filter) {
if (this.props.filter) {
header = <ListBoxHeader filter={this.state.filter} onFilter={this.onFilter} disabled={this.props.disabled} filterPlaceholder={this.props.filterPlaceholder} />
}

Expand Down
19 changes: 16 additions & 3 deletions src/showcase/listbox/ListBoxDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,10 @@ carTemplate(option) {
`}
</CodeHighlight>

<h3>Filter</h3>
<p>Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable <i>filter</i> property.</p>
<h3>Filtering</h3>
<p>Options can be filtered using an input field in the overlay by enabling the <i>filter</i> property. By default filtering is done against
label of the items and <i>filterBy</i> property is available to choose one or more properties of the options. In addition <i>filterMatchMode</i> can be utilized
to define the filtering algorithm, valid options are "contains" (default), "startsWith", "endsWith", "equals" and "notEquals".</p>

<CodeHighlight className="language-jsx">
{`
Expand Down Expand Up @@ -341,6 +342,18 @@ carTemplate(option) {
<td>false</td>
<td>When specified, displays a filter input at header.</td>
</tr>
<tr>
<td>filterBy</td>
<td>string</td>
<td>label</td>
<td>When filtering is enabled, filterBy decides which field or fields (comma separated) to search against.</td>
</tr>
<tr>
<td>filterMatchMode</td>
<td>string</td>
<td>contains</td>
<td>Defines how the items are filtered, valid values are "contains" (default), "startsWith", "endsWith", "equals" and "notEquals".</td>
</tr>
<tr>
<td>filterPlaceholder</td>
<td>string</td>
Expand Down

0 comments on commit f8f03fa

Please sign in to comment.