React form hook using button as input - reactjs

I am trying to use react form hook in my react form. and there i needed to use a field call 'status' which will have 0 or 1 value ie accept or reject. and as input i want to have two submit button with Accept And Reject.
I tried following but didnt worked
//this is schema
const schema = yup.object({
reply: yup.string().required("Reply"),
status: yup.number().oneOf([1, 2]),
});
// this is form controller
<Controller
name="status"
control={control}
render={({ field, fieldState }) => (
<Box display={'flex'} gap={2}>
<Button
color="error"
type="submit"
value={1}
variant='contained'
{...field}
>Accept</Button>
<Button
color="warning"
type="submit"
variant='contained'
value={2}
{...field}
>Reject</Button>
</Box>
)}
/>

Related

form validation in react hook form

I'm creating a form using yup and react hook form . the issue is the errors are triggered when sending the form but I want that the trigger will be when entering fields this is some of the code:
<Controller name="email"
control={control}
defaultValue=""
render={({field}) => (
<Input {...field} name={field.name} placeholder="email"/>
)}
/>
{errors.email && <span>{errors.email.message}</span>}
<Controller name="confirmation_email"
... />}
/>
email: yup.string().email(format_email).required(champs_obligatoire),
confirmation_email: yup.string()
.oneOf([yup.ref('email'), null], 'Emails must match').required(champs_obligatoire),
<form onSubmit={handleSubmit(onSubmit)}>
<MyForm errors={errors} control={control} t={t}/>
<Button type="submit" variant="contained">
Envoyer
</Button>
</form>
this code is from 3 files : the form and the services , thank you in advance for your help .
please I need a detailed explanation because I am new in react world.

Form not Submitting in React using Formik and Yup

I'm using Autocomplete component in Material UI and I'm using Formik and Yup for validations.
My problem is that when I submit my values and console it. It doesn't appear which means it doesn't conform to its yup validation.
Pls check my codesandbox here
Click here
<Formik
validationSchema={citySchema}
initialValues={{ city_id: [{ id: null, name: "" }] }}
onSubmit={submit}
>
{({ handleChange, values, setFieldValue, touched, errors }) => (
<Form>
<Autocomplete
id="city_id"
name="city_id"
options={cities}
getOptionLabel={(option) => option.name}
style={{ width: 300 }}
onChange={(e, value) => {
setFieldValue("city_id", value);
}}
renderInput={(params) => (
<TextField
label="City"
variant="outlined"
helperText={touched.city_id && errors.city_id}
error={touched.city_id && Boolean(errors.city_id)}
{...params}
/>
)}
/>
<Button variant="contained" color="primary" type="submit">
Submit
</Button>
</Form>
)}
</Formik>
Your validationSchema requires a name but your code never supplies it.
Either make it optional or add a name input field.
An easy way to debug this is to print out the errors formik is supplying you:
<Form>
<pre>{JSON.stringify(errors, null, 2)}</pre>
<Autocomplete
...

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
}

Save values in a form in reactjs [duplicate]

This question already has answers here:
Save data in a form using reactjs
(2 answers)
Closed 2 years ago.
I have an application where user can submit data using a form. I'm using dynamic form where user can set how many forms he wants.
<Form name="dynamic_form_nest_item" onFinish={onFinish} autoComplete="off">
<Form.List name="users">
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) =>
!fieldsOnEdit.includes(index) ? (
<Space
key={field.key}
style={{ display: "flex", marginBottom: 8 }}
align="start"
>
<Form.Item
{...field}
name={[field.name, "first"]}
fieldKey={[field.fieldKey, "first"]}
rules={[
{ required: true, message: "Missing first name" }
]}
>
<Input placeholder="First Name" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit{setFieldOnEdit(index)}
</Button>
</Form.Item>
</Space>
) : (
<Edit value={formVal} keyForm={index} />
)
)}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
>
<PlusOutlined /> Add field
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Form>
When i click on submit button appears <Edit value={formVal} keyForm={index} /> component where should appears corresponding value from the form. Now there is an issue:
when i save for example 2 forms, the second value overrides previous and so on.
I made this: value.users[value.users.length - 1].first, trying to set for every form corresponding value but it does not work.
Question: How to solve the issue, and when i will save a form to display the corresponding value in component?
demo: https://codesandbox.io/s/modest-austin-kqztw?file=/index.js:698-2310
The value is not overwritten, you are rendering always the same item.
You have the index of wanted item in keyFrom prop in your Edit component, just use it:
export const Edit = ({ value, keyForm }) => {
return (
<div>
edit mode
<p>value: {value.users[keyForm].first}</p>
</div>
);
};

React Formik bind the external button click with onSubmit function in <Formik>

I'm trying to submit the form by using the external buttons which are located outside of <Form> or <Formik> tags
As shown in the following screenshot, my button is in Bootstrap > Modal Footer section and they are outside of form tag. I'm trying to submit the form when the user clicks on the Submit button.
Please see the similar code as the following. I uploaded it onto CodeSandbox.
function App() {
return (
<div className="App">
<Formik
initialValues={{
date: '10/03/2019',
workoutType: "Running",
calories: 300
}}
onSubmit={values => {
console.log(values);
}}
render={({ values }) => {
return (
<React.Fragment>
<Form>
Date: <Field name="date" />
<br />
Type: <Field name="workoutType" />
<br />
Calories: <Field name="calories" />
<br />
<button type="submit">Submit</button>
</Form>
<hr />
<br />
<button type="submit" onClick={() => this.props.onSubmit}>
Button Outside Form
</button>
</React.Fragment>
);
}}
/>
</div>
);
}
Since the button is outside of the form, it doesn't trigger Submit behaviour and I don't know how to connect this button's action and Formik OnSubmit method. If I moved that button inside form tag, it works as expected and I don't have to do anything special.
I tried to follow this SO's post React Formik use submitForm outside . But I really couldn't figure out how it works.
I tried to bind the button click action like onClick={() => this.props.onSubmit} as mentioned in the post. But it's not doing anything or showing any error.
Could you please help me how I can bind the Submit button outside of the form with 'OnSubmit' function in Formik?
It appears you have access to the submitForm method as a property of the argument passed to the render function. Simply call that with the button's onClick handler...
render={({ submitForm, ...restOfProps}) => {
console.log('restOfProps', restOfProps);
return (
<React.Fragment>
<Form>
Date: <Field name="date" />
<br />
Type: <Field name="workoutType" />
<br />
Calories: <Field name="calories" />
<br />
<button type="submit">Submit</button>
</Form>
<hr />
<br />
<button type="submit" onClick={submitForm}>
Button Outside Form
</button>
</React.Fragment>
);
}}
Formik's render give you a callback param handleSubmit. Assign this to the <button.
Since your button is not in the form, change its type to <button type="button"... and assign the onClick to onClick={handleSubmit}
Update the render as follow,
render={({ values, handleSubmit }) => {
return (
<React.Fragment>
<Form>
Date: <Field name="date" />
<br />
Type: <Field name="workoutType" />
<br />
Calories: <Field name="calories" />
<br />
<button type="submit">Submit</button>
</Form>
<hr />
<br />
<button type="button" onClick={handleSubmit}>
Button Outside Form
</button>
</React.Fragment>
);
}}
This is because the handleSubmit function is never called, replace onClick={() => this.props.onSubmit} with onClick={props.handleSubmit}
edit: since it looks like you need a little more directions, here is an edited version of the linked code sandbox, the correct prop is handleSubmit and you need to destructure it from the props just like you did with values.
https://codesandbox.io/s/qz2jnlp929
Just use onClick={handlesubmit} in your external Button component making sure to destructure the handlesubmit function from the Formik component. Please have a look;
<Formik
initialValues={{field: true}}
onSubmit={() => console("Submited via my onSubmit function")}
>
{({ handleSubmit }) => (
<Form>
<Field
name="field"
placeholder="Date"
/>
</Form>
<Button type="submit" onClick={handleSubmit}>
Save
</Button>
</Formik>

Resources