I am trying to customize the Material UI Autocomplete and show a count of options that are currently shown in a Popper menu after a user searches and enters a string in the search box (this is before you select an option and it becomes a value
which is easy to get a count of with value.length
). I may be missing the prop in order to grab the number of options showing out of the entire option array when a user enters a keystroke in the <Textfield/>
of the renderInput
prop in the <Autocomplete/>
.
Here is the code:
<Autocomplete
value={value}
onClose={handleClose}
onChange={(event, newValue) => {
setValue(newValue);
}}
options={options}
getOptionLabel={option => option.title}
renderInput={params => (
<React.Fragment>
<TextField
{...params}
variant="underlined"
placeholder="Search"
/>
<span className={classes.visibleFilterNum}>
Showing X of {options.length}
</span>
</React.Fragment>
)}
/>
Here is the component so far, need to get a constantly updated count for the showing X of total number of options
Here is a codepen of something similar pulled from Material UI example docs for a better example of the starting set of code
It is straightforward using the useAutocomplete
hook since it exposes the groupedOptions
variable (which is the filtered options ).
Here's an example:
export default function UseAutocomplete() {
const classes = useStyles();
const {
getRootProps,
getInputLabelProps,
getInputProps,
getListboxProps,
getOptionProps,
groupedOptions
} = useAutocomplete({
id: "use-autocomplete-demo",
options: top100Films,
getOptionLabel: (option) => option.title
});
return (
<div>
<div {...getRootProps()}>
<label className={classes.label} {...getInputLabelProps()}>
useAutocomplete
</label>
<input className={classes.input} {...getInputProps()} />
</div>
{groupedOptions.length > 0 ? (
<>
<div>
Showing {groupedOptions.length} of {top100Films.length}
</div>
<ul className={classes.listbox} {...getListboxProps()}>
{groupedOptions.map((option, index) => (
<li {...getOptionProps({ option, index })}>{option.title}</li>
))}
</ul>
</>
) : null}
</div>
);
}
groupedOptions
is not exposed in any straightforward way by the Autocomplete
component, but it is possible to determine the number of displayed options by inspecting the HTML to count the options after it renders. The example below does this by overriding the Paper component . The options are displayed within the Paper
element and all the options receive a data-option-index attribute . The example below uses these aspects to count the options using querySelectorAll
from the Paper
element:
import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import Paper from "@material-ui/core/Paper";
const NumResultsHeader = ({ children, ...other }) => {
const headerRef = React.useRef();
const countRef = React.useRef();
const paperRef = React.useRef();
React.useEffect(() => {
const numOptions = paperRef.current.querySelectorAll(
"li[data-option-index]"
).length;
countRef.current.innerHTML = numOptions;
if (numOptions > 0) {
headerRef.current.style.display = "block";
} else {
headerRef.current.style.display = "none";
}
});
return (
<>
<div ref={headerRef} style={{ display: "none" }}>
Showing <span ref={countRef}></span> of {top100Films.length}
</div>
<Paper {...other} ref={paperRef}>
{children}
</Paper>
</>
);
};
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
PaperComponent={NumResultsHeader}
renderInput={(params) => (
<TextField {...params} label="Combo box" variant="outlined" />
)}
/>
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.