Skip to content

Instantly share code, notes, and snippets.

@shawnco
Created January 24, 2023 22:31
Show Gist options
  • Save shawnco/1b5e61aa3be1de8070689d39c2d0ea38 to your computer and use it in GitHub Desktop.
Save shawnco/1b5e61aa3be1de8070689d39c2d0ea38 to your computer and use it in GitHub Desktop.
Simple Expanding Checkbox Dropdown Tutorial
import React, {useState, useEffect} from 'react';
const Checkbox = props => <input type='checkbox' {...props} />
const List = props => <ul style={{listStyle: 'none', margin: 0, padding: 5}}>{props.children}</ul>
const CheckboxExpand = ({currentData, allData, getValue, getLabel, onChange}) => {
const [current, setCurrent] = useState(currentData);
const [matches, setMatches] = useState([]);
const [showAll, setShowAll] = useState(false);
const inCurrent = val => current.includes(val);
const toggle = e => setShowAll(showAll ? false : true);
useEffect(() => {
const match = [];
current.sort((a, b) => a > b ? 1 : -1).map(c => {
const find = allData.find(a => getValue(a) == c);
if (find) {
match.push(find);
}
});
setMatches(match);
onChange(current);
}, [current]);
const handleChange = e => {
const val = +e.target.value;
const findIndex = current.findIndex(c => c == val);
if (findIndex > -1) {
current.splice(findIndex, 1);
setCurrent([...current]);
} else {
setCurrent([...current, val]);
}
}
return <table border='1'>
<tbody>
<tr>
<td>
<List>
{matches.map(m => <li key={getValue(m)}>
<Checkbox value={getValue(m)} checked={true} onChange={handleChange} />
{getLabel(m)}
</li>)}
<button onClick={toggle}>{showAll ? 'Hide' : 'Show'} All</button>
</List>
</td>
</tr>
{showAll && <tr>
<td>
<List>
{allData.map(a => <li key={getValue(a)}>
<Checkbox value={getValue(a)} checked={inCurrent(getValue(a))} onChange={handleChange} />
{getLabel(a)}
</li>)}
</List>
</td>
</tr>}
</tbody>
</table>
}
export default CheckboxExpand;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment