How to disable formik form after submission of form? - reactjs

I have created a formik form that stores values at the backend. I have set-reset button, initial values. Everything working fine. But I can't able to find a way to disable formik form after submission of the form i.e if the user fills the form after a click on submit button user is not able to click on the text field.
// #ts-ignore
import React, { useState, useEffect } from 'react';
import { Formik, Form, Field } from 'formik';
import { Typography, Button, Grid } from '#material-ui/core';
import * as Yup from 'yup';
import { MyInput } from './comman/MyInput';
import { Textarea } from './comman/Textarea';
import { Event } from '../Tracking/Event';
const contactSchema = Yup.object().shape({
name: Yup.string().required('Please Enter Your Name'),
email: Yup.string()
.email('Please enter a valid email address')
.required('Please enter an email address'),
number: Yup.string()
.min(10, 'Must be 10 digit.')
.max(10, 'Must be 10 digit.'),
});
export default function ContactUs(props: any) {
const [submitted,setSubmittde] = useState(false);
const [state, setState] = useState({
msg: '',
});
const [selectedemail, setEmail] = useState({
text: '',
});
const [comname, setComname] = useState({
cName: '',
});
useEffect(() => {
fetch(`${window.location.href}`);
//const findemail = window.location.href;
const findemail =
'public/home';
const email =
findemail.match(/([a-zA-Z0-9._-]+#[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/) ||
[];
const finalemail = email[0].toString();
const company = findemail.match(/(?<=%)\w+(?=&)/g) || [];
const finalcompany = company.toString();
setComname({ cName: finalcompany });
setEmail({ text: finalemail });
}, []);
return (
<div>
<img
src="public/logo"
width="200"
className="d-inline-block"
alt="logo"
style={{
marginTop: '2em',
marginBottom: '2em',
float: 'right',
}}
/>
<Formik
enableReinitialize
initialValues={{
name: '',
email: selectedemail.text,
number: '',
companyname: comname.cName,
message: '',
}}
validationSchema={contactSchema}
onSubmit={(values, { resetForm }) => {
const data = {
name: values.name,
email: values.email,
number: values.number,
companyname: values.companyname,
message: values.message,
formtype: 'Email Marketing Contactus',
};
const request = new Request(
`${process.env.REACT_APP_PRODUCTION_EMAILCONTACTUS_API}`,
{
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json',
}),
body: JSON.stringify(data),
},
);
fetch(request)
.then((res) => res.json())
.then((data) => {
if (
data.message ===
'We have received your message and will get in touch shortly. Thanks!'
) {
setState({
msg: data.message,
});
} else {
console.log('error');
}
});
resetForm();
}}
>
{({ errors, touched }) => (
<Grid container>
<Grid item xs={12}>
<Typography
variant="body1"
style={{
marginTop: '1em',
fontFamily: 'roboto',
fontSize: '1.3rem',
color: '#2F4858',
}}
>
To know more please submit your information, and one of our
expert advisors will get in touch within 24 hours!{' '}
</Typography>
<br />
<Form>
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '0.5em',
}}
>
Full Name
</Typography>
<Field
id="outlined-multiline-flexible"
type="text"
name="name"
placeholder="Name"
component={MyInput}
/>
<br />
{errors.name && touched.name ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.name}
</div>
) : null}
<Typography
variant="h6"
style={{ fontFamily: 'roboto', marginTop: '1em' }}
>
Email
</Typography>
<Field
type="email"
name="email"
placeholder="Email"
values={props.text}
style={{ color: 'white' }}
component={MyInput}
/>{' '}
<br />
{errors.email && touched.email ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.email}
</div>
) : null}
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
Mobile Number (Optional)
</Typography>
<Field
name="number"
placeholder="Contact Number"
component={MyInput}
// label="Contact Number"
/>
<br />
{errors.number && touched.number ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.number}
</div>
) : null}
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
Company Name (Optional)
</Typography>
<Field
name="companyname"
placeholder="Company Name"
// label="Contact Number"
component={MyInput}
/>
<br />
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
How can we help? (Optional)
</Typography>
<Field
id="outlined-multiline-static"
name="message"
placeholder="Your question about our services"
label="How can we help?"
component={Textarea}
/>
<br />
<br />
<Button
type="submit"
variant="contained"
onClick={() =>
Event(
'Contact from',
'Client submitted ',
'domain',
)
}
style={{
background: '#F79924',
color: 'white',
fontFamily: 'roboto',
fontSize: '1rem',
}}
>
Submit{' '}
</Button>
<br />
{state.msg && (
<Typography
variant="h6"
style={{
color: '#4BB543',
fontFamily: 'roboto-medium',
marginTop: '1em',
}}
>
{' '}
{state.msg}{' '}
</Typography>
)}
</Form>
</Grid>
</Grid>
)}
</Formik>
</div>
);
}
[![Formik form][1]][1]
I don't know how to disable formik form. Please help?
[1]: https://i.stack.imgur.com/PQXBV.png

This can be simply done using the disabled attribute and your existing value isSubmitted.
Pass a prop disabled into your custom input:
<Field
type="email"
name="email"
placeholder="Email"
values={props.text}
style={{ color: 'white' }}
component={MyInput}
disabled={isSubmitted}
/>
And apply it in the custom input using the ...props spread:
const MyInput = ({
field,
label,
name,
id,
value,
...props
}) => (
<div>
<label htmlFor="id">{label} </label>
<input id={id} type="text" {...field} {...props} />
</div>
);
And make sure you set isSubmitted somewhere in the onSubmit function
fetch(request)
.then((res) => res.json())
.then((data) => {
if (
data.message ===
'We have received your message and will get in touch shortly. Thanks!'
) {
setState({
msg: data.message,
});
setIsSubmitted(true);
} else {
console.log('error');
}
});
Live demo of a simple form that disables inputs/button after submission.

Related

Formik TextFields are not updated once component is rendered

I'm fetching data from the server once component mounts, when I console.log(data) browser shows proper data.
I want to use Formik and MIU TextFields to display data which later on will be updated
const [data, setData] = useState([
{
action: "",
description: "",
tag: "",
category: "",
},
]);
console.log(data);
const [initialValues, setInitialValues] = useState([
{
action: "",
description: "",
tag: "",
category: "",
},
]);
useEffect(() => {
getData();
}, []);
useEffect(() => {
setInitialValues(data);
}, [data]);
const { values, handleChange, handleSubmit, resetForm } = useFormik({
initialValues: initialValues,
validationSchema,
onSubmit: () => {
console.log(values);
axios({
method: "POST",
url: "http://localhost:5000/allActions",
values,
}).then((response) => {
console.log(response);
});
resetForm();
},
});
This is Data component which displays TextFields
const Data = () => {
return (
<form onSubmit={handleSubmit}>
{!data[0].action && "...Loading"}
{data &&
data.map((element, idx) => (
<div key={idx} style={{ marginBottom: "100px" }}>
<Box sx={{ margin: "40px", padding: "20px" }}>
<TextField
variant="outlined"
label="action"
id={`action-${idx}`}
name={`values[${idx}].action`}
value={values[idx]?.action}
onChange={handleChange}
/>
</Box>
<Box sx={{ margin: "40px", padding: "20px" }}>
<TextField
variant="outlined"
label="Description"
id={`desciption-${idx}`}
name={`values[${idx}].description`}
value={values[idx]?.description}
onChange={handleChange}
/>
</Box>
<Box sx={{ margin: "40px", padding: "20px" }}>
<TextField
variant="outlined"
label="tag"
id={`id-${idx}`}
name={`values[${idx}].tag`}
value={values[idx]?.tag}
onChange={handleChange}
/>
</Box>
<Box sx={{ margin: "40px", padding: "20px" }}>
<TextField
variant="outlined"
label="category"
id={`category-${idx}`}
name={`values[${idx}].category`}
value={values[idx]?.category}
onChange={handleChange}
/>
</Box>
</div>
))}
<Button color="primary" variant="contained" type="submit">
Update
</Button>
</form>
);
};
The outcome of above code is that is displays proper amount of TextFields, in this case 3 blocks of 4 TextFields, but it's all empty, none of TextField have filled data which is displayed in console.
Can You please suggest what is wrong that TextFields are not updated ?

How should I create Mongoose Schema for Form Checkboxes in React?

I am creating a Form in React, using MUI and react-hooks-form and I cannot seem to make a successful POST request to my endpoint because something between what I am sending through my form and what Mongoose Schema should receive is not working. When I log the data, my checkbox values are log as an array and I have that checkbox group as an array of strings. Always Bad Requests. Hope someone can help me out.
User Schema
import mongoose from "mongoose";
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: [true, "Por favor escribe tu nombre"],
maxLength: [60, "El nombre no puede tener mas de 50 caracteres"],
},
age: {
type: Number,
required: false,
},
email: {
type: String,
required: [true, "Por favor indicanos tu email"],
},
form: {
type: String,
enum: ["form1", "form2", "form3"],
},
pattern: {
type: String,
enum: ["pattern1", "pattern2", "pattern3"],
},
gadgets: [String],
});
export default mongoose.models.User || mongoose.model("User", UserSchema);
React Form (Not Refactored yet)
import React, { FC, ReactElement } from "react";
import { useForm } from "react-hook-form";
import axios from "axios";
import Box from "#mui/material/Box";
import Typography from "#mui/material/Typography";
import Button from "#mui/material/Button";
import TextField from "#mui/material/TextField";
import Radio from "#mui/material/Radio";
import RadioGroup from "#mui/material/RadioGroup";
import FormControlLabel from "#mui/material/FormControlLabel";
import FormControl from "#mui/material/FormControl";
import FormLabel from "#mui/material/FormLabel";
import FormGroup from "#mui/material/FormGroup";
import Checkbox from "#mui/material/Checkbox";
const Form: FC = (): ReactElement => {
const {
register,
formState: { errors },
handleSubmit,
setValue,
} = useForm();
const onSubmit = async (data: any) => {
console.log(data);
axios
.post("http://localhost:3000/api/users", {
name: data.name,
email: data.email,
age: data.age,
form: data.form,
pattern: data.pattern,
gadgets: data.gadgets,
})
.then(function (response) {
console.log(response);
if (response.status === 201 || 200) {
setValue("name", "");
setValue("email", "");
setValue("age", "");
}
})
.catch(function (error) {
console.log(error);
});
};
return (
<Box
component="form"
onSubmit={handleSubmit(onSubmit)}
sx={{}}
noValidate
autoComplete="on"
>
<Box component="div" sx={{ margin: "30px 0 30px 10px" }}>
<Typography variant="body1">Datos Personales</Typography>
</Box>
<Box
component="div"
sx={{ m: 3, display: "flex", justifyContent: "space-around" }}
>
<TextField
{...register("name", { required: true })}
aria-invalid={errors.name ? "true" : "false"}
size="small"
id="name"
label="Nombre Completo"
variant="outlined"
name="name"
type="string"
sx={{ width: "40ch" }}
/>
{errors.name?.type === "required" && (
<p role="alert">Name is required</p>
)}
<TextField
{...register("email", { required: true })}
aria-invalid={errors.email ? "true" : "false"}
size="small"
id="email"
label="Email"
variant="outlined"
name="email"
type="email"
sx={{ width: "40ch" }}
/>
{errors.email?.type === "required" && (
<p role="alert">Email is required</p>
)}
<TextField
{...register("age", { required: true })}
aria-invalid={errors.age ? "true" : "false"}
size="small"
id="age"
label="Edad"
variant="outlined"
name="age"
type="number"
sx={{ width: "10ch" }}
/>
{errors.age?.type === "required" && <p role="alert">Age is required</p>}
</Box>
<Box
component="div"
sx={{
m: 10,
display: "flex",
flexDirection: "column",
justifyContent: "center",
}}
>
<FormControl>
<FormLabel id="demo-form-control-label-placement" sx={{ mb: 3 }}>
Por favor Elija la Forma
</FormLabel>
<RadioGroup
row
aria-labelledby="demo-form-control-label-placement"
name="form"
defaultValue="top"
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
}}
>
<FormControlLabel
{...register("form")}
value="form1"
control={<Radio />}
label="Forma 1"
labelPlacement="top"
/>
<FormControlLabel
{...register("form")}
value="form2"
control={<Radio />}
label="Forma 2"
labelPlacement="top"
/>
<FormControlLabel
{...register("form")}
value="form3"
control={<Radio />}
label="Forma 3"
labelPlacement="top"
/>
</RadioGroup>
</FormControl>
<FormControl>
<FormLabel
id="demo-form-control-label-placement"
sx={{ mb: 3, mt: 3 }}
>
Por favor Elija la Tela
</FormLabel>
<RadioGroup
row
aria-labelledby="demo-form-control-label-placement"
name="pattern"
defaultValue="top"
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
}}
>
<FormControlLabel
{...register("pattern")}
value="pattern1"
control={<Radio />}
label="Tela 1"
labelPlacement="top"
/>
<FormControlLabel
{...register("pattern")}
value="pattern2"
control={<Radio />}
label="Tela 2"
labelPlacement="top"
/>
<FormControlLabel
{...register("pattern")}
value="pattern3"
control={<Radio />}
label="Tela 3"
labelPlacement="top"
/>
</RadioGroup>
</FormControl>
{/* <FormControl>
<FormLabel
id="demo-form-control-label-placement"
sx={{ mb: 3, mt: 3 }}
>
Por favor Elija los Accesorios
</FormLabel>
<RadioGroup
row
aria-labelledby="demo-form-control-label-placement"
name="gadgets"
defaultValue="top"
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
}}
>
<FormControlLabel
{...register("gadgets")}
value="gadget1"
control={<Radio />}
label="Accesorio 1"
labelPlacement="top"
/>
<FormControlLabel
{...register("gadgets")}
value="gadget2"
control={<Radio />}
label="Accesorio 2"
labelPlacement="top"
/>
<FormControlLabel
{...register("gadgets")}
value="gadget3"
control={<Radio />}
label="Accesorio 3"
labelPlacement="top"
/>
</RadioGroup>
</FormControl> */}
<FormLabel id="demo-form-control-label-placement" sx={{ mb: 3, mt: 3 }}>
Por favor Elija los Accesorios
</FormLabel>
<FormGroup
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
}}
>
<FormControlLabel
{...register("gadgets")}
control={<Checkbox />}
label="Accesorio 1"
sx={{ mb: 3 }}
name="gadgets"
value="gadget1"
/>
<FormControlLabel
{...register("gadgets")}
control={<Checkbox />}
label="Accesorio 2"
sx={{ mb: 3 }}
name="gadgets"
value="gadget2"
/>
<FormControlLabel
{...register("gadgets")}
control={<Checkbox />}
label="Accesorio 3"
sx={{ mb: 3 }}
name="gadgets"
value="gadget3"
/>
</FormGroup>
</Box>
<Box
component="div"
sx={{ m: 10, display: "flex", justifyContent: "center" }}
>
<Button variant="contained" type="submit">
Enviar
</Button>
</Box>
</Box>
);
};
export default Form;
API Handler
import dbConnect from "../../../utils/dbConnect";
import User from "../../../models/User";
export default async function handler(req, res) {
const { method } = req;
await dbConnect();
switch (method) {
case "GET":
try {
const users = await User.find(
{}
); /* find all the data in our database */
res.status(200).json({ success: true, data: users });
} catch (error) {
res.status(400).json({ success: false });
}
break;
case "POST":
try {
const user = await User.create(
req.body
); /* create a new model in the database */
res.status(201).json({ success: true, data: user });
} catch (error) {
res.status(400).json({ success: false });
}
break;
default:
res.status(400).json({ success: false });
break;
}
}
LOGGED DATA
AXIOS ERROR
I tried reading Mongoose Docs, searching for videos on youtube. Several posts here in Stack Overflow and I cannot seem to get it.

How can we validate our form using formik

I am unable to validate the following form because of checkbox handling. I have to implement this type of thing in many of my form issue is same i am unable to handle the on change on some of that form to handle the checkbox.
import React, { useEffect } from "react";
import {
Grid,
Typography,
Button,
Box,
TextField,
FormControlLabel,
} from "#mui/material";
import { Formik, Form, Field, ErrorMessage } from "formik";
import axios from "axios";
import * as Yup from "yup";
import API from "../../../../../E2E/Axios.Utils";
const AddReport = ({
handleDialog,
update,
setUpdate,
setAlert,
setAlertContent,
setAlertType,
}) => {
const [tabData, setTabData] = React.useState([]);
const token = localStorage.getItem("token").toString();
const onSubmit = (values, props) => {
console.log("values", values);
const tabs = [];
values.tab_id.map((ele) => {
if (typeof ele === "string") {
tabs.push(Number(ele));
}
console.log("tabs", tabs);
return tabs;
});
const data = {
report_type_name: values.report_type_name,
description: values.description,
tab_id: tabs,
remember: false,
};
API.post("/app/secure/report_type/", data, {
headers: { Authorization: `Bearer ${token}` },
})
.then((res) => {
handleDialog();
setUpdate(update + 1);
setAlertContent(res.data.msg);
setAlertType("success");
setAlert(true);
})
.catch((err) => {
console.log(err);
if (err?.response?.status == 401) {
setAlertContent("Token is invalid or expired.");
setAlertType("error");
setAlert(true);
} else {
setAlertContent(`Error : Something went wrong.`);
setAlertType("error");
setAlert(true);
}
});
props.resetForm();
};
This API is used to get the tab details
const getTabData = () => {
API.get("/app/secure/my_tab/", {
headers: { Authorization: `Bearer ${token}` },
})
.then((res) => {
console.log("GetData", res);
setTabData(res.data.tab_list);
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getTabData();
}, []);
const initialValues = {
report_type_name: "",
description: "",
tab_id: [],
remember: false,
};
const AlphaNumeric = /^[a-zA-Z0-9](([_ -])?[a-zA-Z0-9]*)+$/;
const validationSchema = Yup.object().shape({
report_type_name: Yup.string()
.matches(AlphaNumeric, "Please enter valid report type name.")
.max(40, "Tab Name must be at most 40 characters.")
.required("This field is required."),
description: Yup.string()
.matches(AlphaNumeric, "Please enter valid description.")
.max(160, "Description must be at most 160 characters.")
.required("This field is required."),
});
return (
<Box>
<Typography
id="modal-modal-title"
variant="h6"
component="h2"
sx={{ marginBottom: "4%" }}
>
Add Report
</Typography>
<Box>
<Formik
initialValues={initialValues}
onSubmit={onSubmit}
validationSchema={validationSchema}
>
{(props) => (
<Form noValidate>
<Field
as={TextField}
name="report_type_name"
label="Name"
placeholder="Name"
fullWidth
error={
props.errors.report_type_name &&
props.touched.report_type_name
}
size="small"
helperText={<ErrorMessage name="report_type_name" />}
required
sx={{ marginBottom: "4%" }}
/>
<Field
as={TextField}
name="description"
label="Description"
placeholder="Description"
fullWidth
error={props.errors.description && props.touched.description}
size="small"
helperText={<ErrorMessage name="description" />}
required
sx={{ marginBottom: "4%" }}
/>
<Typography variant="subtitle1" sx={{ textAlign: "left" }}>
<span style={{ fontWeight: "bold" }}>Tabs</span>
</Typography>
<Grid container>
{tabData.map((item) => {
return (
<Grid
item
xl={4}
lg={4}
md={4}
sm={12}
xs={12}
key={item.tab_id}
style={{
display: "flex",
width: "150px",
}}
>
<FormControlLabel
control={
<Field
name="tab_id"
label={item.tab_name}
value={item.tab_id.toString()}
style={{ margin: "8px" }}
type="checkbox"
/>
}
/>
<div style={{ margin: "8px" }}>{item.tab_name}</div>
</Grid>
);
})}
</Grid>
<Grid
container
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
gap: "1rem",
mt: 2,
}}
>
<Grid item>
<Button onClick={handleDialog}>Disagree</Button>
</Grid>
<Grid item>
<Button
type="submit"
variant="contained"
sx={{
padding: "10px",
borderRadius: "20px",
width: "101px",
height: "36px",
}}
>
Save
</Button>
</Grid>
</Grid>
</Form>
)}
</Formik>
</Box>
</Box>
);
};
export default AddReport;
I have put all the code in this. facing same issue.
I dont know from where the error is coming.

Validation of textbox message:- (fill the value)

I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
I dont know how to validate the textbox in this so can anyone do for one textbox other all box i will do on myself i watch videos but i am not geatting it.....
import React, { useState } from 'react'
import './AddRecipes.css'
import axios from 'axios'
function AddRecipes() {
const [state, setstate] = useState({
label: '',
source: '',
dietlabels: [],
healthlabels: [],
cuisineType: [],
ingredients: [],
mealType: [],
makingDescription: '',
recipeImage: null
})
state={
dietlabels= " This is empty fild",
healthlabels= "",
cuisineType ="",
ingredients= "",
mealType= ""
};
const onFormSubmit = async (e) => {
e.preventDefault()
console.log(state.ingredients)
try {
const fd = new FormData()
fd.append('recipeImage', state.recipeImage, state.recipeImage.name)
fd.append('label', state.label)
fd.append('source', state.source)
fd.append('dietlabels', JSON.stringify(state.dietlabels))
fd.append('healthlabels', JSON.stringify(state.healthlabels))
fd.append('ingredients', JSON.stringify(state.ingredients))
fd.append('cuisineType', JSON.stringify(state.cuisineType))
fd.append('mealType', JSON.stringify(state.mealType))
fd.append('makingDescription', state.makingDescription)
// console.log(fd)
const { data: response } = await axios.post(
'http://localhost:8000/recipe',
fd
)
console.log('api response' + response)
} catch (error) {
console.log(error)
}
}
const [arrayState, arraySetSate] = useState({
dietlabels: '',
healthlabels: '',
cuisineType: '',
ingredients: { text: '', weight: '' },
mealType: ''
})
const subIngredientStatePush = (event) => {
let replica = { ...arrayState }
replica.ingredients[event.target.name] = event.target.value
arraySetSate(replica)
}
//string type field data handling
const stringTypeFieldDataHandler = (event) => {
let replicateState = { ...state }
replicateState[event.target.name] = event.target.value
setstate(replicateState)
}
//image file handling
const imageUploadFileHandler = (event) => {
let replicateState = { ...state }
replicateState['recipeImage'] = event.target.files[0]
setstate(replicateState)
}
//array elements data handling
const arrayElementSeparateStateHandler = (event) => {
let repilica = { ...arrayState }
repilica[event.target.name] = event.target.value
arraySetSate(repilica)
}
const addDietLabels = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.dietlabels.push(arrayState.dietlabels)
setstate(replica)
arrayreplica.dietlabels = ''
arraySetSate(arrayreplica)
}
const newlable =()=>{
}
const addHealthLables = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.healthlabels.push(arrayState.healthlabels)
setstate(replica)
arrayreplica.healthlabels = ''
arraySetSate(arrayreplica)
}
const addcuisineType = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.cuisineType.push(arrayState.cuisineType)
setstate(replica)
arrayreplica.cuisineType = ''
arraySetSate(arrayreplica)
}
const addmealType = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
replica.mealType.push(arrayState.mealType)
setstate(replica)
arrayreplica.mealType = ''
arraySetSate(arrayreplica)
}
const AddingredientsClick = () => {
let replica = { ...state }
let arrayreplica = { ...arrayState }
let ingredientObj = {
text: arrayState.ingredients.text,
weight: arrayState.ingredients.weight
}
replica.ingredients.push(ingredientObj)
setstate(replica)
arrayreplica.ingredients = { text: '', weight: '' }
arraySetSate(arrayreplica)
}
return (
<div className="recipeForm container">
<form
style={{
display: 'flex',
flexDirection: 'column',
width: '70%',
alignItems: 'center'
}}
>
<label className="addrecipe-labels" htmlFor="label">
Enter Recipe Name
</label>
<input
type="text"
id="label"
name="label"
placeholder="recipe name"
className="inputs"
value={state.label}
onChange={stringTypeFieldDataHandler}
/>
<br />
<label className="addrecipe-labels" htmlFor="source">
Recipe Source
</label>
<input
type="text"
id="source"
name="source"
placeholder="enter source"
value={state.source}
onChange={stringTypeFieldDataHandler}
className="inputs"
/>
{/* <label className="addrecipe-labels" htmlFor="url">
URL
</label>
<input
type="text"
id="url"
name="url"
placeholder="paste url"
className="inputs"
/> */}
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="dietlabels">
diet labels
</label>
<input
type="text"
id="dietlabels"
name="dietlabels"
onChange={arrayElementSeparateStateHandler}
onChange={newlable}
value={arrayState.dietlabels}
placeholder="type labels"
className="inputs"
/>
<div>{this.state.nameError}</div>
<button
style={{ width: '40px' }}
type="button"
onClick={addDietLabels}
>
Add
</button>
<p>{String(state.dietlabels)}</p>
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="healthlabels">
Health labels
</label>
<input
type="text"
value={arrayState.healthlabels}
onChange={arrayElementSeparateStateHandler}
id="healthlabels"
name="healthlabels"
placeholder="health lables"
className="inputs"
/>
<button
style={{ width: '40px' }}
type="button"
onClick={addHealthLables}
>
Add
</button>
{String(state.healthlabels)}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="cuisineType">
cuisine type
</label>
<input
type="text"
id="cuisineType"
value={arrayState.cuisineType}
onChange={arrayElementSeparateStateHandler}
name="cuisineType"
placeholder="add cautions"
className="inputs"
/>
<button
style={{ width: '40px' }}
type="button"
onClick={addcuisineType}
>
Add
</button>
{String(state.cuisineType)}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="mealtype">
meal type
</label>
<input
type="text"
id="mealtype"
name="mealType"
value={arrayState.mealType}
onChange={arrayElementSeparateStateHandler}
placeholder="add cautions"
className="inputs"
/>
<button style={{ width: '40px' }} type="button" onClick={addmealType}>
Add
</button>
{String(state.mealType)}
</div>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
margin: '5px 5px'
}}
>
<label className="addrecipe-labels" htmlFor="ingredients">
ingredients
</label>
<input
type="text"
id="ingredients"
name="text"
value={arrayState.ingredients.text}
placeholder="ingredient"
className="inputs"
onChange={subIngredientStatePush}
style={{ margin: '0 5px' }}
/>
<input
type="text"
id="quantity"
name="weight"
value={arrayState.ingredients.weight}
onChange={subIngredientStatePush}
placeholder="quantity"
className="inputs"
/>
<button
style={{ width: '50px', marginLeft: '7px' }}
type="button"
onClick={AddingredientsClick}
>
Add
</button>
{JSON.stringify(state.ingredients)}
</div>
{/*
<label className="addrecipe-labels" htmlFor="country">
Country
</label>
<select id="country" name="country" className="inputs">
<option value="australia">Australia</option>
<option value="canada">Canada</option>
<option value="usa">USA</option>
</select> */}
<label className="addrecipe-labels" htmlFor="recipe-description">
Recipe description
</label>
<textarea
id="recipe-description"
name="makingDescription"
value={state.makingDescription}
onChange={stringTypeFieldDataHandler}
placeholder="Write something.."
style={{ height: '200px' }}
className="inputs"
></textarea>
<div style={{ margin: '15px 0' }}>
<label className="addrecipe-labels" htmlFor="recipeImage">
Add recipe image
</label>
<input
type="file"
name="recipeImage"
onChange={imageUploadFileHandler}
id="recipeImage"
/>
</div>
<input
type="submit"
value="Submit"
className="inputs submit"
onClick={onFormSubmit}
/>
</form>
</div>
)
}
export default AddRecipes
You have a couple of mistakes within your code but I'll focus on your question.
To validate, you add the validation logic either to the onChange or onSubmit callback.
onChange callback example
const subIngredientStatePush = ({ target: { name, value }}) => {
// validate
if (name === "text" && value.length > 10) {
setError((errors) => ({ ...errors, [name]: "too long" });
}
//... etc
// update state
const replica = { ...arrayState };
replica.ingredients = { ...replica.ingredients }; // need to copy this state as well
replica.ingredients[name] = value
arraySetSate(replica)
}

How to fetch email id from url?

I have created a formik form in which initial values are fetched from the URL. I am trying to fetch the email id and company name from the URL. I am using react-hooks to fetch data with useEffect. I have tried for email but have not been able to fetch
For example URL = 'https://abc.xyz.com/?abcxyz#gmail.com&abccampaign=email%data%abcpvtltd%'
Code:
// #ts-ignore
import React, { useState, useEffect } from 'react';
import { Formik, Form, Field } from 'formik';
import { Typography, Button, Grid } from '#material-ui/core';
import * as Yup from 'yup';
import { MyInput } from './comman/MyInput';
import { Textarea } from './comman/Textarea';
import { Event } from '../Tracking/Event';
const contactSchema = Yup.object().shape({
name: Yup.string().required('Please Enter Your Name'),
email: Yup.string()
.email('Please enter a valid email address')
.required('Please enter an email address'),
number: Yup.string()
.min(10, 'Must be 10 digit.')
.max(10, 'Must be 10 digit.'),
});
export default function ContactUs(props: any) {
const [state, setState] = useState({
msg: '',
});
const [selectedemail, setEmail] = useState({
text: '',
});
useEffect(() => {
const findemail = window.location.href;
//const findemail =
// 'https://abc.xyz.com/?abcxyz#gmail.com';
console.log('url', findemail);
const finalemail = findemail.split('?');
//const emails = finalemail[1].split('&');
const email = finalemail[1].toString();
console.log(email);
console.log(setEmail({ text: email }));
console.log(selectedemail.text);
}, []);
return (
<div>
<img
src="public/abc.png"
width="200"
className="d-inline-block"
alt="Viser"
style={{
marginTop: '2em',
marginBottom: '2em',
float: 'right',
}}
/>
<Formik
initialValues={{
name: '',
email: selectedemail.text,
number: '',
companyname: '',
message: '',
}}
validationSchema={contactSchema}
onSubmit={(values, { resetForm }) => {
const data = {
name: values.name,
email: values.email,
number: values.number,
companyname: values.companyname,
message: values.message,
formtype: 'Contactus',
};
console.log(data);
const request = new Request(
`${process.env.REACT_APP_PRODUCTION_EMAILCONTACTUS_API}`,
{
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json',
}),
body: JSON.stringify(data),
},
);
fetch(request)
.then((res) => res.json())
.then((data) => {
if (
data.message ===
'Thanks!'
) {
setState({
msg: data.message,
});
} else {
console.log('error');
}
});
resetForm();
}}
>
{({ errors, touched }) => (
<Grid container>
<Grid item xs={12}>
<Typography
variant="body1"
style={{
marginTop: '1em',
fontFamily: 'roboto',
fontSize: '1.3rem',
color: '#2F4858',
}}
>
To know more please submit your information, and one of our
expert advisors will get in touch within 24 hours!{' '}
</Typography>
<br />
<Form>
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '0.5em',
}}
>
Full Name
</Typography>
<Field
id="outlined-multiline-flexible"
type="text"
name="name"
placeholder="Name"
component={MyInput}
/>
<br />
{errors.name && touched.name ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.name}
</div>
) : null}
<Typography
variant="h6"
style={{ fontFamily: 'roboto', marginTop: '1em' }}
>
Email
</Typography>
<Field
type="email"
name="email"
placeholder="Email"
values={props.text}
style={{ color: 'white' }}
component={MyInput}
/>{' '}
<br />
{errors.email && touched.email ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.email}
</div>
) : null}
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
Mobile Number (Optional)
</Typography>
<Field
name="number"
placeholder="Contact Number"
component={MyInput}
// label="Contact Number"
/>
<br />
{errors.number && touched.number ? (
<div className="text-danger" style={{ color: 'red' }}>
{errors.number}
</div>
) : null}
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
Company Name (Optional)
</Typography>
<Field
name="companyname"
placeholder="Company Name"
// label="Contact Number"
component={MyInput}
/>
<br />
<Typography
variant="h6"
style={{
fontFamily: 'roboto',
color: '#2F4858',
marginTop: '1em',
}}
>
How can we help? (Optional)
</Typography>
<Field
id="outlined-multiline-static"
name="message"
placeholder="Your question about our services"
label="How can we help?"
component={Textarea}
/>
<br />
<br />
<Button
type="submit"
variant="contained"
style={{
background: '#F79924',
color: 'white',
fontFamily: 'roboto',
fontSize: '1rem',
}}
>
Submit{' '}
</Button>
<br />
{state.msg && (
<Typography
variant="h6"
style={{
color: '#4BB543',
fontFamily: 'roboto-medium',
marginTop: '1em',
}}
>
{' '}
{state.msg}{' '}
</Typography>
)}
</Form>
</Grid>
</Grid>
)}
</Formik>
</div>
);
}
I think you are almost there.
const email = findemail.split('?')[1].split('&')[0]
returns abcxyz#gmail.com.
Is this what you are expecting ?
Note: the above assumes that findemail will always have an email after .com/?. In case it will be random, then i am not sure if you can get the email. Either we need to have standard input or write multiple switch case statements

Resources