Antd RangePicker Component with React Hook Form - reactjs

I currently have a react-hook-form managed form that I've added an antd RangePicker to. I'm having issues with updates to the RangePicker getting passed to the form object. Currently, the default values are passing fine but it's not taking any changes.
OnChange events seem to be being handled by the standard Controller method with the other field types (Input, etc.). My guess is I have to write something custom here but I'm not sure. Thanks in advance for any help.
Here is my current antd DatePicker that is being managed with react-hook-forms Controller method.
EDIT: Updated my code to use the render method in react-hook-form v6+ as opposed to the as method. I also noticed if I don't pass any defaultValue then the RangePicker accepts and passes both the start and end dates fine. But when I set the defaultValue it always returns the default start date twice.
<Controller
name="materialarrivalpickup"
control={control}
defaultValue={[
moment(user.project.projectmaterialarrival),
moment(user.project.projectmaterialpickup),
]}
rules={{ required: true }}
render={(props) => (
<RangePicker
{...props}
format="MM/DD/YYYY"
onChange={(e) => {
props.onChange(e);
console.log("Range Picker " + e);
}}
/>
)}
/>

Figured this out. Apparently, react-hook-form was properly passing the RangePicker changes to my form object I just couldn't tell based on the log.
When I update the picker the Moment object (two dates) wasn't looking updated in the log produced by react-hook-form watch() (both look like they're 3/3/2020).
But when I expand the Moment object I'm getting my updated dates (3/3/2020 and 3/5/2020).
I'll leave my working RangePicker + react-hook-form code here for anyone else that needs it.
<Controller
name="materialarrivalpickup"
style={{ marginBottom: "8px" }}
control={control}
defaultValue={[
moment(user.project.projectmaterialarrival),
moment(user.project.projectmaterialpickup),
]}
rules={{ required: true }}
render={(props) => (
<RangePicker
{...props}
format="MM/DD/YYYY"
onChange={(e) => {
props.onChange(e);
console.log("Range Picker: " + e);
}}
/>
)}
/>

Related

React Hook Form - Rules.Validate not triggered

I have the following field with a RHF controller and a MUI Textfield:
<Controller
control={control}
name="name"
defaultValue=""
rules={{
required: true,
minLength: 3,
maxLength: 300,
validate: wtf,
}}
render={({ field, fieldState: { error } }) => (
<TextField
{...field}
fullWidth
label="Name"
size="small"
helperText={formState?.errors?.name?.message}
error={error !== undefined}
/>
)}
/>
The wtf method isn't getting called on input change. I've tried with different revalidate modes but this is just not firing at all. Am I missing something here? I've checked examples and tutorials and they all seem to do it this way.
I created a sandbox here and it works perfectly.
I only had to add {mode: "onChange"} inside the useForm method call and return a string if the validation function failed.
I based my improvements in the documentation for register options as it is recommended here in the rules section of the Controller component.
Feel free to ask for any further help.
-Ado

Why does the mui datepicker onChange method revert the format of the date back to the default format

I am using material ui's date picker.
https://mui.com/components/date-picker/#basic-usage
The default format of the datepicker is MM-dd-yyyy (02-23-2022). I want to change the default format to be dd-MM-yyyy` eg. (23-02-2022).
To have it display in the correct format i have used the inputFormat. However i noticed that the onChange value is still an object and therefore i have used the format function from the adapter date-fns to format the value before storing it in state.
However, although the console logs the correct foramt, the value being set in state for the date is still using the old format (MM-dd-yyyy)
What am i doing wrong here. Please see the ccodesandbox for continence https://codesandbox.io/s/basicdatepicker-material-demo-forked-460hxz?file=/demo.js:418-820
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
label="Basic example"
value={value}
onChange={(newValue) => {
setValue(format(newValue, "dd-MM-yyyy"));
}}
renderInput={(params) => <TextField {...params} />}
mask="__-__-____"
inputFormat="dd-MM-yyyy"
/>
</LocalizationProvider>
You need to add a 'rifmFormatter' prop, and write a function to handle it. I am working on MUI X, but it is the same as in previous versions. see: https://mui.com/x/api/date-pickers/date-picker/
You don't need to apply any format for the data. inputFormat="dd-MM-yyyy" will take care of everything on MUI Datepicker. This code is working perfectly. Whatever value you are getting is basically a Date type. You can apply format on that.
<DatePicker
views={["day"]}
label="Just date"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
inputFormat="dd-MM-yyyy"
renderInput={(params) => <TextField {...params} helperText={null} />}
/>;
Attaching the sandbox for reference.

How to set an empty label on Material-UI V5 (#mui/lab) datepicker component?

I'm working on migrating material-ui v4 to MUI v5 and I was using material-ui-pickers along with it.
I read the migration guide: https://mui.com/guides/pickers-migration/ and the docs, but I can't find and equivalent for the emptyLabel feature in: https://material-ui-pickers.dev/api/KeyboardDatePicker
emptyLabel on material-ui-pickers allowed you to set a custom text, that showed up when the value on the picker was set to null.
Is this a missing feature in MUI's date picker or am I missing something?
KeyboardDatePicker is no longer maintained and is now part of the lab components in MUI v5 as DatePicker (as explained in migration guide).
Actually there's no "emptyLabel" prop for DatePicker but you can achieve the same effect using the label prop and a check on your value provided to DatePicker:
<DatePicker
label={value === null ? "null value!" : "placeholder"}
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
see example here
Wouldn't using placeholder cover your desired use case?
<DatePicker
...
renderInput={(params) => (
<TextField
{...params}
inputProps={{
...params.inputProps,
placeholder: "Place for extra info"
}}
/>
)}
/>
Here is a live codesandbox example.

Getting values from react-select component in react-hook-form?

I'm trying to use a react-select component inside of a form created using react-hook-form. I have followed the instructions from the react-hook-form website here, but when I submit the form the value from the select component is "" (the default value).
I know that the form is working in general because other values that are input with ref={register} work fine. It's just this one value that I'm using the Controller for. Am I missing a prop in the Select component or am I going wrong somewhere else?
I have a parent component where the form is defined:
<Form id="public-share-form" onSubmit={handleSubmit(onSubmit)}>
<Controller
as={<PublicShareNetworkSelect />}
name="network"
control={control}
defaultValue=""
/>
</Form>
Then a child component for the react-select component used in the as prop of the Controller:
return (
<Select
closeMenuOnSelect={true}
options={networks}
noOptionsMessage={() => "No matching options"}
defaultValue=""
className="basic-single"
classNamePrefix="select"
/>
);
I think you need to use Select directly like this:
<Controller
as={
<Select
closeMenuOnSelect={true}
options={networks}
noOptionsMessage={() => "No matching options"}
defaultValue=""
className="basic-single"
classNamePrefix="select"
/>
}
name="network"
control={control}
defaultValue=""
/>

React Material UI Color Picker with Formik

I'm trying to use material-ui-color picker with Formik. I'm using React Material UI FormControl. Here's what I've tried for the color picker:
<FormControl
variant="outlined"
error={Boolean(touched.color_code && errors.color_code)}>
<ColorPicker
id="color_code"
defaultValue="#03a9f4"
onChange={handleChange}
value={values.color_code}
aria-describedby="color_code-error-text"
name="color_code"
/>
{touched.color_code && errors.color_code ? (
<FormHelperText id="color_code-error-text">
{errors.color_code}
</FormHelperText>
) : null
}
</FormControl>
Now, the issue is that, the selected color code is not being populated inside formik form values when I'm submitting the form.
Any help would be highly appreciated. Thanks in advance.
The onChange function provides the hex code directly. You can use the setFieldValue function provided from useFormik hook. So try doing the following:
<ColorPicker
id="color_code"
defaultValue="#03a9f4"
onChange={(value) => setFieldValue("color_code", value)}
value={values.color_code}
aria-describedby="color_code-error-text"
name="color_code"/>
I hope this helps!

Resources