jakezatecky / react-dual-listbox

A feature-rich dual listbox for React.
https://jakezatecky.github.io/react-dual-listbox/
MIT License
110 stars 58 forks source link

Ability to filter one listbox only #159

Closed sclavijo93 closed 1 year ago

sclavijo93 commented 2 years ago

Ability to filter one listbox only

No filter applied: imagen

Current behavior when filtering: imagen

What I am trying to accomplish: imagen

This is my final product requirement:

imagen

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:

No filter applied: imagen

Current behavior when filtering: imagen

This is my code snippet (Is a little bit rudimentary but is just for testing) ```jsx 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 ( <> My custom input: { if (filterValue === "") { return true; } return new RegExp(filterValue, "i").test(option.label); }} options={options} selected={selected} onChange={this.onChange} /> ); } } export default FilterExample; ```
jakezatecky commented 1 year ago

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.