ReactJS: onSubmit depending on API response close modal box - javascript

Why the state value is not updating after the form submit ? As i need to close the model after the successfully login.
I have tried to check with this useCallback hook but not able to close the dialogbox.
function HeaderComponent(props) {
const [loggedIn, setIsLoggedIn] = useState(false);
const [show, setShow] = useState(false);
const [modelShow, setmodelShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const registerUser = async event => {
event.preventDefault()
axios.post(`{api_url}/user/login`, data, {
})
.then((response) => {
localStorage.setItem("token", userDetails.auth_token);
setmodelShow(true)
router.push('/')
})
.catch((error)) => {
setmodelShow(false)
}
}
return (
<Modal show={show} onHide={handleClose} className={show ? 'intro' : ''}>
<form onSubmit={registerUser}>
<input type="email" />
<div className="form-group">
{
modelShow ? <input type="submit" name="" value="Login" onClick={handleClose}/>
: <input type="submit" name="" value="Login" />
}
</div>
</form>
</Model>
)
}
export default React.memo(HeaderComponent);

There are needs a little modification in your code like
return ( !modelShow ? <Modal show={show} onHide={handleClose} className={show ? 'intro' : ''}>
<form onSubmit={registerUser}>
<input type="email" />
<div className="form-group">
{
modelShow ? <input type="submit" name="" value="Login" onClick={handleClose}/>
: <input type="submit" name="" value="Login" />
}
</div>
</form>
</Model> : null )

Related

how to add validation to a reactjs form

I have developed a registration form and I tried using validation format but it is not working. I don't know how and where to code a function for it and apply it. please help me how to do it. I will attach the code i have done till now.
import React, { useState } from 'react';
import { Button, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useNavigate } from 'react-router';
export default function Create() {
let navigate = useNavigate();
const [Employee_name, setEmployee_name] = useState('');
const [Employee_id, setEmployee_id] = useState('');
const [Employee_address, setEmployee_address] = useState('');
const [Employee_post, setEmployee_post] = useState('');
const postData = () => {
axios.post(`http://localhost:5000/qo`, {
Employee_name,
Employee_id,
Employee_address,
Employee_post
}).then(() => {
navigate('/read')
})
alert('Data Saved')
}
return (
<div>
<Form className="create-form">
<Form.Field required={true}>
<label>Employee Name</label>
<input placeholder='Employee Name' onChange={(e) => setEmployee_name(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee ID</label>
<input placeholder='Employee ID' onChange={(e) => setEmployee_id(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Address</label>
<input placeholder='Employee Address' onChange={(e) => setEmployee_address(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Position</label>
<input placeholder='Employee Position' onChange={(e) => setEmployee_post(e.target.value)} required={true}/>
</Form.Field>
<Button onClick={postData} type='submit'>Submit</Button>
</Form>
</div>
)
}
There are good libraries out there, that can help you with form validation before allowing a user to submit the form.
One such library could be formik together with Yup.
This is how I do client side form validation on my forms:
Login schema (made with Yup):
import * as Yup from 'yup';
const loginSchema = Yup.object().shape({
username: Yup.string()
.min(3, 'Minimum 3 chars')
.max(50, 'Max 50 chars')
/* password: Yup.string()
.min(6, 'Minimum 6 chars')
.max(50, 'Max 50 chars')
*/
});
Login component:
export const Login = () => {
const [loading, setLoading] = useState(false);
const formik = useFormik({
initialValues: {
username: ''
},
validationSchema: loginSchema,
onSubmit: async (values, {setStatus, setSubmitting}) => {
setLoading(true);
setStatus(null);
try {
// Call your API function to post to the backend here
// You can access your form values in the "values" parameter
setLoading(false);
} catch (error) {
console.error(error);
setStatus('User not found');
setSubmitting(false);
setLoading(false);
}
}
});
}
return (
<form
onSubmit={formik.handleSubmit}
className={'auth-form-wrapper'}
>
{/* begin::Heading */}
<div className={'auth-form-header'}>
<h1>Log in</h1>
<div className={'auth-error-message-container'}>
formik.status && (
<p className={'error-message'}>{formik.status}</p>
)
}
</div>
</div>
{/* end::Heading */}
{/* begin::Form group content */}
<div className={'auth-form-content'}>
{/* begin::Form group */}
<div className={'dynamic-input-container'}>
<input type='text'
id="username"
value={formik.values.username}
onChange={formik.handleChange}
placeholder='Username'
className={'dynamic-input auth-input ' + clsx(
{'is-invalid': formik.touched.username && formik.errors.username},
{
'is-valid': formik.touched.username && !formik.errors.username
}
)}
autoComplete='off'
/>
{formik.touched.username && formik.errors.username && (
<div className='fv-plugins-message-container'>
<span role='alert'>{formik.errors.username}</span>
</div>
)}
</div>
{/* end::Form group*/}
{/* begin::Action */}
<div className='auth-btn-container'>
<Button variant="contained" size="medium" type={'submit'} disabled={loading}>
{
!loading ? <span>Continue</span>
:
(
<span className={'auth-spinner-container'}>
<ClipLoader
loading={loading}
size={20}
aria-label='Loading Spinner'
/>
</span>
)
}
</Button>
</div>
{/* end::Action */}
</div>
{/* end::Form group content */}
</form>
);
Please note, that in my example I only have a "username" input, but you can obviously add as many fields as you wish.
Documentation:
Formik: https://formik.org/docs/tutorial
Yup: https://www.npmjs.com/package/yup
clxs: https://www.npmjs.com/package/clsx
import React, { useState } from 'react';
import { Button, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useNavigate } from 'react-router';
export default function Create() {
let navigate = useNavigate();
const [Employee_name, setEmployee_name] = useState('');
const [Employee_id, setEmployee_id] = useState('');
const [Employee_address, setEmployee_address] = useState('');
const [Employee_post, setEmployee_post] = useState('');
const postData = e => {
e.preventDefault();
if(Employee_name.length == 0) return false;
if(Employee_id.length == 0) return false;
if(Employee_address.length == 0) return false;
if(Employee_post.length == 0) return false;
axios.post(`http://localhost:5000/qo`, {
Employee_name,
Employee_id,
Employee_address,
Employee_post
}).then(() => {
navigate('/read')
})
alert('Data Saved')
}
return (
<div>
<Form className="create-form" onSubmit={e => postData(e)}>
<Form.Field required={true}>
<label>Employee Name</label>
<input placeholder='Employee Name' onChange={(e) => setEmployee_name(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee ID</label>
<input placeholder='Employee ID' onChange={(e) => setEmployee_id(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Address</label>
<input placeholder='Employee Address' onChange={(e) => setEmployee_address(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Position</label>
<input placeholder='Employee Position' onChange={(e) => setEmployee_post(e.target.value)} required={true}/>
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
</div>
)
}
This is updated code from your snippet. try this and let me know what's the progress.
I really appreciate you.

how to render input values on button click react

I have two fields and a button. I want to render input values on the click of a button. Can you guys please tell me how to do it?
function Home() {
const [name, setName] = useState('')
const [age, setAge] = useState(0)
const submitForm = () => {
console.log(name, age)
}
return (
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onClick={submitForm}>Submit</button>
<h1>render "name" gere</h1>
<h2>render "age" gere</h>
</div>
)
}
export default Home
You can add a state to track the display state, as
const [visible, setVisible] = useState(false)
Alter it in form submit as:
const submitForm = () => {
setVisible(true)
}
And render it as:
{visible && <><h1>render {name} gere</h1>
<h2>render {age} gere</h2> </>}
I fix it like this.
function Home() {
const [name, setName] = useState('')
const [age, setAge] = useState(0)
const [data, setData] = useState({})
const submitForm = () => {
setData({name, age})
}
return (
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onClick={submitForm}>Submit</button>
<h1>{data.name}</h1>
<h2>{data.age}</h2>
</div>
)
}
export default Home
Try this and see if it helps.
function Home() {
const {register, handleSubmit} = useForm()
const onSubmit = (data) => {
console.log(data)
}
return (
<form onSubmit = {handleSubmit(onSubmit)}>
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onSubmit={submitForm}>Submit</button>
<h1>render "name" gere</h1>
<h2>render "age" gere</h>
</div>
<form/>
);
}

I want to reset my form after clicking submit in reactjs. I have tried making another method. but it does not work

import React,{ useState} from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react';
import axios from 'axios';
const Create = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
Here I am sending data to a mock api I created
const postData = () =>{
axios.post(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData`,{
firstName,
lastName,
checkbox
})
}
This is the method I created to reset the form but it does not work.
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
}
This is my form where on click i am calling resetForm function but it is not resetting it
is sending the data but not resetting the form.
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder='First Name' onChange={(e)=>setFirstName(e.target.value) } />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder='Last Name' onChange={(e)=>setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox id="c1" label='I agree to the Terms and Conditions' onChange={(e)=>setCheckBox(!checkbox)}/>
</Form.Field>
<Button type='submit' onClick={resetForm}>Submit</Button>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Create;
Actually it will reset the form, the problem is you do not use Controlled Components to show the latest update value in UI
you should bind the value like this:
<input type="text" value={this.state.value} onChange={this.handleChange} />
You can refer the doc here:
https://reactjs.org/docs/forms.html
You can reset your form using the native form.reset() method.
const Create = () => {
const ref = React.useRef(null);
const resetForm = () => ref.current.reset();
return (
<div>
<Form ref={ref}>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder="First Name" onChange={(e) => setFirstName(e.target.value)} />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder="Last Name" onChange={(e) => setLastName(e.target.value)} />
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
<br></br>
<Button onClick={() => navigate(-1)}>Go Back</Button>
</div>
);
};
export default Create;
For that, you have to set value property in your input. Try this
const Create = () => {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [checkbox, setCheckBox] = useState(false);
const postData = () => {
console.log(firstName, lastName, checkbox);
};
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
};
return (
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input
id="f1"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input
id="last1"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
checked={checkbox}
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
</div>
);
};

How do I use the data returned from a handleSubmit function in a modal to display what the user has entered?

At the bottom I listed where I want this information from the form listed but I cannot figure out how to use what is logged in my handleSubmit in my HTML. All of the logs in handleSubmit are returning correctly. Is there a better way to display this information than trying the use the event returned by the form?
class NameForm extends React.Component {
state = {
isOpen: false
};
openModal = () => this.setState({ isOpen: true });
closeModal = () => this.setState({ isOpen: false });
handleSubmit = (event) => {
event.preventDefault()
console.log(event.target[0].value)
console.log(event.target[1].value)
console.log(event.target[2].value)
console.log(event.target[3].value)
}
render() {
return (
<div className = "form-box">
<h5 className = "form-step"> Enter you order below </h5>
<br />
<form onSubmit={this.handleSubmit}>
<div className = "field1">
<label>
Crust :
<input
type="text"
name="Crust"
ref={node => (this.inputNode = node)}
/>
</label>
<br />
<label>
Flavor :
<input
type="text"
name="Flavor"
ref={node => (this.inputNode = node)}
/>
</label>
<br />
<label>
Size :
<input
type="text"
name="Size"
ref={node => (this.inputNode = node)}
/>
</label>
<br />
<label>
Table # :
<input
type="number"
name="Table"
ref={node => (this.inputNode = node)}
/>
</label>
<br />
</div>
<button type="submit" className="submitBtn" onClick={this.openModal}>Submit</button>
<Modal
show={this.state.isOpen}
onHide={this.closeModal}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Thank you for ordering with us, here is what you got!
</Modal.Title>
</Modal.Header>
<Modal.Body>
<p id="order">
I want the information about the users order here
</p>
</Modal.Body>
</Modal>
</form>
</div>
)
}
}
You should control your input element as described in the doc here, as this you will always have the value of an input available in your state and decide to display it were ever you want.
Here is what it could be like in your case --> https://codesandbox.io/s/zealous-dust-bdflk?file=/src/App.js

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;

Categories

Resources