Material UI Autocomplete - reactjs

I am building a form using Material UI's autocomplete feature. The field renders chips however I am unable to modify the onDelete prop of the chip component. I have tried modifying other props such as the variant, label, etc but even trying to get the onDelete prop to do a simple console log does not work. My code is below.
<Autocomplete
onChange={handleRecChange("foodRecs")}
multiple
options={menuItems}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
variant="outlined"
key={option}
label={option}
onDelete={() => console.log("test")}
{...getTagProps({ index })}
/>
))
}
renderInput={params => (
<TextField
{...params}
variant="standard"
label="Recommendations"
placeholder="Choose anything from the menu"
fullWidth
/>
)}
/>

That's because you override onDelete in this line:
{...getTagProps({ index })}
getTagProps is a getter for the tag props. It includes onDelete function, since onDelete is a Chip property (you can print the getTagProps return value to see that).
You should placegetTagProps on the first line, to avoid unwanted prop overrides:
<Chip
{...getTagProps({ index })}
variant="outlined"
key={option}
label={option}
onDelete={() => console.log("test")}
/>

Related

MUI: You have provided an out-of-range value `18:00` for the select component

I use react with Mui;
<Select
disabled={disable}
renderValue={(value) => renderValue(value as number)}
size="small"
value={object.time}
onChange={({ target }) => onChange(target.value as string)}
>
{hours.map((hour) => (
<MenuItem key={hour.id} value={hour.val1}>
<ListItemText title={hour.time} primary={hour.time} />
</MenuItem>
))}
</Select>
I tried using many solutions like add defaultValue="" or stringify the value but none helped

material ui - Autocomplete multiple error

I am using material-ui in React.js. When using multiple in Autocomplete it gives me the error,
Uncaught TypeError: (intermediate value)(intermediate value)(intermediate value).filter is not a function at useAutocomplete,
The above error occurred in the <ForwardRef(Autocomplete)> component:
in ForwardRef(Autocomplete).
material-ui version - "#mui/material": "^5.6.0",
Code:
<Autocomplete
multiple={true}
disableCloseOnSelect
id={field.name}
name={field.name}
options={locations}
value={props.values.locationId}
size="small"
autoComplete={false}
onChange={(e, newValue) => {
props.setFieldValue(
'locationId',
newValue ? newValue : '',
true,
);
}}
onBlur={() =>
props.setFieldTouched(field.name, true)
}
getOptionLabel={(option) =>
option['name'] ? option['name'] : ''
}
renderOption={(props, option, { selected }) => (
<li {...props}>
<Checkbox
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</li>
)}
renderInput={(params) => (
<TextField
{...params}
fullWidth
size="small"
placeholder={field.placeholder}
variant="outlined"
/>
)}
/>
When using multiple, value must be an array (see multiple in the docs). I found this answer helpful for using a controlled Autocomplete component in multiple mode, as you're doing here.

Create tag using Autocomplete material UI when user input anything

I can type something which shows selected tags from the dropdown list but I want a user can type something and create a tag or multiple tags separated by a comma.
I used a useState hook which is an array.
const [tags, setTags] = useState([]);
I set the Autocomplete like the following code -
<Autocomplete
style={{ margin: "10px 0" }}
multiple
id="tags-outlined"
options={tags}
defaultValue={[]}
freeSolo
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip variant="outlined" label={option} {...getTagProps({ index })} />
))
}
renderInput={(params) => (
<TextField
{...params}
label="Tags"
placeholder="Tags"
value={tags}
onChange={(e) => setTags([...tags, e.target.value.split(",")])}
/>
)}
/>;
Surprisingly, I tried for an hour before questioning. But Solve it within a few moments after putting the question.
Here's the solution-
<Autocomplete
style={{ margin: "10px 0" }}
multiple
id="tags-outlined"
options={tags}
defaultValue={[...tags]}
freeSolo
autoSelect
onChange={(e) => setTags([...tags, e.target.value])}
renderInput={(params) => (
<TextField
{...params}
label="Tags"
placeholder="Tags"
value={tags}
/>
)}
/>;
the output will look like this.
user input tag
but I want to add multiple tags that didn't happen right now which can be put via giving a space or comma.
Partly relevant but I think it can be helpful for someone using React Hook Form library with MUI5.
Storing tags in the state would render them being saved in form data when submitted. Instead, you need to use their onChange function.
const Tags = ()=>{
const { control,handleSubmit } = useForm({
defaultValues: {
checkbox: true,
autocomplete:["test"]
}
});
const onSubmit = data => console.log(data);
return <>
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="autocomplete"
control={control}
render={({ field }) => {
const {value,onChange} = field
return <Autocomplete
style={{ margin: "10px 0" }}
multiple
id="tags-outlined"
options={value}
defaultValue={[...value]}
freeSolo
autoSelect
onChange={((e)=>onChange([...value,e.target.value]))}
renderInput={(params) => {
return <TextField
{...params}
label="Tags"
placeholder="Tags"
value={value}
/>
}}
></Autocomplete>
}
}
/>
<input type="submit" />
</form>
</>
}

Autocomplete won't show a value and let me set a new one

I'm using material UI Autocomplete and react-hook-form to build a modal, but I simply can't show a value and change it at the same time.
When I pass the “default” value to InputValue, it does show up on the screen, but I can't edit it via input, and when I place it down on value it won't show on the screen, but it does let me change values via input and select.
This would be my component that is being rendered
<Autocomplete
id={name}
options={options}
getOptionLabel={(option) => (option.descricao ? option.descricao : "")}
filterOptions={filterOptions}
onChange={(e, options) =>
// console.log(options)
setValue(name, options?.descricao)
}
// onInputChange={(e, v) => setValue(name, v)}
value={cnae ? cnae : ""}
inputValue={cnae ? cnae : ""}
renderOption={(props, options) => (
<Box component="li" {...props}>
{options.id +
"/" +
options.grupo.divisao.id +
", " +
options.descricao}
</Box>
)}
loading={loading}
renderInput={(params) => (
<TextField
{...params}
{...other}
label={label}
error={Boolean(errors[name])}
helperText={errors[name] ? errors[name].message : ""}
/>
)}
/>
This are the what props are being passed:
<ACCnae
name="cnae"
label="Ramo"
fullWidth
errors={errors}
options={context.cnae}
setValue={setValue}
cnae={getValues("cnae")}
required
/>
And as you can tell here, i'm typing, but only clearing and selecting works
I've found a way to make it work, but it's definitely not the right way or the best way to do it.
First I find the whole object that I need to set as the value on the autocomplete, that's the only way to actually make it work.
And if the object is already set I use the setValue from react-hook-form to set the new value to the data object.
React.useEffect(() => {
if (!obj) {
setObj(options.find((item) => item.descricao === cnae));
}
if (obj?.descricao) {
setValue(name, obj.descricao);
}
}, [cnae, obj]);
And the only thing that I've changed from the previous component is that now onChange actually takes setObj
<Autocomplete
id={name}
options={options}
getOptionLabel={(option) => option?.descricao}
filterOptions={filterOptions}
onChange={(e, options) => setObj(options)}
value={obj ? obj : ""}
renderOption={(props, options) => (
<Box component="li" {...props}>
{options.id +
"/" +
options.grupo.divisao.id +
", " +
options.descricao}
</Box>
)}
loading={loading}
renderInput={(params) => (
<TextField
{...params}
{...other}
label={label}
error={Boolean(errors[name])}
helperText={errors[name] ? errors[name].message : ""}
/>
)}
/>
If anyone finds a better or simpler way to do it pls let me know

Material UI Autocomplete: Sync value with state

How to store values from Material-UI's Autocomplete into React's state. Autocomplete uses multiselect and has Array of strings as value.
Example with a functional component
In this example we will show an Autocomplete Component with multiple select and checkboxes for each option.
Define state with initial value (In our case: Empty Array):
const [ndl, setNdl] = React.useState([]);
Options which we can select:
const ndlExample = ['Berlin', 'München', 'Saarbrücken', 'Köln'];
Autocomplete Component:
<Autocomplete
multiple
value={ndl}
id="areaFilterId"
options={ndlExample}
limitTags={1}
disableCloseOnSelect
getOptionLabel={option => option}
onChange={(event: any, value: string[] | null) => setNdl(value)}
renderOption={(option, { selected }) => (
<React.Fragment>
<Checkbox icon={icon} checkedIcon={checkedIcon} style={{ marginRight: 8 }} checked={selected} />
{option}
</React.Fragment>
)}
style={{ width: 280 }}
renderInput={params => <TextField {...params} variant="standard" label="Niederlassung" />}
/>
Material's UI Autocomplete API

Resources