React-Quill with Formik is not updating props - reactjs

I am using Formik and React-Quill in my form,
The value seems to be updating when i use <input> but when i plug-in <ReactQuill /> it's not.
Is there something wrong with the setup?
<Field
name="designation"
value={this.props.values.designation}
render={({ field /* _form */ }) => (
// <input {...field} placeholder="designation" />
<ReactQuill
{...field}
/>
)}
/>

For anybody who is still interested in the answer (like I was), you can find it here:
<Formik initialValues={{ designation: '' }}>
<Field name="designation">
{({ field }) => <ReactQuill value={field.value} onChange={field.onChange(field.name)} />}
</Field>
</Formik>
This helps match formik field to ReactQuill props.

I am using "setFieldValue" to update changes. This is working perfectly fine for dynamic Formik forms.
<ReactQuill
value={values.description}
onChange={v => setFieldValue('description', v)}
/>

Related

Material UI Slider with React hook form

I'm having a hard time integrating material Ui Slider with React hook form. It's not registering the values. It's printing the value as undefined on console.log. Got an idea where I might be wrong?
<Controller
render={({ field: { value, onChange } }) => (
<CustomSlider
onChange={onChange}
value={value}
max={60}
marks={marks}
className={classes.slider}
defaultValue={10}
/>
)}
control={control}
name="slider"
/>
Here is codesandbox made by author of react-hook-form that contains many examples. Mui integration is also made.
According to example, you are supposted to do something like this:
<Controller
name="MUI_Slider"
control={control}
defaultValue={[0, 10]}
render={(props) => (
<Slider
{...props}
onChange={(_, value) => {
props.onChange(value);
}}
valueLabelDisplay="auto"
max={10}
step={1}
/>
)}
/>
Another question is in which part of your code are you trying to console.log() values.
You can use watch() method or
<button Click={() => console.log(getValues())}>get values</button>

React-Final-Form delays in taking input with render props in Field

I am currently working on a react project. I am using react-final-form for fetching the data in the form. As I am using the material UI component to create the form I am creating the form somewhat like this.
Code
<Form
onSubmit={onSubmit}
validate={validate}
render={({ handleSubmit, values }) => (
<form onSubmit={handleSubmit}>
<FormControl variant="outlined" className={classes.formControl} key={fieldKey}>
<Field
name={field.fieldName}
render={({ input }) => (
<TextField
{...input}
className={classes.textField}
variant="outlined"
label={props.field.label}
placeholder={props.field.description}
required={props.field.isMandatory}
InputLabelProps={{
shrink: true,
}}
/>
)}
type="text"
/>
</FormControl>
</form>
)}
/>
Now as soon as I remove the input props from the render props it is working fine. but with the input props, it delays in taking input. Without input props, I could not fetch the value from the form.
Is there any way to resolve this time delay?
Thanks in advance.
If you want a simple field. Maybe you can pass on only essential props.
<TextField
name={input.name}
value={input.value}
onChange={input.onChange}
/>
The solution to this is subscriptions.
The form is initially rendered on every action, react-final-form allows to handle subscription,
<Form subscription={{handeleSubmit: true}} ...> </Form>
We can do somewhat like this
There is a video link for this. Video
Hope you find this helpful 😉

react-datepicker with react-final-form

I'm using the react-datepicker inside the react-final-form. I'm using a template with multiple steps https://codesandbox.io/s/km2n35kq3v?file=/index.js. The problem is that I'm not able to integrate the datepicker inside the component. My Code looks like this:
return (
<Field name={props.name} parse={() => true}>
{props => (
<DatePicker
locale="de"
placeholderText="Datum eingeben"
selected={startDate}
dateFormat="P"
openToDate={new Date()}
minDate={new Date()}
disabledKeyboardNavigation
name={props.name}
value={startDate}
onChange={(date) => setStartDate(date)}
/>
)}
</Field>
);
Does anyone knows how I can use it so the data gets passed at the end of the form?
Best regards
I used the wizard form example you sent and added DatePicker similar to yours.
Check the wizard example
But basically, I changed your onChange method to actually use react-final-form field props. Now, it uses this.props.input.onChange, which updates the final form state value, and used this.props.input.value to set the selected state (you can then load initial values into final form):
const RenderDatePicker = ({ name, input, input: { value, onChange } }) => {
return (
<DatePicker
locale="de"
placeholderText="Datum eingeben"
dateFormat="P"
selected={value && isValid(value) ? toDate(value) : null} // needs to be checked if it is valid date
disabledKeyboardNavigation
name={name}
onChange={(date) => {
// On Change, you should use final-form Field Input prop to change the value
if (isValid(date)) {
input.onChange(format(new Date(date), "dd-MM-yyyy"));
} else {
input.onChange(null);
}
}}
/>
);
};
<div>
<label>Date of birth</label>
<Field
name="dateOfBirth"
component={RenderDatePicker}
validate={required}
/>
<Error name="dateOfBirth" />
</div>
Hopefully this helps you.

How to make autocomplete field of material UI required?

I have tried a couple of ways in order to make the material UI's autocomplete field of type required but I am not getting the behavior that I wanted. I had encapsulated my field inside react hook form <Controller/> yet no luck. I want to trigger message 'Field is mandatory' on submit when nothing is added to the field.
Below is the code snippet, I have not removed comments so that it becomes a bit easier for others to understand the approach that I had followed earlier -
<Controller
name="displayName"
as={
<Autocomplete
value={lists}
multiple
fullWidth
size="small"
limitTags={1}
id="multiple-limit-lists"
options={moduleList}
getOptionLabel={(option) => option.displayName}
renderInput={(params,props) => {
return (
<div>
<div className="container">
<TextValidator {...params} variant="outlined" label="Display Name*" className="Display Text"
name="displayName" id="outlined-multiline-static"
placeholder="Enter Display-Name" size="small"
onChange={handleDisplay}
// validators={['required']} this and below line does throw a validation but the problem is this validation stays on the screen when user selects something in the autocomplete field which is wrong.
// errorMessages={['This field is required']}
// withRequiredValidator
/>
</div>
</div>
)
}}
/>
}
// onChange={handleDisplay}
control={control}
rules={{ required: true }}
// required
// defaultValue={options[0]}
/>
<ErrorMessage errors={errors} name="displayName" message="This is required" />
You can use the following logic to get it worked. Though this might not be the best solution but works.
<Autocomplete
renderInput={(params) => (
<TextField
{...params}
label={value.length === 0 ? title : title + " *"} //handle required mark(*) on label
required={value.length === 0}
/>
)}
/>
I tried using the built in required in textfield for autocomplete, and it works like a charm. Maybe you can use this as a reference.
<Autocomplete
renderInput={(params) => {
<TextField {...params} required />
}
// Other codes
/>
Since you are rendering <TextValidator>, you should apply mandatory(required) attribute to that component not on <AutomComplete>.
Try this if your Material UI version is v5
<TextField
{...params}
required
label="Tags"
value={value}
InputProps={{
...params.InputProps,
required: value.length === 0,
}}
/>

Can't submit TextField in Formik

Can't seem to find a reason why the first approach works, and the second doesn't.
Works: pastebin
Doesn't: pastebin
The difference between these two is that there's <TextField> in the second one instead of <div> and <Field>. But the examples I've seen makes the <TextField> work just fine, what am I missing?
You have to pass the component to <Field />:
<Field component={TextField} name="password">
You are now trying to use it like so:
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
render={props => (
<Form>
<TextField
id="name"
name="name"
label="Name"
value={props.values.name}
onChange={props.handleChange}
fullWidth
/>
</Form>
)}
/>
... Which should work, are you getting any errors in the console?
If that doesn't work for some reason you can try doing it via Field render props.
This snippet is taken from the Formik docs.
<Formik
...
<Field
name="lastName"
render={({ field }) => (
<input {...field} placeholder="password" />
)}
/>
...
/>
You see you can use a render props to the Field component to render a custom component if you like.
There are 3 ways to render things with <Field>.
Aside from
string-only component, each render prop is passed the same props for
your convenience.
Field's render props are an object containing:
field: An object containing onChange, onBlur, name, and value of the
field form: Formik state and helpers Any other props passed to field
See more in Formik docs here.

Resources