react-hook-form can't see change value by click on button to reset input - reactjs

Component with input and button to reset input TexInputComponent:
<input
type={type}
name={name}
ref={register}
/>
<button
type="button"
onClick={clearInput}>
Reset input
</button>
const clearInput = () => {
document.querySelector(`#${name}`).value = null;
};
I'm using TexInputComponent inside form in another component:
<TexInputComponent
name="title"
defaultValue={data?.title}
register={register({ required: 'Title is required.' })}
error={errors.title}
/>
Now when I click submit on form react-hook-form return me error e.g 'Title is required!'. When I writing something in TexInputComponent, then error disapear.
The problem is when I writing text and click button to reset input. The clearInput method is executed (this method changing value to null) Now should displaying error, but I thing the react hook form can't see value changing.
How I can fix it?

Your clearInput() doesn't work because you don't provide a unique id so it can't find the input element to reset. So change to this:
<input
id={name} // --> add this line to fix
type={type}
name={name}
ref={register}
/>
However there are other ways to easily reset the form without having to define your own reset method:
Use <input type='reset' /> to create a reset button that resets all fields in a form.
Use reset() function from useForm hook to reset a specific field:
const { register, reset } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>First name</label>
<input type="text" name="firstName" ref={register} />
<label>Last name</label>
<input type="text" name="lastName" ref={register} />
<input type="submit" />
<button
type="button"
onClick={() => reset({ firstName: "default name" })}
>
Reset first name
</button>
</form>
);

Related

React-final-form focus doesn't focus on given field

I was trying to focus on the field when the user press the button, I used focus('fieldName'), but it seems doesn't work.
Below is codesandbox:
https://codesandbox.io/s/condescending-heisenberg-q8dcr?file=/src/App.jsx
As #erikras responded in GitHub issue:
That's not what form.focus() does. form.focus() tells Final Form that
a field has received focus.
You need an actual ref to the DOM node. Like this:
https://codesandbox.io/s/mystifying-mestorf-26yv8?file=/src/App.jsx
From codesandbox, we should const ref = useRef(); with Input
<Field name="firstName" type="text">
{({ input }) => (
<input {...input} placeholder="First Name" ref={ref} />
)}
</Field>
Then onClick:
<button
type="button"
onClick={() => {
ref.current.focus();
}}
disabled={submitting || pristine}
>
Focus
</button>

How to get data from form component and pass to method in React?

In a React project, I have form component which gets input data like email, password and passes to submit method. In a method 'requestOTP' requires email from form component. What could be appropriate solution to get that email data from form and pass to requestOTP method? Below is the code for reference.
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="email"
render={({ onChange, value, ref }) => (
<Input
placeholder="EMAIL"
onChange={onChange}
ref={ref}
value={value}
type="email"
/>
)}
rules={{
required: "Please enter email",
pattern: {
value: /^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: "Invalid email address"
}
}}
/>
<div className={classes2.root}>
<Button
variant="contained"
type="submit"
>
LOG IN
</Button>
</div>
</form>
<form onSubmit={handleSubmit(requestOtp)}>
<Button
variant="contained"
type="submit"
>
GET AN OTP ON YOUR EMAIL
</Button>
</form>
const requestOtp = async (data) => {
{/* I want email data from form component here */}
}
onSubmit event listener already have target values. For example, If you have input tag named 'email' in your form (that is <input name="email" ... />)
function handleSubmit(e) {
const email = e.target['email'].value;
//... and then pass email to the requestOTP function
}

form setstate on submit, not on onchange

I have a view showing name and email. I click edit, and an overlay shows up. I want to have the state updated on save changes, not on change, as to avoid having this.state.name and this.state.newName...
Not sure how to handle this...
This is the view - not editable
<div>
<span>{name}</span>
<span>{email}</span>
</div>
This is the form - editable
<form>
<div>
<span>
<input
type="text"
name="name"
title="Please fill out this field"
required
onBlur={event => { handleChange(event) }}
onChange={event => { handleChange(event) }}
/>
</span>
</div>
<div>
<span>
<input
type="text"
name="email"
title="Please fill out this field"
required
onBlur={event => { handleChange(event) }}
onChange={event => { handleChange(event) }}
/>
</span>
</div>
</form>

Specify initial value for radio button

I want to the "Exact" radio button to be checked when a form is opened:
<Form
onSubmit={onSubmit}
initialValues={{ match_type: "exact" }}
render={({ handleSubmit, form, reset, submitting, pristine, values }) => (
<form
onSubmit={() => {
handleSubmit();
}}
>
<fieldset>
<legend>Match type</legend>
<Field name="match_type">
{({ input }) => (
<label>
<input {...input} type="radio" value="fuzzy" /> Fuzzy
</label>
)}
</Field>
<Field name="match_type">
{({ input }) => (
<label>
<input {...input} type="radio" value="exact" /> Exact
</label>
)}
</Field>
</fieldset>
<button type="submit">Save match</button>
</form>
)}
/>
The radio button remains unchecked. Any idea how I should get this to work? Note using <Field component="input" type="radio" .../> is not an option for me.
Codesandbox: https://codesandbox.io/s/react-final-form-reset-after-submit-forked-q6jyv?file=/index.js:359-1235
You can set the default to be checked in the tag.
<input {...input} type="radio" value="exact" checked />
I just needed to use the Field component properly:
<Field name="match_type" type="radio" value="fuzzy">
{({ input }) => (
<label>
<input {...input} /> Fuzzy
</label>
)}
</Field>
This way the <input will get what it needs spread in from the argument to the render prop.
If you inspect your component in codesandbox provided, you can see that Field component doesn't have value prop. I'm attaching a screenshot here
You have a few options to solve this. The main idea though is to understand what you are passing when you say {...input} In your Field component, you currently only have name prop, so you can add something like this
input={{ name: 'match_type', value: 'exact', onChange: (e) => (whatever you need on change) }}
RFF could be tricky with just setting value like that since source of truth lives in the form. So, you can also use a mutator functionality of the form. This is a good description of how to do it

Using bootstrap components with react-hook validation form

I've been working with React for a while, and decided to try out react-hook. I'm trying to make a simple form with some simple validation, but it seems like the validation does not apply to bootstrap components. For the 'regular' input, it works fine, but for the form.control it's not working(The validation is skipped). Saw one solution where you wrap the componenet in a controller, as shown bellow, but i got the same result. Any ideas?
Thanks.
function Example(){
const { register, handleSubmit, control, errors } = useForm();
const onSubmit = (data:any) => {
console.log(data)
}
return(
<Form onSubmit={handleSubmit(onSubmit)}>
<Form.Label column>Name</Form.Label>
<Controller as={<Form.Control/>} name="firstName" control={control} ref={register({required: true})} defaultValue="" />
{errors.firstName && <p>This is required</p>}
<input name="lastName" className="form-control" ref={register({required: true})} />
{errors.lastName && <p>This is required</p>}
<input type="submit" ref={register({required: true})}/>
</Form>
)
}

Resources