React adding fields from a drop down menu - javascript

I'm fairly new to react, and I got involved in this project that was already ongoing, and I was asked to add more fields to a form, after the user chooses how many they want. Basically the form has a couple of fields, and if the user wants to add more people they can choose 1, 2, 3 or 4 and I need them to do so when choosing from a drop down menu, but I'm not sure how to do it. Can I make a div hide or not based on the click from the drop down? here is the code I'm working with.
It could also be one button that adds multiple fields on click one or the other
I've seen a couple of people doing it with redux, but I don't know enough of redux to figure out what they were doing.
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import {
Card, CardBody, Col, Button, Form, FormGroup, Label, Input, UncontrolledDropdown,
DropdownToggle, DropdownMenu, DropdownItem,
} from 'reactstrap';
import ChevronDownIcon from 'mdi-react/ChevronDownIcon';
import PropTypes from 'prop-types';
import StaticBar from './StaticBar';
import { getBasicQuote } from '../../../redux/actions/quoteActions';
import QuotePanel from './QuotePanel';
class VerticalForm extends PureComponent {
static propTypes = {
history: PropTypes.shape({}).isRequired,
getBasicQuotethis: PropTypes.func.isRequired,
};
constructor() {
super();
this.state = {
};
}
handleSubmit = async (event) => {
const { getBasicQuotethis } = this.props;
const gender = event.target.elements.gender.value;
const age = event.target.elements.age.value;
event.preventDefault();
getBasicQuotethis(age, gender);
}
render() {
return (
<>
<Col md={12} lg={12}>
<Card>
<CardBody>
<div className="card__title">
<h5 className="bold-text">Quote Tool</h5>
<h5 className="subhead">Labels are above fields</h5>
</div>
<Form className="form" onSubmit={this.handleSubmit}>
<FormGroup className="form__form-group">
<Label className="form__form-group-label" for="registerEmail">Gender</Label>
<Input
// className="form__form-group-field"
type="text"
name="gender"
id="registerEmail"
placeholder="Gender"
/>
</FormGroup>
<FormGroup className="form__form-group">
<Label className="form__form-group-label" for="registerPassword">Age</Label>
<Input
// className="form__form-group-field"
type="text"
name="age"
id="registerEmail"
placeholder="Age"
/>
</FormGroup>
<Button size="sm" className="btn btn-primary" type="Submit">
Submit
</Button>
<UncontrolledDropdown>
<DropdownToggle className="icon icon--right" outline color="primary">
<p>Add Dependent <ChevronDownIcon /></p>
</DropdownToggle>
<DropdownMenu className="dropdown__menu">
<DropdownItem>1</DropdownItem>
<DropdownItem>2</DropdownItem>
<DropdownItem>3</DropdownItem>
<DropdownItem divider />
<DropdownItem>4 +</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</Form>
</CardBody>
</Card>
</Col>
<StaticBar />
<QuotePanel />
</>
);
}
}
export default connect(null, { getBasicQuotethis: getBasicQuote })(VerticalForm);
Thank you for your help

Ok so I figure it out how to do it.
class VerticalForm extends PureComponent {
static propTypes = {
history: PropTypes.shape({}).isRequired,
getBasicQuotethis: PropTypes.func.isRequired,
};
constructor() {
super();
this.state = {
showHideDependentSpouse: false,
showHideDependent2: false,
showHideDependent3: false,
showHideDependent4: false,
};
this.hideComponent = this.hideComponent.bind(this);
}
handleSubmit = async (event) => {
const { getBasicQuotethis } = this.props;
const gender = event.target.elements.gender.value;
const age = event.target.elements.age.value;
event.preventDefault();
getBasicQuotethis(age, gender);
}
hideComponent(name) {
switch (name) {
case 'showHideDependentSpouse':
this.setState(prevState => ({ showHideDependentSpouse: !prevState.showHideDependentSpouse }));
break;
case 'showHideDependent2':
this.setState(prevState => ({ showHideDependent2: !prevState.showHideDependent2 }));
break;
case 'showHideDependent3':
this.setState(prevState => ({ showHideDependent3: !prevState.showHideDependent3 }));
break;
case 'showHideDependent4':
this.setState(prevState => ({ showHideDependent4: !prevState.showHideDependent4 }));
break;
default:
}
}
render() {
const {
showHideDependentSpouse, showHideDependent2, showHideDependent3, showHideDependent4,
} = this.state;
return (
<>
<Col md={12} lg={12}>
<Card>
<CardBody>
<div className="card__title">
<h5 className="bold-text">Quote Tool</h5>
<h5 className="subhead">Labels are above fields</h5>
</div>
<Form className="form" onSubmit={this.handleSubmit}>
<FormGroup className="form__form-group">
<Label className="form__form-group-label" for="registerEmail">Gender</Label>
<Input
// className="form__form-group-field"
type="text"
name="gender"
id="registerEmail"
placeholder="Gender"
/>
</FormGroup>
<FormGroup className="form__form-group">
<Label className="form__form-group-label" for="registerPassword">Age</Label>
<Input
// className="form__form-group-field"
type="text"
name="age"
id="registerEmail"
placeholder="Age"
/>
<div>
{showHideDependentSpouse && <DependentSpouse />}
{showHideDependent2 && <Dependent1 />}
{showHideDependent3 && <Dependent1 />}
{showHideDependent4 && <Dependent4 />}
</div>
</FormGroup>
<Button size="sm" className="btn btn-primary" type="Submit">
Submit
</Button>
<Row>
<Col lg={8}>
<p>Check each box to add the respective number of dependents</p>
</Col>
<Col>
<Label check>
<Input type="checkbox" onClick={() => this.hideComponent('showHideDependentSpouse')} />
</Label>
</Col>
<Col>
<Label check>
<Input type="checkbox" onClick={() => this.hideComponent('showHideDependent2')} />
</Label>
</Col>
<Col>
<Label check>
<Input type="checkbox" onClick={() => this.hideComponent('showHideDependent3')} />
</Label>
</Col>
<Col>
<Label check>
<Input type="checkbox" onClick={() => this.hideComponent('showHideDependent4')} />
</Label>
</Col>
</Row>
</Form>
</CardBody>
</Card>
</Col>
<StaticBar />
<QuotePanel />
</>
);
}
}
export default connect(null, { getBasicQuotethis: getBasicQuote })(VerticalForm);
Basically set the state for each of the components i want to render, made individual components aside, and then made a logic to change the state false or true, then created a condition on each to check if the state is true.
Hopefully this will be helpful for someone.

Related

React - multi step form with checkbox in child step does not set to true

I am creating a multistep form in react. The Parent component has 3 child components which are the steps of the form. In the first step I have 4 text inputs and need a checkbox to allow wpp communication, the problem is that i can't set the state of the checkbox to true when is clicked.
The parent component is something like this:
import React from 'react';
import FormStep0 from './formStepZero';
import FormStep1 from './formStepOne';
class VendeForm extends React.Component {
constructor(props) {
super(props)
this.state = {
currentStep: 0,
nombre: '',
apellido: '',
celular: '',
email: '',
username: '',
password: '',
checkbox: false,
}
}
handleChange = event => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
handleSubmit = event => {
event.preventDefault()
const { email, username, password, nombre, apellido, celular,checkbox } = this.state
alert(`Your registration detail: \n
Email: ${email} \n
Username: ${username} \n
Password: ${password} \n
Nombre: ${nombre} \n
Apellido: ${apellido} \n
Celular: ${celular} \n
Checkbox: ${checkbox} \n`)
}
_next = () => {
let currentStep = this.state.currentStep
currentStep = currentStep >= 2? 3: currentStep + 1
this.setState({
currentStep: currentStep
})
}
_prev = () => {
let currentStep = this.state.currentStep
currentStep = currentStep <= 0? 0: currentStep - 1
this.setState({
currentStep: currentStep
})
}
/*
* the functions for our button
*/
previousButton() {
let currentStep = this.state.currentStep;
if(currentStep > 1){
return (
<div className='vertical-center'>
<button
className="btn btn-secondary float-right mx-2 my-2"
type="button" onClick={this._prev}>
Previous
</button>
</div>
)
}
return null;
}
nextButton(){
let currentStep = this.state.currentStep;
if(currentStep <3 && currentStep >=1){
return (
<div className='vertical-center'>
<button
className="btn primary-bg-style float-left mx-2 my-2"
type="button" onClick={this._next}>
Siguiente
</button>
</div>
)
}
return null;
}
empecemosButton(){
let currentStep = this.state.currentStep;
if(currentStep === 0){
return (
<div className='vertical-center'>
<button
className="btn primary-bg-style"
type="button" onClick={this._next}>
Vamos!
</button>
</div>
)
}
return null;
}
render() {
return (
<React.Fragment>
{/*render the form steps and pass required props in*/}
<Step0
currentStep={this.state.currentStep}
handleChange={this.handleChange}
/>
<div className="container d-flex flex-column py-2">
<form onSubmit={this.handleSubmit}>
<Step1
currentStep={this.state.currentStep}
handleChange={this.handleChange}
nombre={this.state.nombre}
apellido={this.state.apellido}
celular={this.state.celular}
email={this.state.email}
checkbox={this.state.checkbox}
/>
<Step2
currentStep={this.state.currentStep}
handleChange={this.handleChange}
username={this.state.username}
/>
<Step3
currentStep={this.state.currentStep}
handleChange={this.handleChange}
password={this.state.password}
/>
</form>
<div className='prev-next-btn'>
{this.previousButton()}
{this.nextButton()}
</div>
{this.empecemosButton()}
</div>
</React.Fragment>
);
}
}
function Step0(props){
if (props.currentStep !== 0) {
return null
}
return(
<div className="vertical-center"> {/*<!--^--- Added class --> */}
...
</div>
)
}
function Step1(props) {
if (props.currentStep !== 1) {
return null
}
return(
<div className="form-group">
<div className="vertical-center">
<div className="container">
<h1 className='pb-4 px-2'>Datos de Contacto</h1>
<CircleSteps currentStep={props.currentStep} />
<FormStep1 nombre={props.nombre}
apellido={props.apellido}
celular={props.celular}
email={props.email}
checkbox={props.checkbox}
handleChange = {props.handleChange}
/>
</div>
</div>
</div>
);
}
export default VendeForm;
and the child component where is the checkbox is:
import React from 'react';
import {Col, Row,Container} from 'reactstrap'
function FormStep1(props) {
return(
<div>
<Container className="vende-form-container pt-3">
<Row className='align-items-center justify-content-center'>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="nombre">Nombre</label>
<input
className="form-control"
id="nombre"
name="nombre"
type="text"
placeholder="Escribe tu nombre"
value={props.nombre}
onChange={props.handleChange}
/>
</div>
</Col>
<Col md={4} sm={12} >
<div className="form-group">
<label htmlFor="apellido">Apellido</label>
<input
className="form-control"
id="apellido"
name="apellido"
type="text"
placeholder="Escribe tu apellido"
value={props.apellido}
onChange={props.handleChange}
/>
</div>
</Col>
</Row>
<Row className='align-items-center justify-content-center'>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="celular">Celular</label>
<input
className="form-control"
id="celular"
name="celular"
type="text"
placeholder="Escribe tu celular"
value={props.celular}
onChange={props.handleChange}
/>
</div>
</Col>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
className="form-control"
id="email"
name="email"
type="text"
placeholder="Escribe tu email"
value={props.email}
onChange={props.handleChange}
/>
</div>
</Col>
</Row>
<Row className='align-items-center justify-content-start'>
{/* checkbox allowing whatsapp communication */}
<Col sm={{size:6, offset:2}} md={{size:3, offset:2}}>
<div className="form-check">
<input
className="form-check-input"
id="wppCheckbox"
name="controlled"
type="checkbox"
checked={props.checkbox}
onChange={props.handleChange}
/>
<label className="form-check-label" htmlFor="wppCheckbox">
Aceptas comunicacion via Whatsapp
</label>
</div>
</Col>
</Row>
</Container>
</div>
);
}
export default FormStep1;
The behavior that currently I have is that i click the checkbox but remains in blank, also the others fields of the form are working well and are passed to state properly
If I understand correctly, your checkbox is handled by generic handleChange() function:
handleChange = event => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
Simplest thing you could try for debugging is just logging what you get in that function when you click the checkbox. Most probably in this case you are always getting the same value ("on") hence nothing changes in the state.
I would suggest either use a dedicated handler, or modify this one to be sth like
handleChange = event => {
const {name, type, value} = event.target
if (type === 'checkbox') {
return this.setState({
[name]: event.target.checked
})
}
this.setState({
[name]: value
})
}

Why the warning: Unknown event handler property `onSession` is displayed in React app?

I'm pretty new to React, I have an simple app where the user can login via modal window that is displayed when the button "Login" it's clicked. User data is stored in a MongoDB collection, to validate the email and password entered by the user in the modal window the app send a request to a service that returns the data of the logged user or nothig if any error happens. If the user exists, the id is stored in local storage, then it must be redirected to another page. The problem is that apparently the method 'onSession' does not exist thus generating the warning: "Unknown property of the event handler onSession".
I have created three components: "LoginForm.js", "LoginModal.js" and "Menu.js". The first has the fields for the email and password and the validations for the login, the second has the properties of the modal window and the last one is for a navigation bar where the "Login" button is displayed.
LoginForm.js:
import React from 'react';
import { Col, Row, Form, Stack, Button, Image } from 'react-bootstrap';
import LoginIMG from '../../../assets/login.png'
import './LoginForm.css';
class LoginForm extends React.Component{
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
if(this.state.email === '' || this.state.password === '') {
alert('You must fill all inputs');
}else{
fetch('http://localhost:8080/api/user/'+this.state.email+'/'+this.state.password)
.then(res => res.json())
.then(data => {
if(data.id !== null) {
localStorage.setItem('idUser', data.id);
this.props.onHide();
this.props.onSession();
}else{
alert('Wrong password or username');
}
});
}
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<div className="form">
<br />
<Row className="justify-content-md-center">
<Form onSubmit={this.handleSubmit}>
<Stack gap={3}>
<Row className="justify-content-md-center">
<Col lg={6} md={4} className='text-center'>
<Image src={LoginIMG} className="avatar" roundedCircle />
</Col>
</Row>
<Row className="justify-content-md-center">
<Col lg={6}>
<Form.Group controlId="formEmail">
<Form.Label>Email</Form.Label>
<Form.Control type="email" name="email" value={this.state.email} onChange={this.handleChange} placeholder="Enter email" />
</Form.Group>
</Col>
</Row>
<Row className="justify-content-md-center">
<Col lg={6}>
<Form.Group controlId="formPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" name="password" value={this.state.password} onChange={this.handleChange} />
</Form.Group>
</Col>
</Row>
<Row className="justify-content-md-center">
<Col lg={6} className="d-grid gap-2">
<Button type="submit" variant="success" size="lg">Login</Button>
</Col>
</Row>
</Stack>
</Form>
</Row>
</div>
);
}
}
export default LoginForm;
LoginModal.js:
import LoginForm from '../../forms/loginForm/LoginForm'
import { Modal } from 'react-bootstrap';
import './LoginModal.css';
function LoginModal(props){
return (
<Modal {...props} size="lg" aria-labelledby="contained-modal-title-vcenter" centered>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
{props.title}
</Modal.Title>
</Modal.Header>
<Modal.Body>
<LoginForm onHide={props.onHide} />
</Modal.Body>
<Modal.Footer>
{/* <Button onClick={props.onHide}>Close</Button> */}
</Modal.Footer>
</Modal>
);
}
export default LoginModal;
Menu.js:
import React from 'react';
import {Navbar, Nav, Container} from 'react-bootstrap';
import { Link } from "react-router-dom";
import LoginModal from '../../modals/loginModal/LoginModal';
import { useState } from 'react';
function Menu(){
const [modalShow, setModalShow] = useState(false);
const [idUser, setIdUser] = useState(0);
const setSession = () => {
if(localStorage.getItem('idUser') != null){
setIdUser(localStorage.getItem('idUser'));
console.log(idUser);
}
}
return(
<>
<Navbar bg="dark" expand="lg" variant="dark">
<Container>
<Link className='navbar-brand' to="/">Divina Comedia</Link>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Link className='nav-link' to="/">Home</Link>
{idUser === 0 ? <Nav.Link id="login" onClick={() => setModalShow(true)}>Login</Nav.Link> : null }
{idUser !== 0 ? <Link className='nav-link' to="/orders">Orders</Link> : null }
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
<LoginModal show={modalShow} onHide={() => setModalShow(false)} onSession={() => setSession()} />
</>
);
}
export default Menu;
I'm really don't know what is wrong, any help is appreciated.
onSession={() => setSession()}
This gets passed into LoginModal, which then passes it into Modal here in LoginModal.js:
<Modal {...props}
And Modal ultimately ends up putting it on a <div>. There is no dom event with that name, and thus you are getting the error.
If that prop is intended for LoginModal, then make sure you deal with it there, and don't pass it on to Modal using the spread syntax. For example:
function LoginModal({ onSession, ...rest }){
// Do something with the onSession prop
return (
<Modal {...rest} size="lg" aria-labelledby="contained-modal-title-vcenter" centered>
// Or maybe do something with it here?
)
}

Hide another component on the click of radio button

I'm very new to React. I'm building a flight booking website. I want to hide the return date form field when the user selects one way trip. I wanted to know what is the best way to go about it.
const TripTypeButton = (props) => {
const [rSelected, setRSelected] = useState(null);
return (
<div>
<ButtonGroup>
<Button color="primary" onClick={() => setRSelected(1)} active={rSelected === 1}>Round Trip</Button>
<Button color="secondary" onClick={() => setRSelected(2)} active={rSelected === 2}>One Way</Button>
</ButtonGroup>
</div>
);
}
const HomePage = (props) =>{
return(
<div>
<div>
<h2> Search for flights</h2>
</div>
<div>
<Form>
<Row form>
<FormGroup>
<TripTypeButton />
</FormGroup>
</Row>
<Row form>
<Col md={3}>
<FormGroup>
<Label>Departure</Label>
<Input type="date" id="departure" name="departure"/>
</FormGroup>
</Col>
<Col md={3}>
<FormGroup>
<Label for="exampleState">Return</Label>
<Input type="date" name="return" id="return"/>
</FormGroup>
</Col>
<Row/>
</Form>
</div>
</div>
);
}
for this situation, you need to keep the state of selected trip type in HomePage component and then based on that state render the Return flight or not!
like below:
const HomePage = (props) => {
const [rSelected, setRSelected] = useState(null);
return (
// some code
// trip type button handler
<TripTypeButton handleSelectedTripType={setRSelected} rSelected={rSelected} />
// the button section of code
{ rSelected !== 1
&& <Col md={3}>
<FormGroup>
<Label for="exampleState">Return</Label>
<Input type="date" name="return" id="return"/>
</FormGroup>
</Col>
}
// rest of jsx code
)
}
and your TripTypeButton would be like below:
const TripTypeButton = ({ handleSelectedTripType, rSelected }) => {
return (
<div>
<ButtonGroup>
<Button color="primary" onClick={() => handleSelectedTripType(1)} active={rSelected === 1}>Round Trip</Button>
<Button color="secondary" onClick={() => handleSelectedTripType(2)} active={rSelected === 2}>One Way</Button>
</ButtonGroup>
</div>
);
}
this is called lifting state up in React! and by that you keep your state in top level components and manage data manipulation by passing required handlers down to the child components by directly props or context!

How do I populate a form field with data from redux?

I am having trouble trying to dynamically populate my "client edit form" with data from the corresponding listing in my "client table". As you can see, I have tried using "{this.onChange}", but to no avail.
import React, { Component } from "react";
import { Table, Container, Button } from "reactstrap";
import {
Modal,
ModalHeader,
ModalBody,
Form,
FormGroup,
Label,
Input,
Card,
CardTitle,
CardText,
CardDeck,
CardSubtitle,
CardBody,
} from "reactstrap";
import { connect } from "react-redux";
import { getClients, addClient, deleteClient } from "../actions/clientActions";
import PropTypes from "prop-types";
class ClientTable extends Component {
componentDidMount() {
this.props.getClients();
}
state = {
detailModal: false,
editModal: false,
name: "",
email: "",
number: "",
};
toggleEdit = () => {
this.setState({
editModal: !this.state.editModal,
});
};
toggleDetails = () => {
this.setState({
detailModal: !this.state.detailModal,
});
};
onDeleteClick = (id) => {
this.props.deleteClient(id);
};
renderClient = (clients, _id) => {
return (
<tr key={_id} timeout={500} classNames="fade">
<td>
<Button
className="remove-btn"
color="danger"
size="sm"
onClick={() => this.onDeleteClick(clients._id)}
>
×
</Button>
<Button
style={{ marginLeft: ".2rem" }}
className="add-btn"
outline
color="warning"
size="sm"
onClick={this.toggleEdit}
>
Edit
</Button>
<Button
style={{ marginLeft: ".3rem" }}
className="detail-btn"
outline
color="info"
size="sm"
onClick={this.toggleDetails}
>
Details
</Button>
</td>
<td>{clients.name}</td>
<td>{clients.email}</td>
<td>{clients.number}</td>
</tr>
);
};
render() {
const { clients } = this.props.client;
return (
<Container id="listContainer">
<Table
id="listTable"
className="table-striped table-bordered table-hover"
dark
>
<tr class="listRow">
<thead id="tableHeader">
<tr>
<th id="listActions">Actions</th>
<th id="listName">Name</th>
<th id="listEmail">Email</th>
<th id="listNumber">Number</th>
</tr>
</thead>
<tbody class="listRow">{clients.map(this.renderClient)}</tbody>
</tr>
<Modal isOpen={this.state.editModal} toggle={this.toggleEdit}>
<ModalHeader toggle={this.toggleEdit}> Edit Client </ModalHeader>
<ModalBody>
<Form onSubmit={this.onSubmit}>
<FormGroup>
<Label for="name"> Name </Label>
<Input
type="text"
name="name"
id="client"
placeholder="Add name"
onChange={this.onChange}
></Input>
<Label for="email"> Email </Label>
<Input
type="text"
name="email"
id="client"
placeholder="Add email"
onChange={this.onChange}
></Input>
<Label for="number"> Number </Label>
<Input
type="text"
name="number"
id="number"
placeholder="Add number"
onChange={this.onChange}
></Input>
<Button color="dark" style={{ marginTop: "2rem" }} block>
Submit Client Edit
</Button>
</FormGroup>
</Form>
</ModalBody>
</Modal>
<Modal isOpen={this.state.detailModal} toggle={this.toggleDetails}>
<ModalHeader toggle={this.toggleDetails}>
Client Details
</ModalHeader>
<CardDeck>
<Card></Card>
</CardDeck>
</Modal>
</Table>
</Container>
);
}
}
ClientTable.propTypes = {
getClients: PropTypes.func.isRequired,
client: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
client: state.client,
});
export default connect(mapStateToProps, {
getClients,
deleteClient,
addClient,
})(ClientTable);
How would I go about putting data from the redux store into the fields in my "Edit Client" form? If anyone has any ideas I would greatly appreciate it. This one is stumping me.
In general, by "controlling" the "value" property of an element. Instead of the element taking care of updating its displayed value natively - and triggering handlers only incidentally to what is visible - its value is passed in as the value from the store. The element then sets its value indirectly, through the reducer and store.
Clarification: the value of an html input element can be controlled using the jsx "value" prop. Pass in an onChange function (which you're already doing) and a value prop to create a typical controlled component.
<input value={state} onChange={onChange} />
https://reactjs.org/docs/forms.html#controlled-components

Redux Forms for Creating and Editing

I am working with redux-form. I need to create a new user and update the user's information using the same form. I've made the required form to create a new user right now, but I don't know how to make it available for updating.
Form Component code:
class UserRegistrationForm extends PureComponent {
static propTypes = {
handleSubmit: PropTypes.func.isRequired,
reset: PropTypes.func.isRequired,
isLoading: PropTypes.bool,
submitting: PropTypes.bool.isRequired,
};
constructor() {
super();
this.state = {
showPassword: false,
};
}
showPassword = (e) => {
e.preventDefault();
this.setState(prevState => ({ showPassword: !prevState.showPassword }));
};
onSubmit = data => {
console.log(data);
}
render() {
const { handleSubmit, reset } = this.props;
return (
<Col md={12} lg={12}>
<Card>
<CardBody>
<div className="card__title">
<h5 className="bold-text">STUDENT INFORMATION</h5>
</div>
<form className="form form--horizontal" onSubmit={handleSubmit}>
<div className="form__form-group">
<span className="form__form-group-label">First Name*</span>
<div className="form__form-group-field">
<Field
name="name"
component="input"
type="text"
placeholder="Name"
/>
</div>
</div>
<div className="form__form-group">
<span className="form__form-group-label">Last Name*</span>
<div className="form__form-group-field">
<Field
name="surname"
component="input"
type="text"
placeholder="Surname"
/>
</div>
</div>
<div className="form__form-group">
<span className="form__form-group-label">E-mail*</span>
<div className="form__form-group-field">
<Field
name="email"
component="input"
type="email"
placeholder="example#mail.com"
/>
</div>
</div>
<ButtonToolbar className="form__button-toolbar">
<Button color="primary" type="submit" className="icon" size="sm"><SendIcon /> Submit</Button>
<Button type="button" onClick={reset} className="icon" size="sm">
<CloseIcon /> Cancel
</Button>
</ButtonToolbar>
</form>
</CardBody>
</Card>
</Col>
);
}
}
export default reduxForm({
validate,
form: 'User_Registration_Form', // a unique identifier for this form
})(withTranslation('common')(UserRegistrationForm));
How can I make the form both available creating and updating?
To use the same form for the update as well, you would need to give an initialValues state to Form. Where initial values would be the value of the student you want to edit. Initialize values would be empty when you are creating a new student.
UserRegistrationForm = reduxForm({
validate,
form: 'User_Registration_Form', // a unique identifier for this form
})(withTranslation('common')(UserRegistrationForm));
InitializeFromStateForm = connect(
state => ({
initialValues: studentData
}),
)(InitializeFromStateForm)
export default UserRegistrationForm
An example is here https://redux-form.com/6.6.3/examples/initializefromstate/
Also in your react route file, try to maintain two routes with the same form component.
<Route path="/student/create" component={UserRegistrationForm} />
<Route path="/student/update/:id" component={UserRegistrationForm} />
So whenever you need to create, you redirect to create route and when you need to update, redirect it to update route, with an id as params.

Categories

Resources