Can we remove the calendar icon from the TextField (MUI)? - reactjs

Here is my basic code to accomplish the task, but couldn't come up with any outcome
<TextField
sx={{
'&::-webkit-calendar-picker-indicator': {
display: 'none',
'-webkit-appearance': 'none',
},
}}
id="outlined-basic"
variant="outlined"
type="date"
helperText="Please select the date"
/>
Also, I did a bit research on InputProps (endAdornment) within TextField to remove the icon, but that didn't work.

You can define in the components property the icon to be null for both cases.
<TimePicker
label="Time"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
disableOpenPicker
/>
<DateTimePicker
label="Date&Time picker"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
disableOpenPicker
/>
Here is a working sandbox

I guess u r using MUIv5
(and I guess u talking about DatePicker)
In that case (as u mentioned), the icon is rendered cuz the InputProps with endAdornment is passed to the text field, if u omit that prop, there will be no icon.
<DatePicker
label="Basic example"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={({ InputProps, ...props }) => (
<TextField {...props} />
)}
/>

Related

Add icon to the start of Material-UI's Autocomplete component

I want to add an icon to the beginning of the Autocomplete component. (with startAdornment)
I read that Autocomplete is a normal text input
So far I tried adding
InputProps={{startAdornment: <InputAdornment position="start">kg</InputAdornment>,}}
to the <TextField /> component. Like below:
<Autocomplete
{...defaultProps}
onChange={(event, value) => {
handleOnChange(event, value);
}}
id="disable-close-on-select"
sx={{ width: 300 }}
renderInput={params => (
<TextField
InputProps={{
startAdornment: <InputAdornment position="start">kg</InputAdornment>,
}}
{...params}
label="search"
variant="standard"
/>
)}
/>
Any help would be great, as I'm a beginner to the Material-UI ecosystem.
defaultProps is defined like this.
const defaultProps = {
options: data,
getOptionLabel: (option: DataType) => option?.id,
};
The prop order matters. Your InputProps you define is overridden by the params.InputProps from renderInput. This:
<TextField InputProps={yourProps} {...params}
is the same as:
<TextField InputProps={yourProps} InputProps={param.InputProps} {...}
And the final result is:
<TextField InputProps={param.InputProps} {...}
You need to define your custom InputProps after you spread the params and make sure to spread in the nested prop too:
renderInput={(params) => {
return (
<TextField
{...params}
InputProps={{
...params.InputProps,
startAdornment: (
<InputAdornment position="start">kg</InputAdornment>
)
}}
label="Movie"
/>
);

How to set the placeholder text of the MUI DatePicker?

How can I set the placeholder text of the MUI DatePicker. The text that is displayed when deleting the text in the input field. I want to set the text to "tt.mm.jjjj" and I always the following error message:
Format string contains an unescaped latin alphabet character `j`
Sandbox
<DatePicker
inputFormat="tt.mm.jjjj"
label="Basic example"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField placeholder="tt.mm.jjjj" {...params} />}
/>
This is how you reset the placeholder of the TextField inside the DatePicker. The reason it doesn't work is because it is overridden by the params.inputProps provided by the DatePicker itself based on the inputFormat:
<DatePicker
{...}
inputFormat="tt.mm.yyyy"
renderInput={(params) => {
console.log(params);
return (
<TextField
{...params}
inputProps={{
...params.inputProps,
placeholder: "tt.mm.jjjj"
}}
/>
);
}}
/>

Disabling browser autocomplete on Material-UI TextField

I am using Material UI's country select (https://material-ui.com/components/autocomplete/#country-select). I have an ongoing issue that when the user clicks into the input, the browser autocomplete pop up blocks the view of country options. I've tried my best to turn autocomplete to off but with no joy. Can anyone advise a possible workaround?
Have tried the 3 commonly suggested fixes:
autoComplete="off"
autoComplete="no"
autoComplete="new-password"
return (
<Autocomplete
id="country-select"
options={options}
classes={{
option: classes.option,
}}
autoHighlight
getOptionLabel={(option) => option.label}
onChange={(e, value) => setFieldValue(field.name, value.label)}
onOpen={field.onBlur}
renderOption={(option) => (
<React.Fragment>
<span>{countryToFlag(option.code)}</span>
{option.label}
</React.Fragment>
)}
renderInput={(params) => (
<TextField
{...params}
label={props.label}
name={props.name}
placeholder={props.placeholder}
variant="outlined"
helperText={_renderErrorText()}
error={hasError}
autoComplete="off"
/>
)}
/>
);
this work for me
autoComplete="chrome-off"
AutoComplete should be on rendered Input by material-ui, not the TextField wrapper. So you should do something like that:
<TextField
{...params}
label={props.label}
name={props.name}
placeholder={props.placeholder}
variant="outlined"
helperText={_renderErrorText()}
error={hasError}
inputProps={{
autoComplete: 'new-password',
}}
/>

React Form Hook with Autocomplete Material UI

I have a countries array which contains id and name. Currently I am using a Material UI Autocomplete element and I have a react hook form. When I submit the form, I want to fetch the country Id. Currently it is posting the country name. Is there a way to post the ids instead of the names without going and fetching the id from the name.
<Autocomplete
className="form-item"
options={countries}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField
{...params}
inputRef={register}
label="Country"
name="country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
Use react-hook-form's Controller and put the entire Autocomplete in the as prop. With this, when you submit the form you will get the entire object of the selected option.
Note: In react-hook-form version 6.x, the onChange is removed, the as prop will take a function and you can obtain onChange as param.
Working demo - v6
<Controller
as={({ onChange }) => (
<Autocomplete
className="form-item"
options={countries}
onChange={(_, data) => onChange(data)}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField
{...params}
label="Country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
)}
name="country"
control={control}
defaultValue={{ label: "The Shawshank Redemption", id: "1994" }}
/>
Note: If you are using v5x then see demo and code snippet below.
Working demo - v5
<Controller
as={
<Autocomplete
className="form-item"
options={countries}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField
{...params}
label="Country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
}
name="country"
control={control}
onChange={([, data]) => data}
defaultValue={{ label: "The Shawshank Redemption", id: "1994" }}
/>
Edit: based on comment
You can use setValue to set default values based on an api.
code snippet:
useEffect(() => {
setTimeout(() => { // fake api
setValue(
"country",
{ label: "hi The Godfather", id: "1972" },
{ shouldDirty: true }
);
}, 2000);
}, []);
Demo v6 above is updated.
Also see official demo of setValue usage here
Here is a simplest way to create it, render your Autocomplete component inside Controller from react hook from, use onChange and value from the render function to control the value
<Controller
control={control}
name="type"
rules={{
required: 'Veuillez choisir une réponse',
}}
render={({ field: { onChange, value } }) => (
<Autocomplete
freeSolo
options={['field', 'select', 'multiple', 'date']}
onChange={(event, values) => onChange(values)}
value={value}
renderInput={(params) => (
<TextField
{...params}
label="type"
variant="outlined"
onChange={onChange}
/>
)}
/>
)}
I'm afraid that there is not an 'easy' way to get the ids with the current setup.
However, you can hook into the Autocomplete#onChange event and use the value prop to take over the internal value state of the Autocomplete component. This results in having the value available in your component and use this to your advantage.
In the example below, the id will be available in the form data as country-id.
function CountryAutocomplete() {
const [value, setValue] = useState(); // `[]` for multiple
return (
<React.Fragment>
<Autocomplete
className="form-item"
value={value}
onChange={(event, value) => setValue(value)}
options={countries}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField
{...params}
inputRef={register}
label="Country"
name="country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
<input value={value?.id} name="country-id" />
</React.Fragment>
);
}

react- cleaning autocomplete generates an error

I have a form created with material-ui, I have a textfield that uses autocomplete which is filled with a useEffect that is responsible for bringing the data from the API to load the AUTOCOMPLETE.
The data is not saved.
Code
const defaultProps={
options:location.name,
getOptionLabel: option => option.label + "-" + option.phone,
};
<Autocomplete
style={{ width: 300 }}
{...defaultProps}
id="city"
autoComplete
onChange={(event, newVal)=>onChange({target:{name:"name",value: newVal.label }}
)}
renderInput={params => (
<TextField {...params} label="Country" margin="normal" variant="outlined" inputProps={{
...params.inputProps,
}}/>
)}
What is causing that behavior?
It appears your problem in on the following line:
onChange={(event, newVal)=>onTagsChange({target:{name:"label",value: newVal.label }}
It may be related to newValue being null after clearing. You could add a protection such as:
value: newVal || newVal.label
Since it is not clear to me how you are using the resulting selection my suggested protection may not be appropriate.
You may also want to take a look at their "controlled" example in the documentation (https://material-ui.com/components/autocomplete/#playground) in which they use the value attribute to control the AutoComplete:
<Autocomplete
{...defaultProps}
id="controlled-demo"
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
renderInput={params => (
<TextField {...params} label="controlled" margin="normal" fullWidth />
)}
/>

Resources