Material-UI Autocomplete disable options present in array - reactjs

I am trying to use the <Autocomplete /> Material-UI component as per their documentation.
Their example shows how to disable autocomplete by using the getOptionDisabled prop function as follows:
getOptionDisabled={option => option === timeSlots[0] || option === timeSlots[2]}
Let's say that I have an array that I am dynamically generating of timeSlots that I would like to disable, timeSlotsArr, how could I use this prop to exclude all options that are present inside the timeSlotsArr array?
My current code, which is not working, looks like this:
<Autocomplete
options={timeSlots}
getOptionDisabled={option => option === timeSlotsArr.indexOf(option}
style={{ width: 300 }}
renderInput={params => (
<TextField
{...params}
label="Disabled options"
variant="outlined"
fullWidth
inputProps={{
...params.inputProps,
autoComplete: 'disabled', // disable autocomplete and autofill
}}
/>
)}
/>

Wouldn't this be enough if you want to disable all the options in the dropdown?
getOptionDisabled={option => true}
As far as I understand you only pass a function that will return a boolean, so that would do it, right?
Also, your code is not working because it is comparing one of the options in the dropdown with what indexOf returns, which is -1 if it wasn't found, the index if it was. That is never going to be true. You could change it to:
getOptionDisabled={option => !!timeSlotsArr.find(option)}
If you use indexOf, the option would the index 0 would return false too, and you wouldn't want that.

This worked for me
getOptionDisabled={(option) => !!timeSlotsArr.find(element => element === option)}

Related

React Mui Autocomplete does not store the value until losing focus of the input

I have a functional Mui Autocomplete that lets the user select from options or make his own input. However, the value is not stored on useState when an option is clicked, only when the input loses its focus. I have checked some tutorials and apparently I have nothing different, but theirs work as expected (selected option on selection is stored as useState value).
CodeSandbox here
<Autocomplete
key={"casa"+index}
freeSolo
autoSelect
fullWidth
value={i.casa}
onChange={e=>ponervalor(e,index)}
options={casasNamesList}
id={"casasNamesList"+index}
size="small"
color="primary"
autoComplete={false}
renderOption={(props, option) => {
return (
<span {...props} style={{ backgroundColor: "primary", border:"0.5px solid black"}}>{option}</span>);
}}
renderInput={(params) => <TextField {...params} label="Casa" name="casa" variant="outlined" />}
/>
Edit: To add information, I believe the property autoSelect has something to do with this problem of mine, as it states:
If true, the selected option becomes the value of the input when the Autocomplete loses focus unless the user chooses a different
option or changes the character string in the input.
However, if I set it to false, the selected option is never stored as value.
Well, finally I was able to resolve it by not using onChange and use instead:
onInputChange={(e,newvalue)=>ponervalorcasa(e,newvalue,index)}

Setting initial selected values for Autocomplete as a controlled component

What's happening is on page load, the: form.values.statistics?.ethnicity generates the Chips fine but doesn't set the selected values in the Autocomplete component.
Like in the image below, the Caucasian appears to be not selected when it should be selected from the Autocomplete component
What I've thought of and tried so far in which data.data.attributes.statistics.ethnicity === form.values.statistics.ethnicity:
Maybe I'm missing the "name" property from the Autocomplete component - tried adding so, but I can't. It says the property doesn't exist for the component. Which is weird?
value={ethnicityOptions[arrayOfSelectedIds]} or value={ethnicityOptions[data.data.attributes.statistics.ethnicity]}
Autocomplete code:
<Autocomplete
multiple
options={ethnicityOptions}
getOptionLabel={(ethnicityOptions) => ethnicityOptions.name}
id="multiple-tags"
value={form.values.statistics?.ethnicity}
onChange={(e, newValue) => {
form.setFieldValue('statistics.ethnicity', newValue);
form.handleChange(e);
}}
renderTags={() => null}
renderInput={(params) => (
<Grid className={classes.autoCompleteGrid}>
<TextField
{...params}
variant="outlined"
onChange={form.handleChange}
placeholder="Ethnicities"
/>
</Grid>
)}
/>
Code for generating Chips:
{form.values.statistics?.ethnicity
? form.values.statistics?.ethnicity?.map((v) => (
<Chip
key={v.name}
label={v.name}
onDelete={() => {
onEthnicityChipDelete(v);
}}
/>
))
: ''}
I'm currently stuck on this and I might be just missing something. Any help to breakthrough would be really appreciated!

Mui 5 Autocomplete disablePortal prop not working

I was using previous Mui version 4.11.4 with the Autocomplete component and everything worked well with the disablePortal prop.
However, i am using Mui 5 now and the autocomplete dropdown list sometimes show on top instead of always being on the bottom as what i wanted.
<Autocomplete
disablePortal={true}
id='controlled-demo'
ref={idRef}
name={id.current}
onChange={(e, value) => {
const id = idRef.current.getAttribute('name');
handleOptionChange(e, value, id);
}}
options={getExercisesByCategoryAndMusclegroup(exercise)}
getOptionLabel={(option) => `${option.title}`}
isOptionEqualToValue={(option, value) => option.title === value.title}
renderInput={(params) => (
<TextField
{...params}
name='exercise'
// onChange={(e, value) => handleOptionChange(e, value)}
label='Search exercise...'
variant='outlined'
size={isMatched ? 'small' : 'medium'}
/>
)}
/>
I've tried using a custom Popper component as i saw on another post setting the placement to 'bottom' but that didnt resolve my issue.
Is there a bug to the new v5? Anyone else is experiencing this?
I don't know if this is a bug in MUI v5, but what worked for me is to simply remove the disablePortal prop, which automatically set the placement of the dropdown list to the bottom for any number of elements in the list.

Append a button at the end of Autocomplete options in Material-UI

I am trying to create an autocomplete component that a person will use to select an item from a list of items, I've done that, no issues.
The problem is thatI also want to add a button at the end of the list (like a last item in the list that is always present), so that if the item that the person is looking for is non existent the person can click that button to add a new item. This is the same question and is answered but for react-select, I cant find anything in the API of material-ui to do the same. Append a button at the end of options in react-select
An example (taken from the question above): https://i.stack.imgur.com/WRFd8.png
I tried adding an onClick to the TextField, but of course, that gets triggered as soon as someone clicks on the auto ocmplete
<Autocomplete
id="supplierIdd"
style={{ width: 300 }}
options={suppliers.map((supplier) => supplier.name)}
renderInput={(params) =>
<>
<TextField {...params} label="Булстат" margin="normal" onClick={()=>{console.log("hi")}} variant="outlined" />
</>
}
/>
I also tried adding to the options array, but of course that is an array of just options, not elements, so where would I add a or whatever element?
I found solution, You can use "filterOptions" method to add a new button at the bottom.
Check this::
<Autocomplete
id="supplierIdd"
style={{ width: 300 }}
options={suppliers.map((supplier) => supplier.name)}
renderInput={(params) =>
<>
<TextField {...params} label="Булстат" margin="normal" onClick={()=>{console.log("hi")}} variant="outlined" />
</>
}
filterOptions={(options) => {
const result = [...options]
result.push(
((
<Button
variant="outlined"
color="primary"
onMouseDown={onAddNew}
>
+ Add New
</Button>
) as unknown) as string, // typecasting required for typescript
)
return result
}}
/>

Clear all selected values from material-ui Autocomplete Combo box

Solution
I used renderTags in my Autocomplete:
renderTags={() => (
<div>
{(props.selectedAutocompleteValues).map(value => (
<Chip key={value} label={value} />
))}
</div>
)}
Original question
I'm trying to add a handler that clears all selected values from an Autocomplete with multiple values and a dropdown. Basicly duplicating the action of the clear-button that is inside the Autocomplete, and triggering this action from outside the Autocomplete.
The reason for this is that I want to have a filter (material-ui Select) that allows reduces the number of options in the Autocomplete. When changing the filter-value, the previously selected values of the Autocomplete should be cleared.
I'm rendering the values in the Autocomplete with the following code, so it seems like what I need to do is change the params in some way. Any suggestions on how to do this, or other ways of clearing the values?
renderInput={params => (
<TextField {...params} label="my-label" variant="outlined" fullWidth />
)}
Update after comment from Ryan Cogswell:
<Autocomplete
multiple
disableCloseOnSelect
autoHighlight
clearText='Nullstill'
closeText='Lukk'
openText='Åpne'
options={Array.from(props.myMap.keys())}
onChange={(event: any, value: string) => {
props.myUpdateFunction(value)
}}
renderInput={params => (
<TextField {...params} label="myLabel" variant="outlined" fullWidth />
)}
/>
where myUpdateFunction is in the grandparent-component of where the Autocomplete is:
myUpdateFunction = (myArray: Array<string>) => {
this.setState({
selectedAutocompleteValues: myArray,
})
}
The Select component that I want to use to reset the Autocomplete component:
<Select
labelId="my-select-label"
id="my-select"
autoWidth
value={props.mySelectValue}
onChange={(event: any) => props.updateSelect(event.target.value)}>
{Array.from(props.selectOptions, ([optionNr, optionName]) =>
<MenuItem key={optionNr} value={optionNr}>{optionName}</MenuItem>
)}
</Select>
with the following onChange handler:
updateFylke = (value: number) => {
const selectedAutocompleteValues = new Array<string>();
this.setState({
mySelectValue: value,
selectedAutocompleteValues: selectedAutocompleteValues,
})
}
I recommend using a controlled input approach (i.e. specify the value prop for the Autocomplete using selectedAutocompleteValues). Then clearing the Autocomplete is just a matter of updating your state appropriately.
You can see an example of this approach in this related answer: Material ui Autocomplete: can tags be created on events aside from 'Enter' events?.

Resources