Making inputs required in a React.js form - reactjs

What is the best (and simplest) way to require inputs (name, email, content etc.) in React.js. I have searched for quite a while but there seems to be so many varying no-so-clear ways to do this. Ideally I want the inputs user_name, user_email and message to be require in order for the form to be sent successfully. Any help would be appreciated.
import React from 'react';
import { MDBContainer, MDBRow, MDBCol, MDBBtn, MDBIcon } from 'mdbreact';
import NavBar from "./NavBar";
import Footer from "./Footer";
import emailjs from 'emailjs-com';
import{ init } from 'emailjs-com';
function Contact() {
function sendEmail(e) {
e.preventDefault();
emailjs.sendForm('hidden', 'hidden', e.target, 'hidden')
.then((result) => {
alert("Great, your request has been sent!");
}, (error) => {
alert("Oops, something went wrong. Please try again")
});
e.target.reset();
}
return (
<div>
<NavBar />
<br />
<br />
<br />
<br />
<br />
<MDBContainer>
<MDBRow className = "formcontainer">
<MDBCol md="6">
<form onSubmit={sendEmail}>
<p className="h4 text-center mb-4">Fill in the information below to contact me!</p>
<br />
<label htmlFor="defaultFormContactNameEx" className="grey-text" > Your name </label>
<input type="text" id="defaultFormContactNameEx" className="form-control" name="user_name" />
<br />
<label htmlFor="defaultFormContactEmailEx" className="grey-text"> Your email </label>
<input type="email" id="defaultFormContactEmailEx" className="form-control" name="user_email"/>
<br />
<label htmlFor="defaultFormContactSubjectEx" className="grey-text"> Subject</label>
<input type="text" id="defaultFormContactSubjectEx" className="form-control" name="user_subject" />
<br />
<label htmlFor="defaultFormContactMessageEx" className="grey-text"> Your message </label>
<textarea type="text" id="defaultFormContactMessageEx" className="form-control" rows="7" name="message"/>
<div className="text-center mt-4">
<MDBBtn color="warning" outline type="submit">
Send
<MDBIcon far icon="paper-plane" className="ml-2" />
</MDBBtn>
</div>
</form>
</MDBCol>
</MDBRow>
</MDBContainer>
<br />
<br />
<Footer />
</div>
);
};
export default Contact;

The easier way to do that is using the required attribute in each of the form's elements.
i.e:
<input required type="email" id="defaultFormContactEmailEx" className="form-control" name="user_email"/>
You can absolutely check if all inputs are not empty when submiting the form too
More info about the required attribute here

Related

Cant Able to login because it shows an error message from firebase "email id is badly formatted"

This is my code but couldnt find any solution , the data got uploaded in firebase , and authentication deatils my email id and details is there but , while trying to login it shows the eeror and i cant find any solution , tried with trim() function , but didnt work . so please try to help
My Code
import React ,{useState,useContext}from 'react';
import FirebaseContext from '../../store/FirebaseContext.js'
import './Login.css';
import {useHistory} from "react-router-dom"
[![Screen Shot for the error message][1]][1]
function Login() {
const history=useHistory()
const [password,setPassword]=useState('')
const [email,setEmail]=useState('')
const {firebase}=useContext(FirebaseContext)
const handleLogin=(e)=>{
e.preventDefault()
firebase.auth().signInWithEmailAndPassword(email.trim(),password)
.then(()=>{
alert('LoggedIn')
history.push("/")
})
.catch((error)=>{
alert(error.message)
})
}
return (
<div className='backdrop'>
<div className="loginParentDiv">
<img className='login-logo' src="https://t4.ftcdn.net/jpg/03/77/48/55/360_F_377485593_QHN6cjoNsNdOBoJNOwVRlFcHyZ0M9n3P.jpg"></img>
<br />
<form onSubmit={handleLogin}>
<label htmlFor="fname">Email</label>
<br />
<br />
<input
className="input"
type="email"
name="email"
placeholder='john123#gmail.com'
/>
<br />
<br />
<label htmlFor="lname">Password</label>
<br />
<br />
<input
className="input"
type="password"
id="lname"
name="password"
placeholder=''
/>
<br />
<br />
<button>Login</button>
</form>
<a href='/signup'>Signup</a>
</div>
</div>
);
}
export default Login;
My Code
You don't have an onChange method in your inputs. Check you are receiving your email in your state with a console.log first.
try this
<input
className="input"
type="email"
onChange={(e) => setEmail(e.target.value)}
name="email"
placeholder='john123#gmail.com'
/>

React on button click Add textarea

I'm making a simple resume portal and I have a textarea(1), in which user can write his/her work experience. To add more than one work experience I have set a button(Add) which basically will add a new textarea(similar to textarea(1) but without label) just below the textarea(1) and so on. This all should be done when button(Add) is clicked.
If I am able to add my code in a child component that would solve my problem I think.
Here's below what I tried:
Child component ( src -> Routes -> UserForm -> Components -> UserDetails -> index.js )
import React from 'react'
import './style.scss';
import { Row, Col } from 'react-bootstrap'
const UserDetails = () => {
return (
<>
<div className='UserDetails'>
<Row>
<Col lg='6'>
<div className='persnlInfo'>
<h4>
Personal Information
</h4>
<p>Your Name</p>
<input type="text" placeholder="Enter here" />
<p>Your Contact</p>
<input type="text" placeholder="Enter here" />
<p>Your Address</p>
<textarea className='formAddress' rows="5" cols="10" placeholder="Enter here" />
<p id='impLinks'>Important Links</p>
<p>Facebook</p>
<input type="text" placeholder="Enter here" />
<p>Instagram</p>
<input type="text" placeholder="Enter here" />
<p>Linkedin</p>
<input type="text" placeholder="Enter here" />
</div>
</Col>
<Col lg='6'>
<h4>
Professional Information
</h4>
<p>Objective</p>
<textarea className='formObjective' rows="5" cols="10" placeholder="Enter here" />
<p>Work Experience</p>
<textarea className='formObjective' rows="3" cols="10" placeholder="Enter here" />
<div className='addButton'>
<input type='button' id='addWrkExp' value='Add' />
</div>
</Col>
</Row>
</div>
</>
)
}
export default UserDetails;
Parent component ( src -> Routes -> UserForm -> index.js )
import React from 'react'
import Pages from '../../Components/HOC/Page/index'
import UserDetails from '../UserForm/Components/UserDetails/index'
class UserForm extends React.Component{
render() {
return(
<>
<Pages
showHeader
showFooter
>
<UserDetails />
</Pages>
</>
);
}
}
export default UserForm;
Output:
To obtain the said above, I've searched up on this but not getting What and Where to put logic/code exactly. If I'm not wrong this can be done using state , props , onClick() and/or something related.
I hope this is enough from my side to understand the problem. Thanks in advance for your help.
You can use a useState for the number of textareas on your page and then when button(add) gets clicked, that state gets increased by one,
This is your Child component ( src -> Routes -> UserForm -> Components -> UserDetails -> index.js )
import React, { useState } from 'react'
import './style.scss';
import { Row, Col } from 'react-bootstrap'
const UserDetails = () => {
const [ workXPs, setWorkXPs ] = useState(1);
return (
<>
<div className='UserDetails'>
<Row>
<Col lg='6'>
<div className='persnlInfo'>
<h4>
Personal Information
</h4>
<p>Your Name</p>
<input type="text" placeholder="Enter here" />
<p>Your Contact</p>
<input type="text" placeholder="Enter here" />
<p>Your Address</p>
<textarea className='formAddress' rows="5" cols="10" placeholder="Enter here" />
<p id='impLinks'>Important Links</p>
<p>Facebook</p>
<input type="text" placeholder="Enter here" />
<p>Instagram</p>
<input type="text" placeholder="Enter here" />
<p>Linkedin</p>
<input type="text" placeholder="Enter here" />
</div>
</Col>
<Col lg='6'>
<h4>
Professional Information
</h4>
<p>Objective</p>
<textarea className='formObjective' rows="5" cols="10" placeholder="Enter here" />
<p>Work Experience</p>
{[...Array(workXPs).keys()].map((workXP, i) => {
return <textarea key={i} className='formObjective' rows="3" cols="10" placeholder="Enter here" />;
})}
<div className='addButton'>
<input type='button' id='addWrkExp' value='Add' onClick={() => setWorkXPs(prev => (prev + 1))} />
</div>
</Col>
</Row>
</div>
</>
)
}
export default UserDetails;
if you wanna do more advanced and add remove buttons, check this: https://www.educative.io/blog/react-hooks-tutorial-todo-list
hope this helps 🙂
You could just make a state and change the state on the button click.
Then change the style according to the state.
Parent Component
import React from "react";
import Pages from "../../Components/HOC/Page/index";
import UserDetails from "../UserForm/Components/UserDetails/index";
class UserForm extends React.Component {
state = {
textAreas: [{ text: "" }]
};
addTextArea = () => {
let updatedTextArea = [...this.state.textAreas];
updatedTextArea.push({ text: "" });
this.setState({ textAreas: updatedTextArea });
};
render() {
return (
<>
<Pages showHeader showFooter>
<UserDetails textAreas={this.state.textAreas} clicked={this.addTextArea} />
</Pages>
</>
);
}
}
export default UserForm;
i changed <UserDetails textAreas={textAreas} clicked={this.addTextArea} /> to <UserDetails textAreas={this.state.textAreas} clicked={this.addTextArea} />
in the UserForm component
child Component
import React from 'react'
import './style.scss';
import { Row, Col } from 'react-bootstrap'
const UserDetails = (props) => {
const {textAreas, clicked} = props
return (
<>
<div className='UserDetails'>
<Row>
<Col lg='6'>
<div className='persnlInfo'>
<h4>
Personal Information
</h4>
<p>Your Name</p>
<input type="text" placeholder="Enter here" />
<p>Your Contact</p>
<input type="text" placeholder="Enter here" />
<p>Your Address</p>
<textarea className='formAddress' rows="5" cols="10" placeholder="Enter here" />
<p id='impLinks'>Important Links</p>
<p>Facebook</p>
<input type="text" placeholder="Enter here" />
<p>Instagram</p>
<input type="text" placeholder="Enter here" />
<p>Linkedin</p>
<input type="text" placeholder="Enter here" />
</div>
</Col>
<Col lg='6'>
<h4>
Professional Information
</h4>
<p>Objective</p>
<textarea className='formObjective' rows="5"
cols="10" placeholder="Enter here" />
<p>Work Experience</p>
{textAreas.map(item => (
<textarea className='formObjective' value=
{item.value} rows="3" cols="10" placeholder="Enter
here" />
)) }
<div className='addButton' onClick={clicked}>
<input type='button' id='addWrkExp' value='Add' />
</div>
</Col>
</Row>
</div>
</>
)
}
export default UserDetails;

Inputting an ARRAY into a FORM field in REACT

I am trying to learn to code by following an eCommerce product tutorial guide in React.
I have finished setting up the product page and checkout.
My goal now is to extract the cart: [] along with the checkout total into a form using EmailJS.
import React from 'react';
import emailjs from 'emailjs-com';
import './form.css';
import { ProductConsumer } from '../../context'
import CartList from './CartList'
import CartColumns from "./CartColumns"
import CartTotals from './CartTotals'
import Title from "../Title";
import { ProductProvider } from "../../context"
import CartItem from './CartItem'
export default function CheckOut() {
function sendEmail(e) {
alert("Your order has been placed!")
e.preventDefault();
emailjs.sendForm('gmail', 'template_3DAGPnwJ', e.target, 'user_m49ol85bvoqFluF8IKatG')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
}
let Order = "cat"
return (
<div>
<ProductConsumer>
{value => {
return(
<div>
<Title name="Check" title="Out"/>
<CartColumns />
<CartList value={value} />
<CartTotals value={value}/>
</div>
)
}
}
</ProductConsumer>
<form className="contact-form" onSubmit={sendEmail}>
<label>Contact Number eg. 12345678 </label>
<input type="tel" name="contact_number" placeholder="12345678" pattern="[0-9]{8}" required />
<label>Name</label>
<input type="name" name="user_name" required />
<label>Email</label>
<input type="email" name="user_email" required />
<label>Address Line 1</label>
<input type="address-line1" name="user_address1" required />
<label>Address Line 2</label>
<input type="address-line2" name="user_address2" />
<label>Message (eg. Special Requests)</label>
<textarea name="message_html" />
<input type="submit" value="Place Order" />
<textarea name="proudct order" value={Order}/>
</form>
</div>
);
}
So far the textarea is showing "cat" from the let Order = "cat".
I would like to put the array information from CartList and CartTotal into Order. Once the client submits the form, I will have their name email address and the order they collected in the cart. This will be emailed to me via EmailJS.
import React from 'react';
import emailjs from 'emailjs-com';
import './form.css';
import { ProductConsumer } from '../../context';
import CartList from './CartList';
import CartTotals from './CartTotals';
import Title from '../Title';
export default function CheckOut() {
function sendEmail(e) {
alert('Your order has been placed! Our staff will get in touch with you to confirm your order and to process payment.');
e.preventDefault();
emailjs
.sendForm(
'gmail',
'xxxxxxxxx',
e.target,
'xxxxxxxxx'
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
}
const Form = ({ context }) => {
let Order = context.cart.map((item) => `ID: ${item.id} \n${item.title} \t $ ${item.price} \t Qty:${item.count} \n\n`);
let OrderSubtotal = context.cartSubtotal ;
let OrderServce = context.cartService;
let OrderShipping = context.cartShipping;
let OrderTotal = context.cartTotal;
return (
<form className="contact-form" onSubmit={sendEmail}>
<label>Contact Number eg. 12345678 </label>
<input
type="tel"
name="contact_number"
placeholder="12345678"
pattern="[0-9]{8}"
required
/>
<label>Name</label>
<input type="name" name="user_name" required />
<label>Email</label>
<input type="email" name="user_email" required />
<label>Address Line 1</label>
<input type="address-line1" name="user_address1" required />
<label>Address Line 2</label>
<input type="address-line2" name="user_address2" />
<label>Message (eg. Special Requests)</label>
<textarea name="message_html" />
<input type="submit" value="Place Order" />
<textarea style={{display:"none"}} name="Order" defaultValue={Order} />
<textarea style={{display:"none"}} name="OrderSubtotal" defaultValue={OrderSubtotal} />
<textarea style={{display:"none"}} name="OrderServce" defaultValue={OrderServce} />
<textarea style={{display:"none"}} name="OrderShipping" defaultValue={OrderShipping} />
<textarea style={{display:"none"}} name="OrderTotal" defaultValue={OrderTotal} />
</form>
);
};
return (
<div>
<ProductConsumer>
{(value) => {
return (
<div>
<Title name="Check" title="Out" />
<CartList value={value} />
<CartTotals value={value} />
</div>
);
}}
</ProductConsumer>
<ProductConsumer>
{(context) => <Form context={context} />}
</ProductConsumer>
</div>
);
}
The answer.
import { ProductConsumer } from '../../context';
let Order = context.cart.map((item) => ID: ${item.id} \n${item.title} \t $ ${item.price} \t Qty:${item.count} \n\n);
which is then exported to emailJS in the textarea.
<textarea style={{display:"none"}} name="Order" defaultValue={Order} />
and rendered
<ProductConsumer>
{(context) => <Form context={context} />}
</ProductConsumer>
Answer suggested by Metafield on Scrimba Discord Community. Thanks a ton!
You can and should use state to update any variable in a React component! CheckOut is a functional component. To use state in a functional component you have to use a hook, which is useState.
To get value from CartList and CartTotal and update Order, pass callback functions from CheckOut component.
Please check the following code, hope it helps.
import React, { useState } from "react";
import emailjs from "emailjs-com";
import "./form.css";
import { ProductConsumer } from "../../context";
import CartList from "./CartList";
import CartColumns from "./CartColumns";
import CartTotals from "./CartTotals";
import Title from "../Title";
import { ProductProvider } from "../../context";
import CartItem from "./CartItem";
export default function CheckOut() {
// Order default value is empty array. i.e. no orders
// updateOrder will update Order
const [Order, updateOrder] = useState([]);
// cartTotal to store CartTotals value
// updateCartTotal will update cartTotal
const [cartTotal, updateCartTotal] = useState(0);
function sendEmail(e) {
alert("Your order has been placed!");
e.preventDefault();
// You can access Order and cartTotal here.
console.log(Order, cartTotal);
emailjs
.sendForm(
"gmail",
"template_3DAGPnwJ",
e.target,
"user_m49ol85bvoqFluF8IKatG"
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
}
return (
<div>
<ProductConsumer>
{(value) => {
return (
<div>
<Title name="Check" title="Out" />
<CartColumns />
{/* updateOrder is a callback passed by prop */}
<CartList value={value} onCartUpdate={updateOrder} />
{/* updateCartTotal is a callback passed by prop */}
<CartTotals value={value} onCartTotalUpdate={updateCartTotal} />
</div>
);
}}
</ProductConsumer>
<form className="contact-form" onSubmit={sendEmail}>
<label>Contact Number eg. 12345678 </label>
<input
type="tel"
name="contact_number"
placeholder="12345678"
pattern="[0-9]{8}"
required
/>
<label>Name</label>
<input type="name" name="user_name" required />
<label>Email</label>
<input type="email" name="user_email" required />
<label>Address Line 1</label>
<input type="address-line1" name="user_address1" required />
<label>Address Line 2</label>
<input type="address-line2" name="user_address2" />
<label>Message (eg. Special Requests)</label>
<textarea name="message_html" />
<input type="submit" value="Place Order" />
<textarea name="proudct order" value={Order} />
</form>
</div>
);
}
I see your input fields are uncontrolled! React suggests to use a controlled component for form input. You can get idea from here - https://reactjs.org/docs/forms.html#controlled-components
Also, since you are learning React I suggest you read about two core parts of React. They are props and state.
For working with forms you can check this popular form handling library for react. https://formik.org/

mdbreact default styling not loading in reactjs

I created a new react app, then I created a registration form component using mdbreact and everything was loading well. All of a sudden, the default styling associated with mdbreact suddenly stopped loading.
import React, { Component } from 'react';
import { MDBContainer, MDBRow, MDBCol, MDBBtn, MDBCard, MDBCardBody, MDBInput } from 'mdbreact';
class Registration extends Component {
render() {
return (
<MDBContainer>
<MDBRow className="d-flex justify-content-center">
<MDBCol md="6">
<form>
<p className="h5 text-center mb-4">Sign up</p>
<div className="grey-text">
<MDBInput label="Your name" icon="user" group type="text" validate error="wrong"
success="right" />
<MDBInput label="Your email" icon="envelope" group type="email" validate error="wrong"
success="right" />
<MDBInput label="Confirm your email" icon="exclamation-triangle" group type="text" validate
error="wrong" success="right" />
<MDBInput label="Your password" icon="lock" group type="password" validate />
</div>
<div className="text-center">
<MDBBtn color="primary">Register</MDBBtn>
</div>
</form>
</MDBCol>
</MDBRow>
</MDBContainer>
);
}
}
export default Registration;
Actual outcome
Expected outcome

Clicking Next button doesn't taking it to next page

import React from 'react';
import { Link } from 'react-router';
import { Field } from 'redux-form';
import BaseForm from '..//BaseForm';
export default class XXXXXXX extends BaseForm {
componentWillMount() {
this.props.retrieveAcademies();
}
render() {
const {
handleSubmit,
formatGraduationDate,
pristine,
submitting,
infoError,
acadamyId
} = this.props;
return (
<div className="col-md-8 col-lg-8 mscs-text">
<div>
<h1 className="mscs-head">Self Registration </h1> <hr />
<form onSubmit={handleSubmit(this.props.startRegistrationProcess.bind(this))} className="registration-step1Class">
<div className="form-section">
<label htmlFor="firstName">First Name:</label>
<Field name="firstName" component={this.renderInputield} label="Enter first Name:" />
</div>
<div className="form-section">
<label htmlFor="lastName">Last Name:</label>
<Field name="lastName" component={this.renderInputield} label="Enter last Name:" />
</div>
<div id="datetimepicker2" className="form-section">
<label htmlFor="dob">Date of Birth:</label>
<Field name="dob" component={this.renderReactDatePicker} type="text" />
</div>
<div className="form-section">
<label htmlFor="maritimeAcadamy">Maritime Academy:</label>
{this.renderAcademiesSelection(acadamyId)}
</div>
<div className="form-section">
<label htmlFor="Yearpassed">Year Passed:</label>
<Field name="passedYear"
component={this.renderReactDatePicker}
type="text"
formatDate={formatGraduationDate}
/>
</div>
<br />
<div className="form-section">
<label htmlFor="CustomerNumber">Customer ID:</label>
<Field name="CustomerNumber" component={this.renderInputield} type="text" label="Enter Customer ID:" />
</div>
<div className="error validation-error">
{infoError && infoError.error} <br />
</div>
<input type="submit" className="btn btn-success" value="Next" />
<input type="reset" className="btn btn-default" value="Cancel" />
</form>
</div>
</div>
);
}
renderAcademiesSelection(acadamyId) {
return (
<div>
<select className="form-control" {...acadamyId}>
<option key={0} value={''}>{'Select your academy'}</option>
{
this.props.academies && this.props.academies.map(function (item, index) {
return (
<option key={item.Id} value={item.Id}>{item.Name}</option>
);
})
}
</select>
</div>
);
}
}
This is the component. Below is the container. The code has some textboxes and dropdowns and calendar controls.
Container :
function mapStateToProps(state, ownProps) {
return {
academies: state.academies.academies,
infoError: state.signUp.error
};
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
retrieveAcademies: () => {
dispatch(retrieveAcademies());
},
startRegistrationProcess: dispatchGenerateRegistrationToken.bind(this),
nextPage: ownProps.nextPage,
}
}
The above code samples are my react component and container. When I am clicking on the Next button it is not taking me to the next step and it is not showing any type of error in the console. I don't know where exactly the mistake is. I can't debug since the console is not giving any type of error. Any help is appreciated here.

Resources