Issue with form submit using Reactjs - javascript

I am working on Reactjs(Nextjs),Trying to submit form but unable to submit form,How can i submit form data ? Here is my current code
export default function Home() {
const checklogin = async (e:any) => {
e.preventDefault();
alert("Its working");
}
<form className="forms-sample" onSubmit={checklogin}>
<div className="form-group first">
<label htmlFor="username">Username</label>
<input
type="text"
className="form-control"
placeholder="your-email#gmail.com"
id="username"
/>
</div>
<div className="form-group last mb-3">
<label htmlFor="password">Password</label>
<input
type="password"
className="form-control"
placeholder="Your Password"
id="password"
/>
</div>
<input
type="submit"
name="submit"
defaultValue="Log In"
className="btn btn-block btn-primary"
/>
</form>

1. controlled form
import React from 'react';
export default function Home() {
const INITIAL_DATA = {
username: '',
password: '',
};
const [formData, setFormData] = React.useState(INITIAL_DATA);
const checklogin = async (e) => {
e.preventDefault();
console.log(formData); // * PROCESS FORMDATA ON SUBMIT
alert('Its working');
setFormData(INITIAL_DATA); // * CLEAR DATA AFTER SUBMIT
};
function handleOnChangeInput(event) {
const name = event?.target?.name;
const value = event?.target?.value;
setFormData((prev) => ({
...prev,
[name]: value,
}));
}
return (
<form className='forms-sample' onSubmit={checklogin}>
<div className='form-group first'>
<label htmlFor='username'>Username</label>
<input
type='text'
className='form-control'
placeholder='your-email#gmail.com'
id='username'
onChange={handleOnChangeInput}
value={formData?.username}
/>
</div>
<div className='form-group last mb-3'>
<label htmlFor='password'>Password</label>
<input
type='password'
className='form-control'
placeholder='Your Password'
id='password'
onChange={handleOnChangeInput}
value={formData?.password}
/>
</div>
<input
type='submit'
name='submit'
defaultValue='Log In'
className='btn btn-block btn-primary'
/>
</form>
);
}
2. Uncontrolled form
import React from 'react';
export default function Home() {
const formRef = React.useRef(null);
const checklogin = async (event) => {
event.preventDefault();
alert('Its working');
// * Get form enteries
const formData = new FormData(formRef?.current);
const formEnteries = Object.fromEntries(formData?.entries());
console.log(formEnteries); // * PROCESS FORMENTERIES ON SUBMIT
// * Clear form fields here
const formCurrentTarget = event?.currentTarget;
formCurrentTarget?.reset();
};
return (
<form className='forms-sample' onSubmit={checklogin} ref={formRef}>
<div className='form-group first'>
<label htmlFor='username'>Username</label>
<input
type='text'
className='form-control'
placeholder='your-email#gmail.com'
id='username'
name='username'
/>
</div>
<div className='form-group last mb-3'>
<label htmlFor='password'>Password</label>
<input
type='password'
className='form-control'
placeholder='Your Password'
id='password'
name='password'
/>
</div>
<input
type='submit'
name='submit'
defaultValue='Log In'
className='btn btn-block btn-primary'
/>
</form>
);
}
Read more about controlled and uncontrolled components here - Link

Related

Why is my useState not working (error in console)?

I have react components:
WelcomePage.jsx
import { useState } from "react";
import SignUpPage from "./SignUpPage";
function WelcomePage() {
const [signUp, toSignUp] = useState(false);
function signUpClick() {
toSignUp(true);
}
return (
<div>
{signUp ? (
<SignUpPage isOpen={toSignUp} back={toSignUp} />
) : (
<div className="Welcome_page__container animate__animated animate__fadeIn">
<h1 className="Welcome_page__title">Welcome to Hotel Review </h1>
<h3 className="Welcome_page__subtitle">Sign in :</h3>
<div className="Welcome_page__wrapper">
<label className="Welcome_page__input-title" htmlFor="welcome_mail">
E-mail:
</label>
<input
value={inputEmail}
onInput={(e) => setInputEmail(e.target.value)}
className="Welcome_page__input"
id="welcome_mail"
type="email"
placeholder="Your e-mail..."
/>
<label className="Welcome_page__input-title" htmlFor="welcome_pass">
Password:
</label>
<input
value={inputPass}
onInput={(e) => setInputPass(e.target.value)}
className="Welcome_page__input"
id="welcome_pass"
type="password"
placeholder="Your password..."
/>
<button className="Welcome_page__btn" onClick={loginClick}>
Login
</button>
<button className="Welcome_page__btn" onClick={signUpClick}>
Sign Up
</button>
</div>
</div>
)}
</div>
);
}
export default WelcomePage;
SignUpPage.jsx
import { useState } from "react";
import { Hotels } from "./Hotels";
function SignUpPage(props) {
const { isOpen, back } = props;
const [isSignUp, setSignUp] = useState(false);
return (
<div>
{isSignUp ? (
<Hotels />
) : (
<div className="Welcome_page__container animate__animated animate__fadeIn">
<button onClick={back(false)}>Back...</button>
<h1 className="Welcome_page__title">Welcome to Hotel Review </h1>
<h3 className="Welcome_page__subtitle">Sign up :</h3>
<div className="Welcome_page__wrapper">
<label className="Welcome_page__input-title" htmlFor="welcome_mail">
E-mail:
</label>
<input
value={inputEmail}
onInput={(e) => setInputEmail(e.target.value)}
className="Welcome_page__input"
id="welcome_mail"
type="email"
placeholder="Your e-mail..."
/>
<label className="Welcome_page__input-title" htmlFor="welcome_pass">
Password:
</label>
<input
value={inputPass}
onInput={(e) => setInputPass(e.target.value)}
className="Welcome_page__input"
id="welcome_pass"
type="password"
placeholder="Your password..."
/>
<label
className="Welcome_page__input-title"
htmlFor="welcome_pass"
></label>
<input
value={inputPass2}
onInput={(e) => setInputPass2(e.target.value)}
className="Welcome_page__input"
id="welcome_pass_repeat"
type="password"
placeholder="Repeat password..."
/>
<button className="Welcome_page__btn_2">Sign Up</button>
</div>
</div>
)}
</div>
);
}
export default SignUpPage;
When I click on Back in the SignUpPage component I get an error -
It is necessary that after clicking on back there is a return to WelcomePage.jsx
Maybe I'm not using or passing useState in SignUpPage.jsx
I read about the error on the Internet, they say that you need to useEffect (), but I doubt that this is the problem ...
Here is the error:
<button onClick={back(false)}>Back...</button>
You are basically calling the back function immediately causing the WelcomePage component to update while rendering the SignUpPage component.
You should do this:
<button onClick={() => back(false)}>Back...</button>
By doing this you are going to execute the back function only when you click on the button

Form validation react

i want to validate my form by checking if all the fields are filled. I am quite new to react. Any suggestions? I have got the states ready, but i am pretty much stuck. Thank you in advance for your replies. I appreciate it
my code:
const [fields, setFields] = useState({
name: '',
email: '',
subject: '',
msg: '',
});
const handleSubmit = (event) => {
emailjs.sendForm().then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
alert('form submitted');
event.target.reset();
event.preventDefault();
};
<form onSubmit={handleSubmit}>
<div className={styles.firstInputs}>
<div>
<label>name</label>
<br />
<input
type='text'
refs='name'
name='name'
placeholder='your name'
></input>
</div>
<div>
<label>email</label>
<br />
<input type='email' name='email' placeholder='email'></input>
</div>
</div>
<label>subject</label>
<br />
<input
type='text'
name='subject'
placeholder='subject'
className={styles.subject}
></input>{' '}
<br />
<label>message</label> <br />
<textarea placeholder='your message' name='message'></textarea>
<br />
<button type='submit' className={styles.sendForm}>
SUBMIT
</button>
</form>;
You are not using your state correctly there.
Set the values of the fields to what is in the state, then change the state when the fields change.
Don't forget you can just add the required attribute to your HTML element to make sure it gets some kind of value.
Then you just validate the state before submission.
Don't just fall back on packages all the time as people suggest here. As you say, you are new to React so, learn to set things up manually (which is basically less work for small forms). Once you understand that, then consider if having another dependency is really saving you time.
See sample code below in action here: https://codesandbox.io/s/form-validation-pbbf1
import { useState } from "react";
import "./styles.css";
const defaultFields = { name: "", email: "", subject: "", message: "" };
export default function App() {
const [fields, setFields] = useState(defaultFields);
const handleSubmit = (event) => {
// Stop form from resetting
event.preventDefault();
// Check fields
if (fields.name.length < 2) {
return alert("Name should be greater than 1 character.");
}
// etc...
// Send off data
/*
emailjs.sendForm().then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
*/
// I would probably put these two
// lines inside the then block above.
setFields(defaultFields);
alert("form submitted");
};
const handleFieldChange = (e) => {
const { name, value } = e.target;
setFields((previousFields) => ({ ...previousFields, [name]: value }));
};
return (
<form onSubmit={handleSubmit}>
{/* NAME */}
<div>
<label>name</label>
<br />
<input
type="text"
name="name"
placeholder="your name"
value={fields.name}
required
onChange={handleFieldChange}
></input>
</div>
{/* EMAIL */}
<div>
<label>email</label>
<br />
<input
type="email"
name="email"
placeholder="email"
value={fields.email}
required
onChange={handleFieldChange}
></input>
</div>
{/* SUBJECT */}
<div>
<label>subject</label>
<br />
<input
type="text"
name="subject"
placeholder="subject"
value={fields.subject}
required
onChange={handleFieldChange}
></input>{" "}
<br />
</div>
{/* MESSAGE */}
<div>
<label>message</label> <br />
<textarea
placeholder="your message"
name="message"
value={fields.message}
required
onChange={handleFieldChange}
></textarea>
</div>
<button type="submit">SUBMIT</button>
</form>
);
}

reactjs clear file input field after submit

I'm trying to delete my file input field data from e.target but i need the rest of the e.target data to send to emailjs.
The problem is when user uploads a file in my form, the file is most of the time bigger than 50kb and this is the limit for my account on emailjs.
I don't need to send my file to emailjs but i need it to just be stored in my database.
I have tried to clear the form field before sending it to emailjs
with fileUpload.current.value = ""; but the data is still actief in
e.target.
This is e.target Data. i need the data to stay in this way in e.target to send to emailjs
<form class="Grade_inputForm__1lbhQ" autocomplete="off">
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="text" name="name" required="" class="Grade_input__22PTE" placeholder="Name*" maxlength="10">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="email" required="" name="email" class="Grade_input__22PTE" placeholder="Email*">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="text" name="Address" required="" class="Grade_input__22PTE" placeholder="Address*">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="tel" name="phone" class="Grade_input__22PTE" placeholder="Phone">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="file" class="Grade_input__22PTE" name="5349366.jpg">
</div>
<div class="Grade_textarea__YR0na css-vurnku">
<textarea name="cards" required="" class="Grade_input__22PTE">
</textarea>
</div>
<div class="Grade_textarea__YR0na css-vurnku">
<textarea name="message" class="Grade_input__22PTE" placeholder="Message">
</textarea>
</div>
<br>
<input type="submit" value="Send" class="Grade_btn__1QKUn">
</form>
how can i delete my file from e.target ?
import React, { useRef, useState } from "react";
import { jsx, Box } from "theme-ui";
import style from "../../style/Grade.module.css";
import { db, storage } from "../components/config/config";
import emailjs from "emailjs-com";
export default function GradeCards() {
const [file, setFile] = useState();
const name = useRef("");
const email = useRef("");
const Addres = useRef("");
const phone = useRef("");
const cards = useRef("");
const message = useRef("");
const fileUpload = useRef("");
const sendEmail = (e) => {
e.preventDefault();
//sending data to emailjs with e.target
emailjs
.sendForm(
"service account",
"template name",
e.target,
"user_id"
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
};
const sendDataToDb = (e) => {
// sendEmail(e);
e.preventDefault();
e.persist(); // this is test when i use sendEmail() in .then()
const formData = new FormData(e.target);
const obj = {};
for (let [key, value] of formData.entries()) {
obj[key] = value;
}
if (file !== null) {
storage
.ref(`/files/${Date.now() + "-" + file.name}`)
.put(file)
.then(() => console.log("Succes"));
}
//this don't help in deleting data from e.target
delete obj[file.name];
db.collection("collectionName")
.add(obj)
.then(() => {
fileUpload.current.value = "";
})
.then(() => {
//test if the data is deleted her.But its still actief in e.target
console.log(e.target);
sendEmail(e);
})
.then(() => {
name.current.value = "";
email.current.value = "";
Addres.current.value = "";
phone.current.value = "";
cards.current.value = "";
message.current.value = "";
console.log("done sending");
});
};
return (
<section>
<Box className={style.container}>
<Box className={style.form}>
<Box className={style.contact_form}>
<form
onSubmit={(e) => sendDataToDb(e)}
className={style.inputForm}
autoComplete="off"
>
<Box className={style.input_container}>
<input
ref={name}
type="text"
name="name"
required
className={style.input}
placeholder="Name*"
maxLength="10"
/>
</Box>
<Box className={style.input_container}>
<input
ref={email}
type="email"
required
name="email"
className={style.input}
placeholder="Email*"
/>
</Box>
<Box className={style.input_container}>
<input
ref={Addres}
type="text"
name="Address"
required
className={style.input}
placeholder="Address*"
/>
</Box>
<Box className={style.input_container}>
<input
ref={phone}
type="tel"
name="phone"
className={style.input}
placeholder="Phone"
/>
</Box>
<Box className={style.input_container}>
<input
ref={fileUpload}
type="file"
name={file?.name}
onChange={(e) => {
setFile(e.target.files[0]);
}}
className={style.input}
/>
</Box>
<Box className={(style.input_container, style.textarea)}>
<textarea
ref={cards}
name="cards"
required
className={style.input}
></textarea>
</Box>
<Box className={(style.input_container, style.textarea)}>
<textarea
ref={message}
name="message"
className={style.input}
placeholder="Message"
></textarea>
</Box>
<br />
<input type="submit" value="Send" className={style.btn} />
</form>
</Box>
</Box>
</Box>
</section>
);
}
I don't know how you can set it here, but in general, if you have an input of type file and with name let's say image2, then you can do the following:
e.target["image2"].value = [];
this will empty the input.
See this sandbox
If you comment out the previous line of code, it will display the full details of the chosen file.
If you have this line there, it will display the object as it was never assigned a file from your disk.

Cannot read property 'value' of null in ReactJS

I've been trying to console.log these 2 inputs, but can't seem to figure it out, can anyone tell me what I've done wrong?
I keep getting the Cannot read property 'value' of null error
function printInputs() {
let username = document.getElementById('user').value
let password = document.getElementById('pass').value
console.log(username);
console.log(password);
}
function App() {
return (
<div className="App">
<h1>Log In</h1>
<h1>{code}</h1>
<form>
<input className='userInput' id='user' type='text' placeholder='username' /><br />
<input className='userInput' id='pass' type='password' placeholder='password' /><br />
<input className='userSubmit' type='submit' value='Log In' onSubmit={printInputs()} />
</form>
</div>
);
}
onSubmit={printInputs()}
You are trying to call printInputs immediately (before the render function has returned anything so before the inputs are in the page).
You need to pass a function to onSubmit:
onSubmit={printInputs}
That said, this is not the approach to take for getting data from forms in React. See the Forms section of the React guide for the right approach.
The way to write forms in react. Working example demo
function App() {
const [state, setState] = React.useState({ username: "", password: "" });
const handleSubmit = e => {
e.preventDefault();
console.log(state);
};
const handleChange = e => {
setState({
...state,
[e.target.name]: e.target.value
});
};
return (
<div className="App">
<h1>Log In</h1>
<form onSubmit={handleSubmit}>
<input
className="userInput"
name="username"
type="text"
placeholder="username"
onChange={handleChange}
/>
<br />
<input
className="userInput"
name="password"
type="password"
placeholder="password"
onChange={handleChange}
/>
<br />
<input className="userSubmit" type="submit" value="Log In" />
</form>
</div>
);
}
in the first never use real dom to manipulate the dom in
React ,use a state to get de value and the onSumbit is used in Form tag
import React, { useState } from "React";
const App = () => {
const [userName, setUserName] = useState("");
const [password, setPassword] = useState("");
const printInputs = () => {
console.log(userName);
console.log(password);
};
return (
<div className="App">
<h1>Log In</h1>
<form onSubmit={printInputs}>
<input
className="userInput"
id="user"
type="text"
placeholder="username"
onChange={event => setUserName(event.target.value)}
/>
<br />
<input
className="userInput"
id="pass"
type="password"
placeholder="password"
onChange={event => setPassword(event.target.value)}
/>
<br />
<input
className="userSubmit"
type="submit"
value="Log In"/>
</form>
</div>
);
};
export default App;

Not changing values of form reactjs

I have a form in which I am generating form fields dynamically . Now Issue is fields which are not dynamically generated are getting input and those field which are dynamically generated are not taking input in fields. name='name' and name='age' fields are not getting input I cant insert data in them . while first two fields owner and description are working fine
import React from "react";
class Form extends React.Component {
state = {
cats: [{ name: "", age: "" }],
owner: "",
description: ""
};
handleChange = e => {
alert('inot');
if (["name", "age"].includes(e.target.className)) {
let cats = [...this.state.cats];
cats[e.target.dataset.id][
e.target.className
] = e.target.value.toUpperCase();
this.setState({ cats }, () => console.log(this.state.cats));
} else {
this.setState({ [e.target.name]: e.target.value.toUpperCase() });
}
};
addCat = e => {
this.setState(prevState => ({
cats: [...prevState.cats, { name: "", age: "" }]
}));
};
handleSubmit = e => {
e.preventDefault();
};
handleClick = e => document.getElementById(e.target.id).remove();
// changeOption =(e) => {
// this.setState.cats(e.target.value);
// }
render() {
let { owner, description, cats } = this.state;
return (
<form onSubmit={this.handleSubmit} onChange={this.handleChange}>
<div className='row mt-5'>
<div className='col-md-12 mb-5'>
<h3 className='text-center text-primary'>Create Products Option</h3>
</div>
<div className='col-md-3'></div>
<div className='col-md-3'>
<label htmlFor='name'>
<b>Owner</b>
</label>
<input
type='text'
className='form-control'
name='owner'
id='owner'
value={owner}
/>
</div>
<div className='col-md-3'>
<label htmlFor='description'>
<b>Description</b>
</label>
<input
type='text'
className='form-control'
name='description'
id='description'
value={description}
/>
<button
className='btn btn-success rounded-0 w-25 float-right mt-2 shadow-none'
onClick={this.addCat}
>
+
</button>
</div>
<div className='col-md-3'></div>
</div>
{cats.map((val, idx) => {
let catId = `cat-${idx}`,
ageId = `age-${idx}`;
return (
<form onSubmit={this.handleSubmit} onChange={this.handleChange}>
<div id={ageId} key={idx}>
<div className='row mt-5'>
<div className='col-md-3'></div>
<div className='col-md-3'>
<label htmlFor={catId}>
<b>{`Cat #${idx + 1}`}</b>
</label>
<input
type='text'
name='name'
data-id={idx}
id={catId}
value={cats[idx].name}
className='name form-control'
/>
</div>
<div className='col-md-3'>
<label htmlFor={ageId}>
<b>Age</b>
</label>
<input
type='text'
name='age'
data-id={idx}
id={ageId}
value={cats[idx].age}
className='age form-control'
/>
<button
className='btn btn-success rounded-0 w-25 float-right mt-2 shadow-none'
onClick={this.addCat}
>
+
</button>
<input
type='button'
name={ageId}
data-id={idx}
id={ageId}
value={"-"}
className='age float-right mt-2 mr-3 btn btn-danger w-25 rounded-0 w-25 shadow-none'
onClick={this.handleClick}
/>
</div>
<div className='col-md-3'></div>
</div>
</div>
</form>
);
})}
<div className='row mt-3'>
<div className='col-md-3'></div>
<div className='col-md-3'>
<label htmlFor='name'>
<b>Min Selection</b>
</label>
<input
type='text'
className='form-control'
name='min'
id='min'
value={""}
/>
</div>
<div className='col-md-3'>
<label htmlFor='description'>
<b>Max Selection</b>
</label>
<input
type='text'
className='form-control'
name='max'
id='max'
value={""}
/>
<input
className='float-right btn btn-success mt-3'
type='submit'
value='Submit'
/>
{/* <button className="float-right" onClick={this.addCat}>Add new cat</button> */}
</div>
<div className='col-md-3'></div>
</div>
</form>
);
}
}
export default Form;
Codesandbox here. Looks like you should be seeing some errors in your console that might provide some explanation:
Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
Detailed answer
Working Sandbox here. There are a few things wrong here:
Your handleChange function needs to change
Your function is looking at className which won't work. Your inputs return form-control name for example. Instead try using the element's name.
Updated function:
handleChange = e => {
if (["name", "age"].includes(e.target.name)) {
let cats = [...this.state.cats];
cats[e.target.dataset.id][e.target.name] = e.target.value.toUpperCase();
this.setState({ cats }, () => console.log(this.state.cats));
} else {
this.setState({ [e.target.name]: e.target.value.toUpperCase() });
}
};
Aside
Do not render <form> elements in other <form> elements.
Don't do this. You don't need another form here. Just remove that.
// Line 76-80:
{cats.map((val, idx) => {
let catId = `cat-${idx}`,
ageId = `age-${idx}`;
return (
<form onSubmit={this.handleSubmit} onChange={this.handleChange}>
// ...

Categories

Resources