Input doesn't change the value in reactjs - javascript

Problem
I'm working on project using reactjs and graphql with apollo client. I'm trying to get user by id and it works, the value shows in the form modal.
But, I can't delete or add the text or content inside form input.
I'm using onChange handler but it doesn't work. here's the code
import React, { useEffect, useState } from "react";
import { useMutation, useQuery } from "#apollo/client";
import { Button, Modal, Form } from "react-bootstrap";
import { GET_USER_BY_ID } from "../../../gql/query";
const ModalEdit = (props) => {
// state for check input component
const [isChecked, setIsChecked] = useState('ACTIVE');
const [value, setValue] = useState({
full_name: "",
email: "",
phone: "",
address: "",
password: "",
group_id: "",
});
useEffect(() => {
if (props.show) {
document.body.classList.add("modal-open");
}
return () => {
if (document.body.classList.contains("modal-open")) {
document.body.classList.remove("modal-open");
}
};
}, [props.show]);
const { data, loading, error } = useQuery(GET_USER_BY_ID, {
variables: { username: props.username },
});
const dataUser = data?.getUserByID;
if (loading) return <p>Loading...</p>;
if (error) return <p>Error!</p>;
const onChange = (event) => {
setValue({
...value,
[event.target.name]: event.target.value
})
}
return (
<Modal show={props.show}>
<Modal.Header>
<Modal.Title> <span>FORMULIR AKUN PENGGUNA</span> </Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group className="mb-3">
<Form.Label>Role Akun</Form.Label>
<Form.Select aria-label="pilih user role">
<option>{dataUser.group_id}</option>
<option>Admin RJ</option>
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Nama Lengkap</Form.Label>
<Form.Control name="full_name" value={dataUser.full_name} onChange= {onChange} />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Email</Form.Label>
<Form.Control type="email" name="email" value={dataUser.email} onChange={ onChange }/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Phone</Form.Label>
<Form.Control type="text" name="phone" value={dataUser.phone} onChange={ onChange } />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Address</Form.Label>
<Form.Control type="text" name="address" value={dataUser.address} onChange={ onChange } />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Password</Form.Label>
<Form.Control type="password" name="password" value={dataUser.password} onChange={ onChange } />
</Form.Group>
<Form.Label>Aktifkan Akun</Form.Label>
{dataUser.status === 'ACTIVE' ? (
<Form.Check
type="switch"
checked={isChecked}
onChange={(event) => setIsChecked(event.target.checked)}
id="custom-switch"
label="Aktifkan Akun"
/> ) : (
<Form.Check
type="switch"
id="custom-switch"
checked={isChecked}
onChange={(event) => setIsChecked(event.target.checked)}
label="Aktifkan Akun"
/>
)}
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" type="submit" >Submit</Button>
<Button variant="secondary" onClick={props.onClose}>
Close
</Button>
</Modal.Footer>
</Modal>
);
};
export default ModalEdit;
Question
How can i'm edit the form input?
Any help will be apprieciated, thank you

The value prop of your inputs are causing this issue. Instead of binding the value directly to dataUser.address and such, you should set them to value.address and so on.
As for showing the user's data, you should map the values when creating the state.
Your state should be as follows:
const [value, setValue] = useState({
full_name: dataUser.full_name,
email: dataUser.email,
phone: dataUser.phone
address: dataUser.address,
password: dataUser.password,
group_id: dataUser.group_id,
});
And your input should be as follows:
<Form.Control name="full_name" value={value.full_name} onChange= {onChange} />

Related

Error: Cannot read property "name" of undefined. However, after the page is refreshed, the error is removed

I have the following code for when the profile route is being called:
import React, { useState, useEffect } from 'react'
import { Row, Col, Form, Button } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import Message from '../components/Message'
import Loader from '../components/Loader'
import { getUserDetails } from '../actions/userActions'
const ProfileScreen = ({ location, history }) => {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const dispatch = useDispatch()
const userDetails = useSelector((state) => state.userDetails)
const { loading, user, error } = userDetails
const userLogin = useSelector((state) => state.userLogin)
const { userInfo } = userLogin
useEffect(() => {
if (!userInfo) {
history.push('/login')
} else {
if (!user.name) {
dispatch(getUserDetails('profile'))
} else {
setName(user.name)
setEmail(user.email)
}
}
}, [history, userInfo, dispatch, user])
const submitHandler = (e) => {
e.preventDefault()
// DISPATCH PROFILE UPDATE
}
return (
<Row>
<Col md={3}>
<h1>Sign Up</h1>
{error && <Message variant='danger'>{error}</Message>}
{loading && <Loader />}
<Form onSubmit={submitHandler}>
<Form.Group controlId='name'>
<Form.Label>Full Name</Form.Label>
<Form.Control
type='name'
placeholder='Enter your Full Name'
value={name}
onChange={(e) => setName(e.target.value)}
></Form.Control>
</Form.Group>
<Form.Group controlId='email'>
<Form.Label>Email Address</Form.Label>
<Form.Control
type='email'
placeholder='Enter your email address'
value={email}
onChange={(e) => setEmail(e.target.value)}
></Form.Control>
</Form.Group>
<Form.Group controlId='password' className='my-3'>
<Form.Label>Password</Form.Label>
<Form.Control
type='password'
placeholder='Enter your password'
value={password}
onChange={(e) => setPassword(e.target.value)}
></Form.Control>
</Form.Group>
<Form.Group controlId='confirmPassword' className='my-3'>
<Form.Label>Confirm Password</Form.Label>
<Form.Control
type='password'
placeholder='Confirm your password'
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
></Form.Control>
</Form.Group>
<Button type='submit' variant='primary' className='my-4'>
Update
</Button>
</Form>
</Col>
<Col md={9}>
<h2>My Orders</h2>
</Col>
</Row>
)
}
export default ProfileScreen
After the code is being executed, and the user goes to the profile route, at first it shows "Cannot read property 'name' of undefined"
however after the page is being refreshed, the error gets removed and the app then works completely fine.
This is the error being shown
Please check your condition.
useEffect(() => {
if (!userInfo) {
history.push('/login')
} else {
if (Object.keys(user).length === 0) {
dispatch(getUserDetails('profile'))
} else {
setName(user.name)
setEmail(user.email)
}
}
}, [history, userInfo, dispatch, user])

How to get username and password in a javascript object in ReactJS?

I am unable to get the login credentials in the object, the code below works perfectly fine for other forms
SignIn.js
export default function SignIn(props) {
const [state, setState] = useState({
username:'',
password:''
});
const handleSubmit = (event) =>{
event.preventDefault()
const loginCredentials = state;
console.log(loginCredentials)
}
const handleChange = (evt, name)=>{
const { value } = evt.target;
setState({
...state,
[name]: value
});
props.loginHandler()
}
const classes = useStyles();
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="username"
name="name"
autoComplete="email"
autoFocus
onChange={(event)=>handleChange( event, "username")}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={(event)=>handleChange( event, "password")}
/>
<Button onClick={handleSubmit}
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
</form>
</div>
</Container>
);
}
Moreover can any one guide me how to handle file responses in react, I have an endpoint which has a csv file as a response how can I write the request so that the file starts downloading on the press of a button
If I understand your necessity, you can do this directly in the button onChange event, like this:
onChange={(event) => setName(event.target.value)}
onChange={(event) => setPassword(event.target.value)}
and you can create some state like this:
const [values, setValues] = useState({ name: '', password: '' });
...and apply these data in your submit function:
const handleSubmit = () =>{
setValues({ name, password });
console.log(values);
}

ReactJs with Bootstrap: Multistep form validation, using Formik and Yup

I'm developing a multistep form in ReactJs with Bootstrap, using Formik and Yup.
Actually, I have 2 problems here, despite I've read part of Formik and Yup documentation, I haven't found the answer yet.
I change my select fields' values, but the validationSchema simply ignores these values and only the initialValues are submitted to this validation.
Before validating my fields' values through validationSchema, I have to check whether the select option is not the first one (this first option is equivalent to "choose your option" for each field, and when the user submits it, it's value should be empty for the schema), it's possible to be done without validationSchema, by creating a validate function out of Formik, but I want to use Formik because I want a prettier way to display the errors as it does. I've tried plenty of stuff around, but I haven't gotten any answer until now.
Here is the Step 1 Form Code**
import React, { Component } from 'react';
import Form from 'react-bootstrap/Form';
import {ErrorMessage, Formik, validateYupSchema} from "formik";
import Col from 'react-bootstrap/Col';
import InputGroup from 'react-bootstrap/InputGroup';
import Button from 'react-bootstrap/Button';
import * as yup from 'yup';
import PropTypes from 'prop-types';
import {Categories} from './categoriesList.jsx';
import {Brands} from './brandsList';
import {ProductTypes} from './productTypesList';
import NewProduct from './newProductComponent.jsx';
let schema = yup.object().shape({
productCategory: yup.string().required(),
productBrand: yup.string().required(),
productType: yup.string().required()
});
class FormProducts1 extends Component {
reset = () => {
this.props.handleReset1();
}
render() {
const {values, handleChange, handleReset1} = this.props;
const CategoryOptions = Categories,
MakeItemCategory = function(itemCategory) {
return <option value={itemCategory} key={itemCategory}>{itemCategory}</option>;
};
const BrandOptions = Brands,
MakeItemBrand = function(itemBrand) {
return <option value={itemBrand} key={itemBrand}>{itemBrand}</option>;
};
const ProductOptions = ProductTypes,
MakeItemProduct = function(itemProduct) {
return <option value={itemProduct} key={itemProduct}>{itemProduct}</option>;
};
return (
<Formik
initialValues = {{
productCategory:'',
productBrand: '',
productType: ''
}}
validationSchema = {schema}
onSubmit = {
values => {console.log(values)}
}
>
{({
handleSubmit,
handleBlur,
touched,
isInvalid, //defines what is invalid
errors //catch up the errors to be displayed
}) => (
<Form onSubmit={handleSubmit}>
<Form.Group as={Col} md="12" controlId="formProduct.ProductCategory">
<Form.Label>Categoria do Produto</Form.Label>
<Form.Control
name="productCategory"
as="select"
onChange={handleChange('productCategory')}
value={values.productCategory}
onBlur={() => handleBlur('productCategory',true)}
isInvalid={touched.productCategory && errors.productCategory}
>
{CategoryOptions.map(MakeItemCategory)}
</Form.Control>
<Form.Control.Feedback type="invalid">{errors.productCategory}</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="12" controlId="formProduct.ProductBrand">
<Form.Label>Marca do Produto</Form.Label>
<Form.Control
name="productBrand"
as="select"
onChange={handleChange('productBrand')}
value={values.productBrand}
onBlur = {() => handleBlur('productBrand',true)}
isInvalid = {touched.productBrand && errors.productBrand} >
{BrandOptions.map(MakeItemBrand)}
</Form.Control>
<Form.Control.Feedback type="invalid">{errors.productBrand}</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} md="12" controlId="formProduct.ProductType">
<Form.Label>Tipo do Produto</Form.Label>
<Form.Control
name="productType"
as="select"
onChange={handleChange('productType')}
value={values.productType}
onBlur = {() => handleBlur('productType',true)}
isInvalid={touched.productType && errors.productType}>
{ProductOptions.map(MakeItemProduct)}
</Form.Control>
<Form.Control.Feedback type="invalid">{errors.productType}</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="buttonsCategory" style={this.formatForm}>
<Button variant="secondary m-2" type="reset" style={this.styleAddButton} onClick={this.reset}>
Limpar
</Button>
<Button variant="primary" type="submit" style={this.styleAddButton}>
Continuar
</Button>
</Form.Group>
</Form>
)}
</Formik>
);
}
}
export default FormProducts1;
*****************Here is the Steps' Container Component Code *******************
import React, { Component } from 'react';
import FormProducts1 from './formProducts1';
import FormProducts2 from './formProducts2';
import FormProducts3 from './formProducts3';
import FormProductsSuccess from './formProductsSuccess';
import PropTypes from "prop-types";
class NewProduct extends Component {
state = {
step:1,
productCategory:'',
productBrand:'',
productType:'',
productName:'',
productPrice:0,
productCode:'',
productDescription:''
}
formatForm = {
marginTop:15
};
styleAddButton = {
fontSize:15,
fontWeight:"bold"
};
//Proceed to the next step
nextStep = () => {
const {step} = this.state
this.setState({
step: step + 1
});
}
//Go back to previous step <div>
prevStep = () => {
const {step} = this.state
this.setState({
step: step - 1
});
}
//Handle fields change
handleChange = input => e => {
this.setState({
[input]: e.target.value
});
}
toCurrency(number) {
const formatter = new Intl.NumberFormat("pt-BR", {
style: "decimal",
currency: "BRL"
});
return formatter.format(number);
}
handleReset1 = () => {
this.setState({
productCategory:'',
productBrand:'',
productType:''
});
}
handleReset2 = () => {
this.setState({
productName:'',
productPrice:0,
productCode:'',
productDescription:''
});
}
render() {
const {step} = this.state;
const {productCategory, productBrand, productType, productName, productPrice, productCode, productDescription} = this.state;
const values = {productCategory, productBrand, productType, productName, productPrice, productCode, productDescription};
switch(step){
case 1:
return (
<FormProducts1 nextStep = {this.nextStep}
handleChange = {this.handleChange} handleReset1 = {this.handleReset1}
values={values}
/>
)
case 2:
return(
<FormProducts2 nextStep = {this.nextStep}
prevStep = {this.prevStep} handleChange = {this.handleChange}
handleReset2 = {this.handleReset2}
values={values} toCurrency = {this.toCurrency}
/>
)
case 3:
return(
<FormProducts3 nextStep = {this.nextStep} prevStep = {this.prevStep}
values={values} toCurrency = {this.toCurrency}
/>
)
case 4:
return(
<FormProductsSuccess/>
)
}
}
}
NewProduct.propTypes = {
value: PropTypes.string,
onChange: PropTypes.func
};
export default NewProduct;
Thanks!
It took two days to make it error-free... and I had hoped this would be work at your end..
Here, you can find react-bootstrap all input(form-control) along with formik and yup validation package
import React from 'react';
import { Container, Row, Col, Image, Form, Button } from 'react-bootstrap';
import style from '../styles/Contact.module.css';
import { Formik, Field} from 'formik';
import * as Yup from 'yup';
const dropdown=[
{
key:"Select an option",
value:""
},
{
key:"Option 1",
value:"option1"
},
{
key:"Option 2",
value:"option2"
},
{
key:"Option 3",
value:"option3"
}
]
// RegEx for phone number validation
const phoneRegExp = /^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/
// Schema for yup
const validationSchema = Yup.object().shape({
name: Yup.string()
.min(2, "*Names must have at least 2 characters")
.max(30, "*Names can't be longer than 30 characters")
.required("*Name is required"),
email: Yup.string()
.email("*Must be a valid email address")
.max(100, "*Email must be less than 100 characters")
.required("*Email is required"),
phone: Yup.string()
.min(10, "*Names can't be longer than 10 numbers")
.matches(phoneRegExp, "*Phone number is not valid")
.required("*Phone number required"),
msg: Yup.string()
.min(2, "*Messages must have at least 2 characters")
.max(250, "*Messages can't be longer than 250 characters")
.required("*Messages is required"),
selectionOption: Yup.string()
// .of(Yup.string())
// .min(1)
.required('Required'),
});
const Signup = () => {
return (
<>
<Formik
initialValues={{ name: "", email: "", phone: "", msg: "",selectionOption:"" }}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting, resetForm }) => {
// When button submits form and form is in the process of submitting, submit button is disabled
console.log(values)
setSubmitting(true);
// Simulate submitting to database, shows us values submitted, resets form
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
resetForm();
setSubmitting(false);
}, 500);
}}
>
{({ values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting }) => (
<Form className="form" onSubmit={handleSubmit} autoComplete="off" name="contact" method="POST" >
<Row className="mb-5">
<Col lg={6} md={6} sm={12}>
<Form.Group controlId="formName">
<Form.Label className="form_label" >FullName</Form.Label>
<Form.Control
type="text"
name="name"
placeholder="Full Name"
onChange={handleChange}
onBlur={handleBlur}
value={values.name}
className={touched.name && errors.name ? "has-error" : null}
/>
{touched.name && errors.name ? (
<div className="error-message">{errors.name}</div>
) : null}
</Form.Group>
</Col>
<Col lg={6} md={6} sm={12}>
<Form.Group>
<Form.Label className="form_label" >Number</Form.Label>
<Form.Control
type="text"
name="phone"
placeholder="Phone"
onChange={handleChange}
onBlur={handleBlur}
value={values.phone}
className={touched.phone && errors.phone ? "has-error" : null}
/>
{touched.phone && errors.phone ? (
<div className="error-message">{errors.phone}</div>
) : null}
</Form.Group>
</Col>
</Row>
<Row className="mb-5">
<Col lg={6} md={6} sm={12}>
<Form.Group>
<Form.Label className="form_label" >Email</Form.Label>
<Form.Control
type="text"
name="email"
placeholder="Email"
onChange={handleChange}
onBlur={handleBlur}
value={values.email}
className={touched.email && errors.email ? "has-error" : null}
/>
{touched.email && errors.email ? (
<div className="error-message">{errors.email}</div>
) : null}
</Form.Group>
</Col>
<Col lg={6} md={6} sm={12}>
{/* <Form.Select aria-label="Default select example">
<option>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Form.Select> */}
<Form.Group controlId="exampleForm.ControlSelect1">
<Form.Label>Example select</Form.Label>
<Form.Control as="select" name ="selectionOption" onChange={handleChange}
onBlur={handleBlur} value={values.selectionOption}
className={touched.selectionOption && errors.selectionOption ? "has-error" : null}
>
{
dropdown.map(drop=>{return(
<option key={drop.value} value={drop.value}>
{drop.key}
</option>
)
}
)
}
</Form.Control>
{/* <ErrorMessage name="selectionOption"></ErrorMessage> */}
{touched.selectionOption && errors.selectionOption ? (
<div className="error-message">{errors.selectionOption}</div>
) : null}
{/* <Form.Label>Example select</Form.Label>
<Field as="select" name ="selectionOption" onChange={handleChange}
onBlur={handleBlur} value={values.selectionOption}
style={{ display: "block" }}
// isValid={touched.selectionOption && !errors.selectionOption}
// isInvalid={!errors.selectionOption}
className={touched.selectionOption && errors.selectionOption ? "has-error" : null}
>
<option className='text-muted'>---</option>
<option value="ortho">ortho</option>
<option value="pedri">pedri</option>
<option value="crown">crown</option>
</Field>
{touched.selectionOption && errors.selectionOption ? (
<div className="error-message">{errors.selectionOption}</div>
) : null} */}
</Form.Group>
</Col>
</Row>
<Row className="mb-5">
<Col lg={12} md={12} sm={12}>
<Form.Group controlId="formmsg">
<Form.Label>Messages :</Form.Label>
<Form.Control
type="text"
name="msg"
as="textarea" rows={4}
placeholder="Query / Feedback"
onChange={handleChange}
onBlur={handleBlur}
value={values.msg}
className={touched.msg && errors.msg ? "has-error" : null}
/>
{touched.msg && errors.msg ? (
<div className="error-message">{errors.msg}</div>
) : null}
</Form.Group>
</Col>
</Row>
<Button type="submit" className={style.customizeBtn} name="contact" id="contact" disabled={isSubmitting}>
<Image src="img/send.png" className={style.imgBtn} />
<span className={style.titleBtn}>Submit</span>
</Button>
</Form>
)}
</Formik>
</>
)
}
export default Signup;

React Bootstrap can't validate forms

I am trying to add some validation to my React + Bootstrap project but I am not able to achieve this. According to Bootstrap Form validation documentation I have to provide a Form.Control.Feedback component to the Form Group component.
But is not showing the errors but check marks like everything is fine. I created this Code Sandbox yo demostrate what I need to achieve and what is showing me:
And just in case, this is the code if you don't need the sandbox to see the error:
import React, { useState } from "react";
import "./styles.css";
import { Container, Form, Button } from "react-bootstrap";
import validator from "validator";
import empty from "is-empty";
export default function App() {
const [validated, setValidated] = useState(false);
const [errors, setErrors] = useState({});
const [phone, setPhone] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = async e => {
e.preventDefault();
const errors = {};
// validation
if (!validator.isMobilePhone(phone, ["es-UY"])) {
errors.phone = "Invalid phone number";
}
if (!validator.isEmail(email)) {
errors.email = "Invalid email address";
}
if (!empty(errors)) {
setErrors(errors);
}
setValidated(true);
};
return (
<Container>
<Form validated={validated} onSubmit={handleSubmit}>
<h1>Test form</h1>
<Form.Group controlId="phone">
<Form.Label>Phone number</Form.Label>
<Form.Control
type="tel"
value={phone}
onChange={e => setPhone(e.target.value)}
/>
<Form.Control.Feedback type="invalid">Error</Form.Control.Feedback>
{errors.phone && (
<Form.Control.Feedback type="invalid">
{errors.phone}
</Form.Control.Feedback>
)}
</Form.Group>
<Form.Group controlId="email">
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
feedback="Error"
/>
{errors.email && (
<Form.Control.Feedback type="invalid">
{errors.email}
</Form.Control.Feedback>
)}
</Form.Group>
<Form.Group controld="submit">
<Button type="submit" variant="primary">
Submit
</Button>
<Button
type="reset"
variant="info"
style={{ marginLeft: 10 }}
onClick={() => {
setErrors({});
setValidated(false);
}}
>
Reset
</Button>
</Form.Group>
</Form>
</Container>
);
}
So, what am I doing wrong?
Make sure you've set setValidated as false for the errors
const handleSubmit = async e => {
e.preventDefault();
const allErrors = {}; // <--- changed this as well
// validation
if (!validator.isMobilePhone(phone, ["es-UY"])) {
allErrors.phone = "Invalid phone number";
}
if (!validator.isEmail(email)) {
allErrors.email = "Invalid email address";
}
if (!empty(allErrors)) {
setErrors(allErrors);
setValidated(false);
}
else {
setValidated(true);
}
};
In your field add isInvalid as props:
<Form.Control
type="tel"
value={phone}
isInvalid={!!errors.phone} <------
onChange={e => setPhone(e.target.value)}
/>
<Form.Control
type="text"
value={email}
isInvalid={!!errors.email} <-----
onChange={e => setEmail(e.target.value)}
feedback="Error"
/>

Modal doesnt show up in react

I'm new to react thus the question.
This is my CustomModal,
import React from 'react';
import {useState} from "react";
import {Button, Modal} from "react-bootstrap";
const CustomModal = (props) =>{
const [show, setShow] = useState(true);
const handleClose = () => setShow(false);
return (
<div>
<Modal show={show} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>{props.message}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
)
};
export default CustomModal;
I want to render it inside a class component when user submits a registration form.
class Register extends React.Component {
state = {
email : '',
username: '',
password: '',
second_password: ''
};
handleSubmit = async (event) =>{
event.preventDefault();
const emailValidated = await this.validateEmail(this.state.email);
const usernameValidated = this.validateUsername(this.state.username);
const passwordValidated = this.validatePassword(this.state.password, this.state.second_password);
let registrationComplete = false;
if(emailValidated === true && usernameValidated === true && passwordValidated === true){
registrationComplete = await this.register(this.state.email, this.state.username, this.state.password);
console.log(registrationComplete);
this.showModal("Hello World!"); //This is the function begin called to show the modal.
}
};
validateUsername = (username) =>{
return true;
};
validatePassword = (password, second) =>{
return true;
};
validateEmail = async (email) =>{
return true;
};
//This is the function that should display the modal
showModal = (message) =>{
return (<CustomModal message={message}/>);
};
register = async (email, username, password) =>{
return true;
};
render() {
return (
<div className="register">
<h1>Register</h1>
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email"
placeholder="Enter email"
value={this.state.email}
onChange={event => this.setState({email: event.target.value})}/>
<Form.Text className="text-muted">
Please make sure you've access to this mail. You'll receive an activation code here.
</Form.Text>
</Form.Group>
<Form.Group controlId="formPlainText">
<Form.Label className="form-label">Username</Form.Label>
<Form.Control type="text"
placeholder="Username"
value={this.state.username}
onChange={event => this.setState({username: event.target.value})}/>
<Form.Text className="text-muted">
Please make it atleast 8 characters long.
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password"
placeholder="Password"
value={this.state.password}
onChange={event => this.setState({password: event.target.value})}/>
<Form.Text className="text-muted">
Please make sure it's atleast 8 characters long and uses a mix of letters and numbers.
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Retype Password</Form.Label>
<Form.Control type="password"
placeholder="Password"
value={this.state.second_password}
onChange={event => this.setState({second_password: event.target.value})}/>
</Form.Group>
<Button variant="primary" type="submit">
Register
</Button>
</Form>
</div>
);
}
}
export default Register;
All the values are correct and the console log shows true but the Modal doesn't display. Can someone help me with this?
There are some issues on your code
The customModal has to be part of the render of the Register component
There should be a state to track the status of the modal from the Register component
Also the register has to be notified when the Modal closes
I have modified your code and working. You can find it live here
I prefer attack this problem creating portals here documentation.
you might to have issues with z-index in the future.
Basically, you create an element outside the DOM hierarchy.
Now, your issue is that, you must render modal inside render method and control it, with boolean state "showModal".
I prepare for you an example:
example in my GitHub account
git clone ...
npm install
npm run start
preview:

Categories

Resources