Material-UI Autocomplete move clear and popup Icon location to the left - reactjs

We try to implement the autocomplete text field.
The clear and popup icon always appears from the right side (end adornment).
We have an option to work with rtl direction and we can't find a way to flip this component:
put the clear/popup icon in the start adornment.
change the direction that will set the end adornment to the left side of the field
Is anyone found a way to do this?

The clear and popup icon buttons of Autocomplete is hardcoded in endAdornment prop, there is no way to change that using the public API, but you can swap it by using this workaround:
export default function Demo() {
return (
<Autocomplete
options={top100Films.map((option) => option.title)}
renderInput={(params) => {
return (
<TextField
{...params}
InputProps={{
...params.InputProps,
startAdornment: (
<div>{params.InputProps.endAdornment.props.children}</div>
),
endAdornment: null
}}
label="freeSolo"
/>
);
}}
/>
);
}
Live Demo

Related

How can I add an Material UI Icon to an input component in React?

I got a basic input component in React and want to be able to add an Material UI - Icon either on the left or on the right side inside of the input field.
What is the best practice for doing this?
Appreciate any help.
You probaly looking for "input adornments"
https://mui.com/material-ui/react-text-field/#input-adornments
<TextField
{...textFieldProps}
onClick={() => {}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<YourCustomIcon />
</InputAdornment>
),
}}
/>

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.

React Mui DateRangePicker include Calendar Icon

I want to implement a DateRangePicker from Material UI with a calendar icon, e.g. it should look like that:
According to the Api documentation it should work with
components={{
OpenPickerIcon: CalendarTodayIcon
}}
but it doesn't. See codesandbock.
I also tried it by adding an Icon manually to the TextField which shows an Icon but doesn't open the PopupMenu when clicking on the Icon.
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton>
<CalendarTodayIcon />
</IconButton>
</InputAdornment>
)
}}
Anyone an idea how to implement that? I am using mui 5.1.0 and mui/lab 5.0.0-alpha.50
I haven't used the Component from the library but you're right according to the documentation
components={{
OpenPickerIcon: CalendarTodayIcon
}}
Should work but it doesn't.
In your workaround, you're not supplying anything on the IconButton onClick event handler so naturally, the icon does nothing when clicked.
What you need to do is focus on the input whenever the Icon is clicked. You can achieve that by using the useRef hook in your input and then calling the current.focus() method inside the onClick handler of the IconButton.
const startInputRef = React.useRef();
<TextField
inputRef={startInputRef}
{...startProps}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={() => {
startInputRef.current.focus();
}}
>
<CalendarTodayIcon />
</IconButton>
</InputAdornment>
)
}}
/>
See codesandbox for a working example.
I still think this is a hacky workaround though so I'd suggest opening an issue on the library's github repo to get instructions.

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