I am trying to replicate a search field using old jQuery typeahead with react-bootstrap-typeahead. It queries uses multiple async data sources, and display the result grouped by the return of such sources.
For instance, as seen on the image, by typing the letter "b" it queries an address database as well as the previously searched values by user (saved on React store) and display results grouped by each database. If a result is empty for a given database, it is not shown, as the next example:
According to this closed issue on the project it is possible to query multiple databases making multiple queries on the onSearch
function. But is it possible to group the results like on the above example?
Yes, it's possible to group the search results in the way you describe. You can use the renderMenu
prop to group the results by data source and render a menu header to denote each source.
Here's an adaptation from the live examples:
const renderMenu = (results, menuProps, props) => {
let index = 0;
// Group the results by the "region" key in each option.
const regions = groupBy(results, 'region');
const items = Object.keys(regions)
.sort()
.map((region) => {
return (
<React.Fragment key={region}>
{index !== 0 && <Menu.Divider />}
<Menu.Header>{region}</Menu.Header>
{regions[region].map((option) => {
const item = (
<MenuItem key={option.label} option={option} position={index}>
<Highlighter search={props.text}>{option.label}</Highlighter>
</MenuItem>
);
index += 1;
return item;
})}
</React.Fragment>
);
});
return <Menu {...menuProps}>{items}</Menu>;
};
const GroupedResults = () => {
return (
<Typeahead
id="grouped-results"
options={options}
placeholder="Choose a state..."
renderMenu={renderMenu}
/>
);
};
Here's the working sandbox.
As far as the data source is concerned, note that the typeahead component is essentially agnostic about that; it is simply filtering the array passed into the options
prop, which can come from anywhere, or even multiple places.