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

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
}}
/>

Related

React - Mui - Autocomplete - asks for keys

console: Warning: Encountered two children with the same key
how can i add keys?
i tried
<Stack spacing={2} sx={{ width: 300 }}>
<Autocomplete
id="free-solo-demo"
freeSolo
options={cityObj.map((option) => option.name)}
renderInput={(params) => (
<TextField
{...params}
error={weatherData?.error ? true : false}
fullWidth
label="name your city here..."
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
ref={inputField}
onKeyDown={(e) => e.key === "Enter" && handleSubmit(e)}
/>
)}
/>
</Stack>
Autocomplete automatically maps your options and put the option value as key for each option.
So evidently you have some duplicate name values in in your cityObj array.
I don't know if there is a way to change the keys in order to suppress the warning, but even if there is, I recommend to not fiddling with it and fixing the problem in a correct manner by removing the duplicate value from your options array. Because why would we have two or more identical options in a autocomplete anyway?

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!

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?.

MUI-Autocomplete does not update value on select

I'm using React and Material-UI framework for a project and want to implement the MUI-Autocomplete Component. I do get the options displaying as they're meant to be but upon selecting one of these options the Input field goes blank and even the state remains unchanged.
I also tried the demo on the website and couldn't get it to work.
Here's the code. Take a look at output here.
Link to video showing output
<Autocomplete
id="combo-box-demo"
options={this.props.products}
getOptionLabel={option => option.name}
style={{ width: 300 }}
renderInput={params => (
<TextField
{...params}
label="Combo box"
variant="outlined"
fullWidth
/>
)}/>
I could not replicate the problem on CodeSandbox but here's the link to it.
Link to CodeSandbox
onSelectCapture={this.handleChange}

Material-UI Autocomplete disable options present in array

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)}

Resources