Email Validation in React Functional Component - reactjs

Using React functional component, I'm trying to validate the email address. Below is my code.
Problem is when I tried to enter any text nothing happens, its not allowing any letters to be entered.
Below is my component code, Please help me out
const UpdateEmailAddress: React.FC<Step> = (props: Step) => {
const [customerEmail, setCustomerEmail] = useState<any>('');
const [checkValidEmail, setcheckValidEmail] = useState<boolean | null>(null);
const emailValidate = (value: any) => {
if (!validEmailRegex(value)) {
setcheckValidEmail(true);
} else {
setcheckValidEmail(false);
}
};
const handleChange = (e: any) => {
if (e.target.value) {
setCustomerEmail(e.target.value);
}
};
return (
<>
<div className="step container update-email-container pt-10" ref={props.domRef}>
<div className="row">
<div className="col-md-4">
<div className="mb-4">
<TextField
aria-label={content.emailAddress.header}
enableClearText
errormessage={content.emailAddress.emailError}
helptext={content.emailAddress.helptext}
id="emailAddress"
isValid={checkValidEmail}
label={content.emailAddress.emailAddress}
maxLength={0}
name="emailAddress"
tooltipText=""
type="email"
onChange={(e:any) => handleChange(e)}
value={customerEmail}
/>
</div>
<ButtonAction
onClick={emailValidate(customerEmail)}
className="load-more-button mb-0"
type="button"
aria-label={content.emailAddress.nextButton}
>
{content.emailAddress.nextButton}
</ButtonAction>
</div>
</div>
</div>
</>
);
};

Your logic in onChange method is wrong it should be
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setCustomerEmail(e.target.value)}

You have to define the onChange() method.
It should be like this
const handleChange = (e) => {
setCustomerEmail(e.target.value);
};
Then you will be able to enter textfield.
Secondly, you have to pass the value in emailvalidate() in onClick() of button.
<ButtonAction onClick={()=>emailValidate(customerEmail)} className="load-more-button mb-0" type="button" aria-label={content.emailAddress.nextButton}>
{content.emailAddress.nextButton}
</ButtonAction>
And remove e parameter in emailValidate(value) as it is only using value and not e.

Related

Passing values between components in React

I m beginner to reactJS and I m having so much trouble with self learning.
I want to print the data I get from first page.
I used 2 .js files
This is userpage.js:
import resultPage from "./resultPage";
// JS
//const input = document.getElementById('myText');
//const inputValue = input.value
// React
// value, onChange
const Multi = () => {
const [person, setPerson] = useState({ firstName: "", email: "", age: "" });
const [people, setPeople] = useState([]);
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setPerson({ ...person, [name]: value });
};
const handleSubmit = (e) => {
//e.preventDefault();
if (person.firstName && person.email && person.age) {
const newPerson = { ...person, id: new Date().getTime().toString() };
setPeople([...people, newPerson]);
setPerson({ firstName: "", email: "", age: "" });
resultPage(people, person);
}
};
return (
<>
<article className="form">
<form>
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input
type="text"
id="firstName"
name="firstName"
value={person.firstName}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input
type="email"
id="email"
name="email"
value={person.email}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="age">Age : </label>
<input
type="number"
id="age"
name="age"
value={person.age}
onChange={handleChange}
/>
</div>
<button type="submit" className="btn" onClick={handleSubmit}>
add person
</button>
</form>
</article>
</>
);
};
export default Multi;
This has 2 textboxes and a submit button.
This code is from resultPage.js:
function resultPage(people, person) {
return (
<article>
{people.map((person) => {
const { id, firstName, email, age } = person;
return (
<div key={id} className="item">
<h4>{firstName}</h4>
<p>{email}</p>
<p>{age}</p>
</div>
);
})}
</article>
);
}
export default resultPage;
What am I doing wrong? I m new to reactjs. So kindly spare my obvious mistakes and help me.
From React documentation
HTML form elements work a bit differently from other DOM elements in React, because form elements naturally keep some internal state.
You need to add handleSubmit to your form, and it'll work. As #Halcyon suggested, using a Capital case for a component is good. It's tough to distinguish between HTML elements and components if you use lowercase. Read this for more details.
I am attaching a working sandbox for your code.
You're calling resultPage in handleSubmit. That's not going to work. You want resultPage to be part of the rendering, probably conditionally.
Consider something like:
return <>
{person.firstName !== "" && <resultPage people={people} person={person} />}
{person.firstName === "" && <>
// the form
</>}
</>;
Also since resultPage is a component, it's best to capitalize it.
I think you probably want a 3rd component:
const MyComponent = () => {
const [ people, setPeople ] = React.useState([]);
const [ isEditing, setIsEditing ] = React.useState(false);
return <>
{isEditing && <Multi setPeople={(people) => {
setPeople(people);
setIsEditing(false);
}}
{isEditing === false && <resultPage people={people} />}
</>;
}
Mutli now accepts a prop setPeople that is called in handleSubmit.

react simple keyboard not able to type in multiple input

I have following code of Calculator.jsx where everything looks fine.The main thing I want to achieve is keyboard to displayed only on input click which is done but the keyboard does not seem to type though the following code looks fine. Are there any other way to show/hide keyboard only on input click as well as make keyboard be able to type. My code for Calculator.jsx is
Calculator.jsx
import React, { useState, useRef, useEffect } from 'react';
import './Calculator.css'
import { Link } from 'react-router-dom';
import Keyboard from "react-simple-keyboard";
import "react-simple-keyboard/build/css/index.css";
const Calculator = () => {
const [inputs, setInputs] = useState({});
const [layoutName, setLayoutName] = useState("default");
const [inputName, setInputName] = useState("default");
const keyboard = useRef();
const [keyboardVisibility, setKeyboardVisibility] = useState(false);
useEffect(() => {
function clickHanlder(e) {
if (
!(e.target.nodeName === "INPUT") &&
!e.target.classList.contains("hg-button") &&
!e.target.classList.contains("hg-row")
) {
setKeyboardVisibility(false);
}
}
window.addEventListener("click", clickHanlder);
return window.removeEventListener("click", clickHanlder, true);
}, []);
const onChangeAll = inputs => {
setInputs({ ...inputs });
console.log("Inputs changed", inputs);
};
const handleShift = () => {
const newLayoutName = layoutName === "default" ? "shift" : "default";
setLayoutName(newLayoutName);
};
const onKeyPress = button => {
console.log("Button pressed", button);
if (button === "{shift}" || button === "{lock}") handleShift();
};
const onChangeInput = event => {
const inputVal = event.target.value;
setInputs({
...inputs,
[inputName]: inputVal
});
keyboard.current.setInput(inputVal);
};
const getInputValue = inputName => {
return inputs[inputName] || "";
};
return (
<div>
<div className="bg">
<div className="deposit">
<div className="header">
<h1>Deposit Calculator</h1>
<div className="form">
<form className="calculator">
<div className="form-group">
<label for="depositAmount">Deposit Amount:</label>
<span className="rupees">Rs</span>
<input className="IInput"
type="text"
name='depositAmount'
placeholder='0'
value={getInputValue("depositAmount")}
onChange={onChangeInput}
onFocus={() => {
setKeyboardVisibility(true);
setInputName("depositAmount")
}}
/>
</div>
<div className="form-group">
<label for="interestRate">Interest Rate:</label>
<input className= "IIinput"
type="text"
name='Interest'
placeholder='0'
value={getInputValue("interestRate")}
onChange={onChangeInput}
onFocus={() => {
setKeyboardVisibility(true);
setInputName("interestRate")
}}
/>
<span className= "percent">%</span>
</div>
<div class="form-group">
<label for="Tenure">Tenure:</label>
<input className="Input"
type='number'
min='1'
max='5'
name='tenure'
placeholder='1 year'
value={getInputValue("tenure")}
onChange={onChangeInput}
onFocus={() => {
setKeyboardVisibility(true);
setInputName("tenure")
}}
/>
</div>
{ keyboardVisibility && (
<Keyboard
keyboardRef={(r) => (keyboard.current = r)}
layoutName={layoutName}
onChange={onChangeAll}
onKeyPress={onKeyPress}
/>
)}
</form>
<button className="calculate">Calculate
</button>
</div>
<div className="given">
<p >
Total Deposit: Rs 0
</p>
<p>
Interest: Rs 0
</p>
<p>
Maturity Amount: Rs 0
</p>
</div>
</div>
</div>
</div>
<Link to="/">
<button className="Back">
<i class="fas fa-angle-double-left"></i>
</button>
</Link>
</div>
);
};
export default Calculator;
You are setting the inputs state by spreading input string from keyboard onChangeAll into an object setInputs({ ...inputs }). If I enter ab it will set as {0: "a", 1:"b"}.
Update the onChange prop in Keyboard to onChangeAll and pass inputName prop with your inputName state value. Read react-simple-keyboard DOCS.
onChangeAll
const onChangeAll = (inputs) => {
console.log("Inputs changed", inputs);
setInputs(inputs);
};
Keyboard
{keyboardVisibility && (
<Keyboard
keyboardRef={(r) => (keyboard.current = r)}
layoutName={layoutName}
onChangeAll={onChangeAll}
onKeyPress={onKeyPress}
inputName={inputName}
/>
)}
CodeSandbox link

Need little help on React hooks

I try to make a todo list with React and Redux Toolkit. In handleSubmit function to add item on list, my setText somehow not set the value to empty string.
Here are my full code on Stackblitz: https://stackblitz.com/edit/react-ts-bqmjz1?file=components%2FTodoForm.tsx
const TodoForm = (): JSX.Element => {
//Input value
const [text, setText] = useState('');
const dispatch = useDispatch();
//setText not working
const handleSubmit = (e: any) => {
e.preventDefault();
if (text.trim().length === 0) {
return;
}
dispatch(addItem({ title: text }));
setText('');
};
return (
<form className="container-fluid" onSubmit={handleSubmit}>
<div className="input-group">
<input
className="form-control"
placeholder="Enter the value..."
onChange={(e: { target: HTMLInputElement }) =>
setText(e.target.value)
}
/>
{/* Submit button */}
<button type="submit" className="btn btn-primary">
Add
</button>
</div>
</form>
);
};
You're very close! You just missed the value prop on the input:
value={text}
const TodoForm = (): JSX.Element => {
//Input value
const [text, setText] = useState('');
const dispatch = useDispatch();
//setText not working
const handleSubmit = (e: any) => {
e.preventDefault();
if (text.trim().length === 0) {
return;
}
dispatch(addItem({ title: text }));
setText('');
};
return (
<form className="container-fluid" onSubmit={handleSubmit}>
<div className="input-group">
<input
className="form-control"
placeholder="Enter the value..."
value={text}
onChange={(e: { target: HTMLInputElement }) =>
setText(e.target.value)
}
/>
{/* Submit button */}
<button type="submit" className="btn btn-primary">
Add
</button>
</div>
</form>
);
};
If I understood well the input does not become empty when you click on the add button. To do that you just have to add value={text} in your input
<input
className="form-control"
placeholder="Enter the value..."
value={text}
onChange={(e: { target: HTMLInputElement }) =>
setText(e.target.value)
}
/>

How do I add a task in a react to-do app by pressing ENTER key?

I am new to react.js .
I made a simple to-do app to learn CRUD using react.js:
A task is added when I click the '+' button. But I need to add a task when I click the 'ENTER' Key.
What should I do?
Here's A Part Of My Code :
JSX :
function Body() {
const [toDos,setToDos] = useState([])
const [toDo,setToDo] = useState('')
const deleteTodo = idToDelete => setToDos(currentTodos => currentTodos.filter(toDo => toDo.id !== idToDelete))
return (
<div className="bodyoftodo">
<div className="input">
<form onSubmit={toDo} >
<input value={toDo} onChange={(e)=>setToDo(e.target.value)} type="text" placeholder="🖊️ Add item..." />
<i onClick={()=>setToDos([...toDos,{id:Date.now() ,text: toDo, status: false}])} className="fas fa-plus"></i>
</form>
</div>
<div className="todos">
{toDos.map((obj)=>{
return(
<div className="todo">
<div className="left">
<input onChange={(e)=>{
console.log(e.target.checked);
console.log(obj);
setToDos(toDos.filter(obj2=>{
if(obj2.id===obj.id){
obj2.status=e.target.checked
}
You can do it with set a function on onKeyPress event.
handleKeyPress = (event) => {
if(event.key === 'Enter'){
setToDos([...toDos,{id:Date.now() ,text: toDo, status: false}])
setToDo("");
}
}
return(
<div>
<input value={toDo} onChange={(e)=>setToDo(e.target.value)} type="text"
placeholder="🖊️ Add item..." onKeyPress={handleKeyPress} />
</div>
);
}
You could wrap the input and button in a form and include the function to add a task in the onsubmit attribute of the form. That way, the function gets called whether you click the button or press enter.
Like so:
const AddToDo = () => {
// ...state
const [todoText, setTodoText] = useState('');
const handleSubmit = (e) => {
e.preventDefault(); //stop default action of form
//....call add todo function
setTodoText(''); //clear input
}
return (
<form onSubmit={handleSubmit}>
<input type='text' onChange={ ({ target }) => setToDoText(target.value)}>
<button type='submit'>Add ToDo</button>
</form>
)
}
In this case, clicking on the button or pressing enter would trigger the handleSubmit function.
If you are using a form you can do the below by adding on the onSubmit
import { useState } from "react";
export default function App() {
const [todos, setTodos] = useState([]);
const [todo, setTodo] = useState("");
const handleAddTodo = (e) => {
e.preventDefault()
setTodos([...todos, todo]);
setTodo("");
};
const handleChange = (e) => {
setTodo(e.target.value);
};
return (
<div className="App">
<h2>Todos</h2>
<form onSubmit={handleAddTodo}>
<label>
New Todo
<input value={todo} onChange={handleChange} />
</label>
</form>
<ul>
{todos.map((t, i) => (
<li key={i}>{t}</li>
))}
</ul>
</div>
);
}
Else, you can just use the input and hook up a listener on Key Up / Key Down and if the Key Code is Enter (13).You can trigger to add the Todo
const handleKeyUp = (e) =>{
if(e.keyCode === 13){
handleAddTodo()
}
}
Full Example In Codesandbox https://codesandbox.io/s/ancient-sunset-mr55h?file=/src/App.js:239-325
One option could be to make it form by wrapping your input field and button inside the form tag and then give type="submit" to the button
or you could attach event listner with enter key

How to do validation using useRef()

How do I validate input box value using useRef .
Initial validation is not required once user clicks on input box and comes out then it should validate if input box is empty it should show input box cannot be empty.
Codesandbox Link
code i tried. using onBlur
export default function App() {
const name = React.useRef("");
const nameBlurData = (name) => {
console.log("name", name);
};
return (
<div className="App">
<form>
<input
onBlur={() => nameBlurData(name.current.value)}
type="text"
ref={name}
placeholder="Enter First Name"
/>
// show error message here
</form>
</div>
);
}
You can use "useRef" to validate the value of an input field.
No need to use "useState".
Below code is a basic implementation of OP's question
You can replace the "console.log" with your alert component.
import { useRef } from "react";
const ComponentA = () => {
const emailRef = useRef(null);
const passwordRef = useRef(null);
const onBlurHandler = (refInput) => {
if (refInput.current?.value === "") {
console.log(`${refInput.current.name} is empty!`);
}
}
return (
<form>
<input ref={emailRef} onBlur={onBlurHandler.bind(this, emailRef)} />
<input ref={passwordRef} onBlur={onBlurHandler.bind(this, passwordRef)} />
<form/>
)
}
Link to "useRef"
Note: Not tested, code typed directly to SO's RTE
You can use a local state and conditionally render an error message like this:
const [isValid, setIsValid] = useState(true)
const nameBlurData = (name) => {
setIsValid(!!name);
};
return (
<div className="App">
<form>
<input
onBlur={() => nameBlurData(name.current.value)}
type="text"
ref={name}
placeholder="Enter First Name"
/>
{!isValid && <span> input must not be empty </span> }
</form>
Note that you don't really need a ref in this case, you can just use the event object like:
onBlur={(event) => nameBlurData(event.target.value)}
You need to use useState hook to update the value of the name property. Using ref is not ideal here.
Live demo https://stackblitz.com/edit/react-apqj86?devtoolsheight=33&file=src/App.js
import React, { useState } from 'react';
export default function App() {
const [name, setName] = useState('');
const [hasError, setError] = useState(false);
const nameBlurData = () => {
if (name.trim() === '') {
setError(true);
return;
}
setError(false);
};
return (
<div className="App">
<form>
<input
onBlur={nameBlurData}
type="text"
value={name}
onChange={e => setName(e.target.value)}
placeholder="Enter First Name"
/>
{hasError ? <p style={{ color: 'red' }}>Name is required</p> : null}
</form>
</div>
);
}

Resources