I'm trying to get data from 2 text boxes using react useState. But when I check the console.log, it takes text letters one by one as an array.
create.js
import React, {useState} from 'react'
import { Form, Button, FormGroup, FormControl, ControlLabel } from "react-bootstrap";
export default function Create() {
const[firstName, setFirstName] = useState('');
const[lastName, setLasttName] = useState('');
console.log(firstName);
console.log(lastName);
return (
<div>
<div>create</div>
<div>
<Form>
<Form.Group className="mb-3" >
<Form.Label>First Name</Form.Label>
<Form.Control type="text" name='fName'
onChange={(e)=> setFirstName(e.target.value)}
placeholder="Enter first name" />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Last Name</Form.Label>
<Form.Control type="text" name='lName'
onChange={(e)=> setLasttName(e.target.value)}
placeholder="Enter last name" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
</div>
)
}
App.js
import './App.css';
import Create from './Components/create';
function App() {
return (
<div className="App">
<h2>Hello</h2>
<Create/>
</div>
);
}
export default App;
This is how the console looks like.
Console should be as shown below
The onChange function gets triggered every time the input changes. If you want it to trigger only once, when you are done typing, you can use onBlur this will assign the values only when the input field gets blurred.
Here's a sandbox for you to play with. Make sure you check the console to see when firstName gets updated https://codesandbox.io/s/pedantic-tharp-rfnxqg?file=/src/App.js
I would highly suggest that you check out React Hook Forms
import React, {useState} from 'react'
import { Form, Button, FormGroup, FormControl, ControlLabel } from "react-bootstrap";
export default function Create() {
const[firstName, setFirstName] = useState('');
const[lastName, setLasttName] = useState('');
const submitForm =(e)=>{
console.log(firstName)
console.log(lastName)
e.preventDefault()
}
return (
<div>
<div>create</div>
<div>
<Form onSubmit={(e)=>submitForm(e)}>
<Form.Group className="mb-3" >
<Form.Label>First Name</Form.Label>
<Form.Control type="text" name='fName'
onChange={(e)=> setFirstName(e.target.value)}
placeholder="Enter first name" />
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Last Name</Form.Label>
<Form.Control type="text" name='lName'
onChange={(e)=> setLasttName(e.target.value)}
placeholder="Enter last name" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
</div>
)
}
Related
So, I'm trying to show an Amazon country API to my React-Select component and I've tried to do this in many different ways, but I would only get as result a blank page or a white list on my Select component
The code below has only the Axios method to call the API.
What Should I do so I can show the API data on the Select component?
Here's my Form.jsx component:
import { useState, useEffect } from 'react';
import '../App.css';
import Form from 'react-bootstrap/Form';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Button from 'react-bootstrap/Button';
import Select from 'react-select';
import Axios from 'axios';
function Forms() {
const [countries, setCountry] = useState([])
Axios.get(`https://amazon-api.sellead.com/country`)
.then(res => {
const countries = res.data;
console.log(countries)
})
return (
<Form>
<Row className="mb-3">
<Form.Group as={Col} controlId="formGridEmail">
<Form.Control type="text" name = "name" placeholder="Nome" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="email" name = "email" placeholder="E-mail" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name = "cpf" placeholder="CPF" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name = "tel" placeholder="Telefone" />
</Form.Group>
<Form.Label>País</Form.Label>
<Form.Group as={Col} controlId="formGridPassword">
<Select
/>
</Form.Group>
<Form.Label>Cidade</Form.Label>
<Form.Group as={Col} controlId="formGridPassword"> <br/>
<Select
/>
</Form.Group>
<Button variant="primary" type="submit">
Enviar
</Button>
</Row>
</Form>
);
}
export default Forms;
Hey, First of all, you have to understand that you have to store that data somewhere, The data that you received from API.
Once you store it all you need is just update that in useState([]). That you created.
Now this API you are calling must be called once only so all we need is useEffect() hook with [] an empty array as a dependency so it will only call once the function that is handling API, on initial render.
Once you have data then just loop through it using the map function and render the options.
Here is code.
App.js
import "./styles.css";
import Forms from "./Forms.js";
export default function App() {
return (
<div className="App">
<Forms />
</div>
);
}
Forms.js
import { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
import Col from "react-bootstrap/Col";
import Row from "react-bootstrap/Row";
import Button from "react-bootstrap/Button";
import Select from "react-select";
import Axios from "axios";
function Forms() {
// creating an useState for setting country list received from api
const [countriesList, setCountriesLits] = useState([]);
//async funtion that handling api
const getCountries = async () => {
let contries = []; // to store api data
const countryRes = await Axios.get(
`https://amazon-api.sellead.com/country`
);
countryRes.data.forEach((data) => {
contries.push(data.name);
});
// updating state
setCountriesLits(contries);
};
const handleChange = (e) => {
alert(e.target.value);
};
useEffect(() => {
getCountries();
}, []);
return (
<Form>
<Row className="mb-3">
<Form.Group as={Col} controlId="formGridEmail">
<Form.Control type="text" name="name" placeholder="Nome" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="email" name="email" placeholder="E-mail" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name="cpf" placeholder="CPF" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name="tel" placeholder="Telefone" />
</Form.Group>
<Form.Label>País</Form.Label>
<Form.Group as={Col} controlId="formGridPassword">
<select onChange={handleChange}>
{/* rendering option from the state countriesList */}
{countriesList.map((data, i) => (
<option key={i} value={data}>
{data}
</option>
))}
</select>
</Form.Group>
<Form.Label>Cidade</Form.Label>
<Form.Group as={Col} controlId="formGridPassword">
{" "}
<br />
<Select />
</Form.Group>
<Button variant="primary" type="submit">
Enviar
</Button>
</Row>
</Form>
);
}
export default Forms;
You can also visit the working code here on codesandbox
Below is the output:
All you're doing is logging the data to the console (and shadowing a variable):
const countries = res.data;
console.log(countries)
If the data needs to be set in state, set it in state (and you don't need the local variable at all):
setCountry(res.data);
You've also removed the prop from your <Select> component. Clearly you'll need that back:
<Select options={countries} />
As an aside... Names matter. There is a pluralization inconsistency here:
const [countries, setCountry] = useState([])
It's best to keep your names consistent and meaningful, otherwise you end up confusing yourself when you try to use the data. Since this is an array of values, maintain pluralization:
const [countries, setCountries] = useState([]);
So I'm trying to get my form validation to work using EmailJs and Bootstrap within React for a simple contact form. I got the validation to work on the UI, however, it will still send the email even if the fields are red and required. Any idea what I'm doing wrong? I followed the examples here: https://react-bootstrap.github.io/forms/validation/ and here: https://www.emailjs.com/docs/examples/reactjs/ but it does not seem to be working correctly.
Thanks in advance for any help you can provide.
EDIT
I was able to solve this by using a handleSubmit function after my sendEmail function. Please see updated code below.
I also added a way to clear the form by setting setValidated(false); e.target.reset(); within .then() method after the user submits the form...Hopefully this will help others struggling with this.
import React, { useRef, useState } from "react";
import emailjs from "#emailjs/browser";
import Button from "react-bootstrap/Button";
import PageTitle from "../components/PageTitle";
import Form from "react-bootstrap/Form";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import FloatingLabel from "react-bootstrap/FloatingLabel";
import config from "../configData.json";
import "./Contact.scss";
export const Contact = () => {
const [validated, setValidated] = useState(false);
const form = useRef();
const sendEmail = (e) => {
e.preventDefault();
emailjs
.sendForm(
config.serviceId,
config.templateId,
"#contact-form",
config.publicKey
)
.then(
() => {
alert("Your message has been sent.");
setValidated(false);
e.target.reset();
},
(error) => {
alert("There was a problem sending your message.", error);
}
);
};
const handleSubmit = (event) => {
const form = event.currentTarget;
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
} else {
// alert("Message was sent!");
sendEmail(event);
}
setValidated(true);
};
return (
<>
<PageTitle title="Contact" />
<div className="container my-5">
<h2 className="mb-4">Leave a Message</h2>
<Form
noValidate
ref={form}
onSubmit={handleSubmit}
validated={validated}
id="contact-form"
>
<Row>
<Form.Group as={Col} md="12" controlId="nameValidation">
<FloatingLabel
controlId="floatingInput"
label="Name"
className="mb-3"
>
<Form.Control
type="text"
placeholder="Name"
name="user_name"
size="lg"
required
/>
<Form.Control.Feedback type="invalid">
Please enter your name.
</Form.Control.Feedback>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</FloatingLabel>
</Form.Group>
<Form.Group as={Col} md="12" controlId="emailValidation">
<FloatingLabel
controlId="floatingInput"
label="Email"
className="mb-3"
>
<Form.Control
type="email"
placeholder="name#example.com"
name="user_email"
size="lg"
required
/>
<Form.Control.Feedback type="invalid">
Please enter a valid email.
</Form.Control.Feedback>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</FloatingLabel>
</Form.Group>
<Form.Group as={Col} md="12" controlId="messageValidation">
<FloatingLabel
controlId="floatingInput"
label="Message"
className="mb-3"
>
<Form.Control
placeholder="Message"
name="user_message"
size="lg"
required
as="textarea"
rows={3}
/>
<Form.Control.Feedback type="invalid">
Please enter a message.
</Form.Control.Feedback>
<Form.Control.Feedback>Looks good!</Form.Control.Feedback>
</FloatingLabel>
</Form.Group>
</Row>
<Button
type="submit"
value="Send"
variant="primary"
size="lg"
className="mt-3 w-100"
>
SEND
</Button>
</Form>
</div>
</>
);
};
export default Contact;
Could you please share your HTML where you are getting this info?
Even required, you can make the type='email' required so it will validade for you.
if that still a problem (which should not be), then make an IF to validade for you.
Here is an example. You can use the function below to validade if it is an email. Send the email typed by the user via parameter.
const validateEmail = (email) => {
return String(email)
.toLowerCase()
.match(
/^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
);
};
How can we be able to generate another element by clicking on a button? in my case I want to add another input when I click on the button.
import React from 'react';
function App() {
return (
<Form>
<Form.Group controlId="formBasicEmail">
<Form.Control type="email" placeholder="Enter email" />
</Form.Group>
<Button variant="primary">Add another input</Button>
</Form>
);
}
export default App;
import React, { useState} from 'react';
function App() {
const [activeInput, setActiveInput] = useState(false)
const handleClick = () => {
setActiveInput(!activeInput)
}
return (
<Form>
<Form.Group controlId="formBasicEmail">
<Form.Control type="email" placeholder="Enter email" />
</Form.Group>
{ activeInput && <input type="text" placeholder="type something "/> }
<Button variant="primary"
onClick={handleClick}
>Add another input</Button>
</Form>
);
}
export default App;
I am working on a React project, In my project I have one button If I click that button one
model is appearing. In that Model I have two Input tags and three buttons.
Here comes the login, In UI If Input tags have a Value then I have to hide Blue button in UI.
And If In UI If Input tags have no Value then I have to hide Red Buuton in UI this time I have
to show Blue button.
This is App.js
import React, { useState } from 'react';
import './App.css';
import Form from './Form/Form';
function App() {
const [show, setShow] = useState(false)
return (
<div className="App">
<button className='btn btn-danger'
onClick={() => setShow(true)}>Click here</button>
{ show && <Form></Form>}
</div>
);
}
export default App;
This is Form.js
import React, { useState } from 'react';
import './Form.css';
import {
Row,
Col,
Button,
ButtonGroup,
Card,
CardHeader,
CardSubtitle,
CardBody,
CardText,
Container,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
FormGroup,
Label,
Input,
UncontrolledButtonDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem
} from 'reactstrap';
const Form = () => {
const fun = () => {
}
return (
<div>
<Row>
<Col md="6" sm="6" xs="6">
<Modal
isOpen>
<ModalHeader >Add Role</ModalHeader>
<ModalBody>
<FormGroup>
<Label for="exampleName">Name</Label>
<Input
type="text"
name="name"
placeholder="Enter Your Name"
value='Tom'
/>
</FormGroup>
<FormGroup>
<Label for="exampleEmail">Description</Label>
<Input
type="textarea"
name="description"
placeholder="Enter Description"
value='React developer'
/>
</FormGroup>
</ModalBody>
<ModalFooter>
<Button color="secondary">
Cancel
</Button>
<Button className='one' color="primary">
Blue
</Button>
<Button color='danger'>Red</Button>
</ModalFooter>
</Modal>
</Col>
</Row>
</div>
)
}
export default Form
If you feel I am not clear with my doubt please put a comment.
you can check truthy value. If input has value, show 1 button and hide the other
const Form = () => {
const [value1, setValue1] = useState('');
const [value2, setValue2] = useState('');
return (
<div>
<Input
type="text"
name="name"
placeholder="Enter Your Name"
value={value1}
onChange={e => setValue1(e.target.value)}
/>
<Input
type="text"
name="value2"
placeholder="Enter Your Email"
value={value2}
onChange={e => setValue2(e.target.value)}
/>
{(!value1 || !value2) && <Button>Blue</Button>} // Show button if there is some value
{(value1 && value2) && <Button>Rad</Button>} // Show button if field is empty
</div>
);
}
I am working on React project, In that project I have a scenario that is I have to write
Condition for Input tag. The Condition wants to be like this, In my form the Input tag type is
Number, and its min Value is 1001 and max value is 1500. So now what I want is If I type number
Less than 1001 then it should not take that number in Input tag. Someone please help me how to
Write logic like this.
This is Form.js
import React from 'react';
import './aum-company-modal.css';
import { Button, Col, Modal, ModalBody, ModalFooter, ModalHeader, Row, FormGroup, Label, Input, } from 'reactstrap';
const AumCompanyModal = () => {
return (
<Row>
<Col md="6" sm="6" xs="6">
<Modal isOpen
>
<ModalHeader >Add new</ModalHeader>
<ModalBody>
<Row>
<Col md="12" sm="12" xs="12">
<FormGroup>
<Label for="exampleName">Min Value</Label>
<Input
type="text"
name="roleName"
placeholder="Enter minimum value"
value='1000'
/>
</FormGroup>
<FormGroup>
<Label for="exampleName">Max Value</Label>
<Input
type="number"
name="roleName"
placeholder="Enter maximum value"
min='1001' max='1500'
/>
</FormGroup>
</Col>
</Row>
</ModalBody>
<ModalFooter>
<Button color="secondary">
Cancel
</Button>
<Button type="submit" color="primary">
Submit
</Button>
</ModalFooter>
</Modal>
</Col>
</Row>
)
}
export default AumCompanyModal
You input does not have a value property so I would suggest you to make an state to use it as value and the set an onChange which is a function that checks that just like this:
const [ inputValue, setInputValue ] = useState(1000);
handleChange = (e) => {
if (e.target.value > 999 && e.target.value < 1501) {
setInputValue(e.target.value);
}
}
<Input
type="number"
name="roleName"
placeholder="Enter maximum value"
min='1001' max='1500'
onChange={handleChange}
value={inputValue}
/>