Multiple required conditions of an input with .includes() method - reactjs

I'm making validation of an email input in my React App, but I want that input should have both # and .(dot) while submitting the form. I tried the .some() method but if only one condition is true then it will return true but I want both:
const emailValidation = ["#", "."];
<input
type="text"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
onBlur={(e) => {
setIsEmailValid(
emailValidation.some((el) => e.target.value.includes(el))
);
}}
/>

<input
type="text"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
onBlur={(e) => {
setIsEmailValid(
emailValidation.every((el) => e.target.value.includes(el))); }}
/>
Here you just need to use every() method instead of some()

Related

How can i put value in input?

Why can't I put a value in the input? The problem is: I need to put a 'name' in <Form.Item> to apply the rules. Without that, the rules will not be able to work, but if you remove the name="userName" from <Form.Item the value appears at the input.
How can i solve that?
<Form autoComplete="off" layout="vertical" onFinish={handleFinish}>
<Form.Item name="userName" rules={getTextRule('name')}>
<Input value={fields?.firstName} name="firstName" onChange={(e) => {
handleInputChange(e)
}} />
</Form.Item>
</Form.Item>
simple we can code like
const [text,setText] = useState('')
return(
<input type='text' value={text} onChange={e=>setText(e.target.value)}/>
)
If you use the form you can let Ant Form manage the state by removing the value & the onChange props on the <Input />.
Else if you manage the state by yourself make sure to get the value from the e.target.value.
ex:
const [fields, setFields] = useState({})
const handleOnChange = (e) => {
setFields((state) => {
...state,
[e.target.name]: e.target.value,
})
}
return (
<Input
name="firstName"
value={fields.firstName}
onChange={handleOnChange}
/>
)

save values of arrays inside a state from different input fields

i want to get the values from 5 input fields and save them inside a single state of arrays , how can i achieve that ?
const [features,setFeatures] = useState([]);
const handleChange = e => {
setFeatures(prev => ({ ...prev, features, [e.target.name]: e.target.value }))
}
<Input type="text" name="features" label="Feature 1" value={features} required change={handleChange} />
<Input type="text" name="features" label="Feature 2" value={features} required change={handleChange} />
<Input type="text" name="features" label="Feature 3" value={features} required change={handleChange} />
<Input type="text" name="features" label="Feature 4" value={features} required change={handleChange} />
<Input type="text" name="features" label="Feature 5" value={features} required change={handleChange} />
You can check the below implementation
Note that I hardcoded the array length and I'd assume your input array is static. If your input array is dynamic, you can use iteration for generating input fields. Besides that, I modified Input to input and change to onChange for the primitive input element. The button and form are for demo only.
const App = () => {
const [features,setFeatures] = React.useState(new Array(5));
const handleChange = (e,index) => {
const updatedFeatures = [...features] //clone data
updatedFeatures[index] = e.target.value
setFeatures(updatedFeatures)
}
const handleSubmit = (e) => {
e.preventDefault();
console.log(features);
}
return (<form onSubmit={handleSubmit}><input type="text" name="features" label="Feature 1" value={features[0]} required onChange={(e) => handleChange(e, 0)} />
<input type="text" name="features" label="Feature 2" value={features[1]} required onChange={(e) => handleChange(e, 1)} />
<input type="text" name="features" label="Feature 3" value={features[2]} required onChange={(e) => handleChange(e, 2)} />
<input type="text" name="features" label="Feature 4" value={features[3]} required onChange={(e) => handleChange(e, 3)} />
<input type="text" name="features" label="Feature 5" value={features[4]} required onChange={(e) => handleChange(e, 4)} />
<button type="submit">Submit</button>
</form>)
}
ReactDOM.render(
<App/>,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

I have prevented default behaviour of form on submit, but it still sending post request automatically to current url

<form
className="login"
onSubmit={e => {
alert('hey getting called')
e.preventDefault()
this.authorizeUser(e)
}}
>
<input
type="text"
name="email"
onChange={e => this.handleInputChange(e)}
value={email}
className="login-input"
placeholder="Email Adress"
autoFocus
/>
<input
type="password"
name="password"
onChange={e => this.handleInputChange(e)}
value={password}
className="login-input"
placeholder="Password"
/>
<button
type="submit"
style={{height: '37px', float: 'left'}}
className="login-button"
>
Login
</button>
</form>
code is not reaching up to alert statement.
instead i see url changes to ->
http://localhost:3000/signin?email=testUSer%40abx.in&password=1234567 and page gets refreshed
This issue is happening after i updated react version from 16.9 to 17.0.0.
UPDATE
When i add the listener via add event listener inside componentDidMount() then suddenly it started working as expected!
still wonder why the onSubmit directly on form didn't work

Not able to see typed text in input using react hooks and controlled components

//The value coming from the input that triggered the event is getting updated in the state but not displaying in the browser, I don't really understand what's happening, I have been using the same method to update the state in my other project
import React, { useState } from "react";
const Register=()=>{
const [user,setUser]=useState({
name:"",
email:"",
password:"",
reenterPassword:""
});
let changeHandler=(e)=>{
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
return(
<div className="register">
<h1>Register</h1>
<input onChange={changeHandler} name="Username" placeholder="Please Enter Your Name" type="text" defaultValue="" value={user.name}/>
<input onChange={changeHandler} name="Email" placeholder="Enter your Email" type="email" value={user.email}/>
<input onChange={changeHandler} name="Password" placeholder="Create Your Password" type="password" value={user.password}/>
<input onChange={changeHandler} name="ReEnterPassword" placeholder="Re-Enter Your Password" type="password" value={user.reenterPassword}/>
<div className="button">Register</div>
<div>OR</div>
<div className="button">Login</div>
</div>
)
}
export default Register;
[1]: https://i.stack.imgur.com/G8beV.png
there is good answer here about it: https://stackoverflow.com/a/58877875/2091359
you should not use useState like this, you can do useState for each input separately like this:
const [name, setName] = useState('')
const handleChangeName = (e) => {
setName(e.target.value);
}
return(
<div className="register">
<h1>Register</h1>
<input onChange={handleChangeName} name="Username" placeholder="Please Enter Your Name" type="text" value={name}/>
...
or use useReduce
Try this code:
const Register=()=>{
const [user,setUser]=useState({
Username:"",
Email:"",
Password:"",
ReEnterPassword:""
});
let changeHandler=(e)=>{
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
return (
<div className="register">
<h1>Register</h1>
<input onChange={(e)=>changeHandler(e)} name="Username" placeholder="Please Enter Your Name" type="text" defaultValue="" value={user.name}/>
<input onChange={(e)=>changeHandler(e)} name="Email" placeholder="Enter your Email" type="email" value={user.email}/>
<input onChange={(e)=>changeHandler(e)} name="Password" placeholder="Create Your Password" type="password" value={user.password}/>
<input onChange={(e)=>changeHandler(e)} name="ReEnterPassword" placeholder="Re-Enter Your Password" type="password" value={user.reenterPassword}/>
<div className="button">Register</div>
<div>OR</div>
<div className="button">Login</div>
</div>
);
}
export default Register;
You need to use the same name for the html input attribute too, and try to use callback in the onChange event.

Toggle Password Visibility for multiple password inputs

So if I'm using on input I can toggle password visibility.
I'm having trouble with it only toggling one input at a time.
D
Currently my code looks like this..
const [isPasswordShown, setPasswordShown] = useState(false);
const togglePassword = () => {
setPasswordShown(isPasswordShown ? false : true);
};
const renderTogglePasswordIcon = () => {
return (
<FontAwesomeIcon
onClick={togglePassword}
icon={isPasswordShown ? faEye : faEyeSlash}
/>
);
};
<Input
variant={InputVariants.text}
type={isPasswordShown ? "text" : "password"}
name="password"
label="Password"
error={errors.password?.message}
onChange={(e) => handlePasswordInput(e)}
ref={register}
/>
<i>{renderTogglePasswordIcon()}</i>
<Input
variant={InputVariants.text}
type={isPasswordShown ? "text" : "password"}
name="passwordConfirmation"
label="Confirm Password"
error={errors.passwordConfirmation?.message}
ref={register}
onChange={(e) => confirmPassword(e)}
/>
<i>{renderTogglePasswordIcon()}</i>
Do you want to toggle the inputs separately or only one of the inputs?
I would only use the toggle function for one input element. So you can set the html type to password hardcoded in the second element:
<Input
variant={InputVariants.text}
type={isPasswordShown ? "text" : "password"}
name="password"
label="Password"
error={errors.password?.message}
onChange={(e) => handlePasswordInput(e)}
ref={register}
/>
<i>{renderTogglePasswordIcon()}</i>
<Input
variant={InputVariants.text}
type="password"
name="passwordConfirmation"
label="Confirm Password"
error={errors.passwordConfirmation?.message}
ref={register}
onChange={(e) => confirmPassword(e)}
/>
<i>{renderTogglePasswordIcon()}</i>
Otherwise you can use a second parameter

Resources