what happens if I select a date by clicking on the calendar it works fine but if I set inputFormat="yyyy/MM/dd" then I will type the date it will not react like date format its go like 11111111111111111111 it is considered as a string like this so its break the format of date but if I select from the calendar it works fine but only if I will edit direct type it goes wrong.
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Basic example"
value={value}
inputFormat="yyyy/MM/dd"
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
add mask props to your code.
<DatePicker
...
mask="____/__/__"
/>
Related
I am using material UI + react hook form .
https://react-hook-form.com/get-started
https://mui.com/material-ui/
I am trying to make datepicker. but I am facing one issue . My date picker open on top left why ?
here is my code
https://codesandbox.io/s/adoring-currying-iuptqe?file=/src/App.tsx
<Controller
control={control}
name="date"
rules={{
validate: {
min: (date) => isFuture(date) || "Please, enter a future date"
}
}}
render={({ field: { ref, onBlur, name, ...field }, fieldState }) => (
<DatePicker
{...field}
inputRef={ref}
label="Date"
renderInput={(inputProps) => (
<TextField
{...inputProps}
onBlur={onBlur}
name={name}
error={!!fieldState.error}
helperText={fieldState.error?.message}
/>
)}
/>
)}
/>
After some experiments, it seems that it could be because the posted sandbox is having the latest version of MUI, but pairing with an outdated version of #mui/x-date-pickers.
Updated #mui/x-date-pickers to the latest 5.0.13 to match the main MUI version and it looks to be fixed.
Forked demo with the update: codesandbox
I'm creating a form which has a date field. I'm using MUI and react-hook-form for validation. I've tried to render the field in two different ways, but when submitting my form I'm not getting the expected value:
Render 1
Using a Controller component:
const [originalReleaseDate, setOriginalReleaseDate] = useState(null);
<Controller
name={"original_release_date"}
defaultValue={originalReleaseDate}
control={control}
render={({field}) =>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Original Release Date"
value={originalReleaseDate}
onChange={(newValue) => {
setOriginalReleaseDate(newValue);
}}
renderInput={(params) =>
<TextField
{...params}
/>}
/>
</LocalizationProvider>
}
/>
when I render the field this way, I'm getting null for original_release_date after submitting the form.
Render 2
Registering the field directly using {...register("reissue_release_date")} instead of react-hook-form Controlled component.
const [reissueReleaseDate, setReissueReleaseDate] = useState(null);
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Reissue Release Date"
value={reissueReleaseDate}
onChange={(newValue) => {
setReissueReleaseDate(newValue);
}}
renderInput={(params) =>
<TextField
{...params}
{...register("reissue_release_date")}
/>}
/>
</LocalizationProvider>
this way is working half way. If I manually type the date then I'm getting its value on submit, BUT if I use the date picker and then submitting the form I get "".
Any idea what's going on?
Just modified the above answer with a bracket.
const [reqDate, setreqDate] = useState(new Date());
<Controller
name="reqDate"
defaultValue={reqDate}
control={control}
render={
({ field: { onChange, ...restField } }) =>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Request Date"
onChange={(event) => { onChange(event); setreqDate(event); }}
renderInput={(params) =>
<TextField
{...params}
/>}
{...restField}
/>
</LocalizationProvider>
}
/>
InputDate.propTypes = {
name: PropTypes.string,
label: PropTypes.string,
};
export default function InputDate({ name, label }) {
const { control } = useFormContext();
return (
<Controller
name={name}
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<LocalizationProvider dateAdapter={AdapterMoment} >
<DesktopDatePicker
label={label}
control={control}
inputFormat="DD-MM-YYYY"
value={value}
onChange={(event) => { onChange(event); }}
renderInput={(params) => <TextField {...params} error={!!error} helperText={error?.message} />}
/>
</LocalizationProvider>
)} />
)
}
In most cases, if you are using react-hook-form, you don't need to track form fields with useState hook.
Using a Controller component is the right way to go. But there is a problem with onChange handler in your 1st method.
When you submit form, you are getting default date null because field is destructed, but it's not passed to DatePicker. So, onChange prop of field is not triggered when date is changed and react-hook-form doesn't have new date.
Here's how your render method should be
render={({field}) =>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Original Release Date"
renderInput={(params) =>
<TextField
{...params}
/>}
{...field}
/>
</LocalizationProvider>
}
If for some reason, you need to update component state then you have to send data to react-hook-form and then update local state
render={({field: {onChange,...restField}) =>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Original Release Date"
onChange={(event) => {
onChange(event);
setOriginalReleaseDate(event.target.value);
}}
renderInput={(params) =>
<TextField
{...params}
/>}
{...restField}
/>
</LocalizationProvider>
}
I couldn't replicate your setup, but my guess is that in the first render the
reference to the 'setOriginalReleaseDate' is lost when being passed through the Controller's render arrow function.
...
onChange={(newValue) => {
setOriginalReleaseDate(newValue);
}}
...
so, try putting the logic in a defined function like:
const handleOriginalReleaseDateChange = (newValue) => {
setOriginalReleaseDate(newValue);
};
and change the onChange to call the function.
...
onChange={handleOriginalReleaseDateChange}
...
Trying to make a program where there are radio switches each equating to a different boolean value. Depending on the boolean value, it would either make the 'disable' prop on the textfield either true or false. My code allows for the button to be default selected as enabled editing and when I select disable it disables the textfield. However, if I click disable then try and click enable again it won't change the textfield from disable.
const [radioEdit, setRadioEdit] = React.useState(false);
<RadioGroup
value={radioEdit}
onChange={(e) => setRadioEdit(e.target.value)}
aria-labelledby="demo-radio-buttons-group-label"
name="radio-buttons-group"
row
>
<FormControlLabel
value={true}
control={<Radio />}
label="Disabled"
/>
<FormControlLabel
value={false}
control={<Radio />}
label="Enabled"
/>
<p>{String(radioEdit)}</p>
<TextField
id="outlined-basic"
variant="outlined"
size="small"
////////RIGHT HERE////////
value={data["companyname"]}
disabled={radioEdit}
/>
If the default state of radioEdit isn't 'false', it is automatically disabled (set to true or null) and won't let me update it multiple times.
The issue is with onChange you have defined with RadioGroup. Usually, we define
onChange={(e) => setRadioEdit(e.target.value)}
to set the value of text input onEventChangeHandler. But here it's for the Radio button. I was using typescript to find the answer for this and as soon as I copy-pasted your code it showed me the error at setRadioEdit(e.target.value) whereas the setRadioEdit should be boolean. The reason why TypeScript is super useful.
The answer is
onChange={() => setRadioEdit(!radioEdit)}
I'm toggling my state here onChange. So when we setRadioEdit as true, it's actually the radioEdit would be set as true. That's how the useState hook works. So by defining setRadioEdit(!radioEdit) we are toggling the state. If it's true it changes to false and vice versa.
Also you will have to close the </RadioGroup> component. Complete answer
const [radioEdit, setRadioEdit] = useState(false);
return (
<>
<RadioGroup
value={radioEdit}
onChange={(e) => setRadioEdit(!radioEdit)}
aria-labelledby="demo-radio-buttons-group-label"
name="radio-buttons-group"
row
>
<FormControlLabel value={true} control={<Radio />} label="Disabled" />
<FormControlLabel value={false} control={<Radio />} label="Enabled" />
</RadioGroup>
<p>{String(radioEdit)}</p>
<TextField
id="outlined-basic"
variant="outlined"
size="small"
disabled={radioEdit}
/>
</>
);
I am using Mui 5 date picker my issue is if I change the date using calendar I will get the expected result like the example I selected 26 I get this
"2022-01-26T09:16:10.000Z"
but when I edit directly in the field example I selected 27 I get this
"2022-01-26T18:30:00.000Z" because of this I will get a validation error I am not understanding why this happening and after the edit, if the select date from again calendar 26 then the final value is
"2022-01-25T18:30:00.000Z"
for external I am using momentjs and fromik.
const [value, setValue] = React.useState(null);
return (
<Box>
{JSON.stringify(value)}
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Basic example"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
</Box>
);
Using moment, set the initial value to start of the day startOf.
const [value, setValue] = React.useState(moment().startOf('day'))
Code snippet:
export default function BasicDatePicker() {
const [value, setValue] = React.useState(moment().startOf('day'));
return (
<LocalizationProvider dateAdapter={AdapterMoment} >
<DatePicker
label="Basic example"
value={value}
onChange={(newValue) => {
setValue(moment(newValue));
}}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
);
}
Sandbox : here
EDIT:
if you have a specific date to be passed,
React.useState(moment('03-03-2021').startOf("day"))
I have a React + Material-UI frontend. One section allows users to select items from a dropdown and I want the list of whatever the user selects. User can also click x and delete what they selected. How can I use state or some variable to get the final list of items?
CODE:
<Autocomplete
multiple
className={classes.inputField}
id="checkboxes-tags-demo"
options={userData}
disableCloseOnSelect
getOptionLabel={(option) => option.username}
renderOption={(option, { selected }) => (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.username}
</React.Fragment>
)}
style={{ width: 500 }}
renderInput={(params) => (
<TextField {...params} variant="outlined" label="Users" placeholder="Favorites" />
)}
/>
You can access the current selected values by adding an onChange to the Autocomplete component. I have used the Material UI example to show this in action (I am just logging the value to the console -- you will probably want to update a state item):
<Autocomplete
multiple
id="tags-standard"
options={top100Films}
onChange={(event, value) => {
// Printing the current value array
console.log(value);
}}
getOptionLabel={(option) => option.title}
defaultValue={[top100Films[13]]}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
label="Multiple values"
placeholder="Favorites"
/>
)}
/>
The value is an array of objects:
There's a sandbox of this working here (again, it's using the standard Material UI example code). I have only updated the first Autocomplete component to print the value onChange.