Guys I am facing issue with submit button disable function
I have set 3 conditions:
And only if these 3 conditions satisfied will the boolean "allvalid" be set as true
Issues: I discovered that after I fulfilled all the conditions the button is still disabled But when I put 1 more character in the password submit button works, and I delete that 1 character which is still working(now 8 chars), but when I delete one more(now 7) submit button is still enabled, only when I reduce to 6 it's disabled again
I want it to be enabled exactly when all the conditions are fulfilled and disabled immediately when it's not
Here's the code
export function SignupForm(props) {
const { switchToSignin } = useContext(AccountContext);
const [passwordOne, setPasswordOne] = useState("")
// booleans for password validations
const [containsN, setContainsN] = useState(false) // number
const [contains8C, setContains8C] = useState(false) // min 8 characters
// checks all validations are true
const [allValid, setAllValid] = useState(false)
const [terms,setTerms]=useState(false)
// Client shall check on the terms otherwise submit button is disabled
const checkTerms=() => {
setTerms(true)
}
const validatePassword = () => {
// has number
if (/\d/.test(passwordOne)) setContainsN(true)
else setContainsN(false)
// has 8 characters
if (passwordOne.length >= 8) setContains8C(true)
else setContains8C(false)
// all validations passed
if (containsN && contains8C && terms) setAllValid(true)
else setAllValid(false)
}
const handleSubmit=(e)=> {
alert('Submitted' );
e.preventDefault();
}
return (
<BoxContainer>
<FormContainer onSubmit={handleSubmit}>
<Input type="text" placeholder="Full Name" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password"
value={passwordOne}
onChange={e=>setPasswordOne(e.target.value)}
onKeyUp={validatePassword}
/>
<column>
<Condition>
<img className="check" src={contains8C?check:uncheck} alt="icon1" />
8 Characters min.
<img className="check" src={containsN?check:uncheck} alt="icon2" />
One number
</Condition>
</column>
<column>
<Checkbox>
<input type="checkbox" onClick={checkTerms}></input>
</Checkbox>
<Terms align='left'>By creating account, you agree to accept our Privacy policy, Terms of Service and Notification settings.</Terms>
</column>
<Marginer direction="vertical" margin={10} />
<SubmitButton type="submit" value="Submit" disabled={!allValid}>Signup</SubmitButton>
</FormContainer>)
I checked your repository and I think I found the issue.
First thing your SubmitButton component disable property is not working correctly.
So that's why I changed it to basic HTML button to make sure value handled normally.
So new like of button should looks like this:
<button type="submit" value="Submit" disabled={!allValid}>Signup</button>
Another point about checkbox. You need to handle is it checked or not, so new checkbox button should looks this:
<input type="checkbox" onClick={(e)=>checkTerms(e)}></input>
And final step you need to track validation values at form and you should update the state again to make button disabled and enabled. For this purpose, you need to use useEffect hook like this:
useEffect(()=>{
// Track all local states and validate the term
validatePassword()
},[passwordOne,terms,containsN,contains8C,validatePassword]);
and new checkTerms function will be:
const checkTerms=(e) => {
setTerms(e.target.checked)
}
I will put final signupForm.jsx for you:
import React, { useState,useEffect } from 'react';
import { useContext } from "react";
import {
BoldLink,
BoxContainer,
FormContainer,
Input,
MutedLink
} from "./common";
import { Marginer } from "../marginer";
import { AccountContext } from "./accountContext";
import styled from "styled-components";
import check from "./images/check.png";
import uncheck from "./images/uncheck.png";
const Terms = styled.h5`
width: 250px;
color: #000000;
font-weight: 500;
font-size: 10px;
z-index: 10;
margin: 0;
margin-top: 7px;
`;
const Condition= styled.div`
background: #fff;
padding: 3px;
width: 250px;
height: 30px;
float: left;
flex:50%;
font-weight: 500;
font-size: 9px;
color: #000;
margin: 2px;
`;
const Checkbox= styled.div`
background: #fff;
padding: 3px;
width: 30px;
height: 10px;
float: left;
flex:50%;
font-weight: 500;
font-size: 9px;
color: #000;
margin: 2px;
`;
export function SignupForm(props) {
const { switchToSignin } = useContext(AccountContext);
const [passwordOne, setPasswordOne] = useState("")
// booleans for password validations
const [containsN, setContainsN] = useState(false) // number
const [contains8C, setContains8C] = useState(false) // min 8 characters
// checks all validations are true
const [allValid, setAllValid] = useState(false)
const [terms,setTerms]=useState(false)
// labels and state boolean corresponding to each validation
const checkTerms=(e) => {
setTerms(e.target.checked)
}
const validatePassword = () => {
// has number
if (/\d/.test(passwordOne)) setContainsN(true)
else setContainsN(false)
// has 8 characters
if (passwordOne.length >= 8) setContains8C(true)
else setContains8C(false)
// all validations passed
if (containsN && contains8C && terms) setAllValid(true)
else setAllValid(false)
}
const handleSubmit=(e)=> {
alert('Submitted' );
e.preventDefault();
}
useEffect(()=>{
// Track all local states and validate the term
validatePassword()
},[passwordOne,terms,containsN,contains8C,validatePassword]);
return (
<BoxContainer>
<FormContainer onSubmit={handleSubmit}>
<Input type="text" placeholder="Full Name" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password"
value={passwordOne}
onChange={e=>setPasswordOne(e.target.value)}
onKeyUp={validatePassword}
/>
<column>
<Condition>
<img className="check" src={contains8C?check:uncheck} alt="icon1" />
8 Characters min.
<img className="check" src={containsN?check:uncheck} alt="icon2" />
One number
</Condition>
</column>
<column>
<Checkbox>
<input type="checkbox" onClick={(e)=>checkTerms(e)}></input>
</Checkbox>
<Terms align='left'>By creating account, you agree to accept our Privacy policy, Terms of Service and Notification settings.</Terms>
</column>
<Marginer direction="vertical" margin={10} />
<button type="submit" value="Submit" disabled={!allValid}>Signup</button>
</FormContainer>
<Marginer direction="vertical" margin="1em" />
<MutedLink href="#">
Already have an account?
<BoldLink href="#" onClick={switchToSignin}>
Signin
</BoldLink>
</MutedLink>
</BoxContainer>
);
}