Ability to filter one listbox only
Closed this issue · 1 comments
Ability to filter one listbox only
Current behavior when filtering:
What I am trying to accomplish:
This is my final product requirement:
I've tried the following:
1 - Not passing the prop canFilter
but a filterCallback
function with no luck because the filterCallback
is not being called if canFilter
is not declared.
2 - Hiding the inputs via CSS while passing canFilter
and filterCallback
to the component. This can fullfill my design requirements but when I type into the custom input the filterCallback
is being fired and filtering both listbox when I only want to filter the first one.
Examples for the point number 2:
Current behavior when filtering:
This is my code snippet
(Is a little bit rudimentary but is just for testing)
import React from "react";
import DualListBox from "react-dual-listbox";
const options = [
{
label: "Earth",
options: [{ value: "luna", label: "Moon" }],
},
{
label: "Mars",
options: [
{ value: "phobos", label: "Phobos" },
{ value: "deimos", label: "Deimos" },
],
},
{
label: "Jupiter",
options: [
{ value: "io", label: "Io" },
{ value: "europa", label: "Europa" },
{ value: "ganymede", label: "Ganymede" },
{ value: "callisto", label: "Callisto" },
],
},
];
class FilterExample extends React.Component {
state = { filterValue: "", selected: ["luna", "io"] };
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onCustomInputChange = this.onCustomInputChange.bind(this);
}
onChange(selected) {
this.setState({ selected });
}
onCustomInputChange(e) {
this.setState({ filterValue: e.target.value });
}
render() {
const { filterValue, selected } = this.state;
return (
<>
<style>
{`input.rdl-filter{
display: none
}`}
</style>
My custom input:
<input
value={filterValue}
onChange={this.onCustomInputChange}
style={{
borderRadius: 50,
borderColor: "#999999",
marginLeft: 10,
}}
/>
<DualListBox
canFilter
filterCallback={(option) => {
if (filterValue === "") {
return true;
}
return new RegExp(filterValue, "i").test(option.label);
}}
options={options}
selected={selected}
onChange={this.onChange}
/>
</>
);
}
}
export default FilterExample;
This is easily done in userland through some CSS:
.rdl-selected .rdl-filter-container {
display: none;
}
/* Apply enough margin to the rightmost control so that it aligns with the left */
.rdl-selected .rdl-control {
margin-top: 46px;
}
This will not affect the results on the rightmost box when filtering with the left box.
I decided against including this as an enhancement. It makes some of the code more unwieldy just to hide one of the filters. It also would either result in yet another filter proper or require overloading the existing canFilter
to support an array.