React-redux password strength bar not working - javascript

Hi I want to add a progress strength bar for my password but not sure how to link an "eventlistner" in react. So far the code works for checking the password regex but not sure how to add the password strength bar. I don't know how to use addEventListener in react.
Please have a look at my code and tell me what am I doing wrong? Thanks.
import React from 'react'
import {connect} from 'react-redux'
import {registerUserRequest} from '../../actions/register'
import {loginError} from '../../actions/login'
class Register extends React.Component {
constructor(props) {
super(props)
this.state = {
user_name: '',
contact_number: '',
email_address: '',
password: '',
confirm_password: ''
}
this.updateDetails = this.updateDetails.bind(this)
this.submit = this.submit.bind(this)
this.validateEmail = this.validateEmail.bind(this)
this.validatePassword = this.validatePassword.bind(this)
}
componentDidMount() {
this.props.dispatch(loginError(''))
}
updateDetails(e) {
this.setState({[e.target.name]: e.target.value})
}
submit(e) {
e.preventDefault()
e.target.reset()
let {user_name, password, confirm_password, email_address,
contact_number} = this.state
function confirmation (){
if (confirm_password != password)
return false
else
return true
}
const isEmail = this.validateEmail(email_address)
const passwordsNotSame = (confirm_password != password)
const isPass = this.validatePassword(password)
if (!isEmail || passwordsNotSame) return
this.props.dispatch(loginError("Incorrect email/Passwords don't
match"))
else if (!isPass) return this.props.dispatch(loginError('Password
strength must be 8 or above and must include atleast one number '))
else return this.props.dispatch(registerUserRequest(this.state))
}
validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\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,}))$/;
var isValid = re.test(String(email).toLowerCase());
// console.log('No joke', isValid)
return isValid
}
validatePassword(pass) {
var re = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/;
var isPasswordValid = re.test(String(pass));
return isPasswordValid
}
const pass = document.getElementById("password")
pass.addEventListener('keyup', function() {
checkPassword(pass.value)
})
checkPassword(password) {
var strengthBar = document.getElementById("strength")
var strength = 0;
if (password.match(/[a-zA-Z0-9][a-zA-Z0-9]+/)) {
strength += 1
}
if (password.match(/[~<>]+/)) {
strength +=1
}
if (password.match(/[!#£$%^&()]+/)) {
strength +=1
} if (password.length > 5) {
strength +=1
}
switch(strength) {
case 0:
strengthBar.value = 20;
break
case 1:
strengthBar.value = 40;
break
case 2:
strengthBar.value = 60;
break
case 3:
strengthBar.value = 80;
break
case 4:
strengthBar.value = 100;
break
}
}
render() {
const {auth} = this.props
return (
<form onSubmit={this.submit}>
<h1>Register</h1>
<hr />
<b>{auth.errorMessage && <span>{auth.errorMessage}</span>}</b>
<div className="field is-horizontal">
<div className="field-label is-normal">
<label>Username</label >
</div>
<input className="input is-medium"required placeholder="User
Name" type="text" name="user_name" onChange={this.updateDetails}/>
</div>
<div className="field is-horizontal">
<div className="field-label is-normal">
<label>Contact Number</label>
</div>
<input className="input is-medium"required placeholder="Contact
Number" type="text" name="contact_number" onChange=
{this.updateDetails}/>
</div>
<div className="field is-horizontal">
<div className="field-label is-normal">
<label>Email Address</label>
</div>
<div className="field-body">
<div className="field">
<input className="input is-medium"required
placeholder="Email Address" type="text" name="email_address" onChange=
{this.updateDetails}/>
</div>
</div>
</div>
<div className="field is-horizontal">
<div className="field is-horizontal">
<label>Password</label>
<progress max="100" value="0" id="strength"></progress>
</div>
<input className="input is-medium"required
placeholder="Password" type="password" name="password" onChange=
{this.updateDetails}/>
</div>
<div className="field is-horizontal">
<div className="field is-horizontal">
<label>Confirm Password</label>
</div>
<input className="input is-medium"required
placeholder="Confirm Password" type="password" name="confirm_password"
onChange={this.updateDetails}/>
</div>
<input className="button is-primary" value="Register"
type="submit" />
</form>
)
}
}
const mapStateToProps = ({auth}) => ({auth})
export default connect(mapStateToProps)(Register)

This are some changes you can make in your component,
In progress component,
<progress max="100" value={(this.state.password_strength * 20)} id="strength"></progress>
in password input,
<input className="input is-medium"required
placeholder="Password" type="password" name="password" onChange=
{this.updateDetails} onKeyUp={this.checkPassword}/>
In your constructor, initializing password_strength and binding method checkPassword
constructor(props) {
super(props)
this.state = {
user_name: '',
contact_number: '',
email_address: '',
password: '',
confirm_password: '',
password_strength: 0,
}
this.updateDetails = this.updateDetails.bind(this)
this.submit = this.submit.bind(this)
this.validateEmail = this.validateEmail.bind(this)
this.validatePassword = this.validatePassword.bind(this)
this.checkPassword = this.checkPassword.bind(this);
}
and finally, your checkPassword method,
checkPassword(e) {
const password = e.target.value;
const password_strength = 0;
var strength = this.state.password_strength;
if (password.match(/[a-zA-Z0-9][a-zA-Z0-9]+/)) {
strength += 1
}
if (password.match(/[~<>]+/)) {
strength +=1
}
if (password.match(/[!#£$%^&()]+/)) {
strength +=1
} if (password.length > 5) {
strength +=1
}
this.setState({password_strength: strength});
}
If still doesn't work, Please share your working code on codepen.

Related

How to properly change the button disabled state in a useReducer based off of password fields matching?

I am working with a basic form. The form contains a username field, email field, password field, and a repeated password field. I'm trying to solve state management by throwing the form state in a useReducer. However, I'm not getting the buttonDisabled state to properly calculate out to what it should be. The goal is for the button to be disabled on load, and then when all fields are not empty, and when the password field and the repeated password fields match, the button will enable.
SignUpReducer.js
userName: "",
email: "",
password: "",
repeatedPassword: "",
buttonDisabled: true
}
export const formReducer = (state, action) => {
console.log(state, "STATE");
console.log(state.buttonDisabled, "BUTTON DISABLED?");
switch(action.type) {
case "Handle Input Text":
return {
[action.field]: action.payload,
buttonDisabled: state.password === state.repeatedPassword,
};
default:
return state;
}
}
SignUpPage.js
import React from "react";
import { useReducer } from "react";
import { formReducer, initialState } from "./SignUpReducer";
const SignUpPage = () => {
const [state, dispatch] = useReducer(formReducer, initialState);
const handleTextChange = (e) => {
dispatch({
type: "Handle Input Text",
field: e.target.name,
payload: e.target.value,
});
}
return (
<>
<h1>Sign Up</h1>
<label htmlFor="username">Username</label>
<input type="text" name="userName" value={state.userName} onChange={handleTextChange} id="username"/>
<label htmlFor="email">E-mail</label>
<input type="text" name="email" value={state.email} onChange={handleTextChange} id="email"/>
<label htmlFor="password">Password</label>
<input name="password" value={state.password} onChange={handleTextChange} type="password" id="password"/>
<label htmlFor="repeatedPassword">Repeat Password</label>
<input name="repeatedPassword" value={state.repeatedPassword} onChange={handleTextChange} type="password" id="repeatedPassword"/>
<button className="btn-primary" disabled={state.buttonDisabled}>Sign Up</button>
</>
)
};
export default SignUpPage;
You'll need to update the fields state before checking the disabled status of the button:
const { useReducer } = React;
const initialState = {
userName: "",
email: "",
password: "",
repeatedPassword: "",
buttonDisabled: true
}
const formReducer = (state, action) => {
switch(action.type) {
case "Handle Input Text":
const { buttonDisabled, ...fieldsState } = state;
// update the field
const form = {
...fieldsState,
[action.field]: action.payload,
};
// compute disabled with new values of fields
const disabled =
!Object.values(form).every(Boolean) // are all values filled
|| form.password !== form.repeatedPassword; // are the password identical
return {
...form,
buttonDisabled: disabled
};
default:
return state;
}
}
const SignUpPage = () => {
const [state, dispatch] = useReducer(formReducer, initialState);
const handleTextChange = (e) => {
dispatch({
type: "Handle Input Text",
field: e.target.name,
payload: e.target.value,
});
}
return (
<div>
<h1>Sign Up</h1>
<label htmlFor="username">Username</label>
<input type="text" name="userName" value={state.userName} onChange={handleTextChange} id="username"/>
<label htmlFor="email">E-mail</label>
<input type="text" name="email" value={state.email} onChange={handleTextChange} id="email"/>
<label htmlFor="password">Password</label>
<input name="password" value={state.password} onChange={handleTextChange} type="password" id="password"/>
<label htmlFor="repeatedPassword">Repeat Password</label>
<input name="repeatedPassword" value={state.repeatedPassword} onChange={handleTextChange} type="password" id="repeatedPassword"/>
<button className="btn-primary" disabled={state.buttonDisabled}>Sign Up</button>
</div>
)
};
ReactDOM.createRoot(root)
.render(<SignUpPage />)
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id="root"></div>
A better option would be to remove the disabledButton state from the reducer, because it's derived from the form state. You can also minimize the reducer by passing it an update object, and spreading it over the existing state:
const { useReducer } = React;
const initialState = {
userName: "",
email: "",
password: "",
repeatedPassword: "",
}
const formReducer = (state, update) => ({
...state,
...update,
});
const SignUpPage = () => {
const [state, dispatch] = useReducer(formReducer, initialState);
const handleTextChange = (e) => {
dispatch({ [e.target.name]: e.target.value });
}
const disabled =
!Object.values(state).every(Boolean) // are all values filled
|| state.password !== state.repeatedPassword; // are the password identical
return (
<div>
<h1>Sign Up</h1>
<label htmlFor="username">Username</label>
<input type="text" name="userName" value={state.userName} onChange={handleTextChange} id="username"/>
<label htmlFor="email">E-mail</label>
<input type="text" name="email" value={state.email} onChange={handleTextChange} id="email"/>
<label htmlFor="password">Password</label>
<input name="password" value={state.password} onChange={handleTextChange} type="password" id="password"/>
<label htmlFor="repeatedPassword">Repeat Password</label>
<input name="repeatedPassword" value={state.repeatedPassword} onChange={handleTextChange} type="password" id="repeatedPassword"/>
<button className="btn-primary" disabled={disabled}>Sign Up</button>
</div>
)
};
ReactDOM.createRoot(root)
.render(<SignUpPage />)
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id="root"></div>
If you want all logic to be separated from the view, you can extract it by creating a custom hook:
const { useReducer, useCallback } = React;
const initialState = {
userName: "",
email: "",
password: "",
repeatedPassword: "",
}
const formReducer = (state, update) => ({
...state,
...update,
});
const useLoginForm = () => {
const [form, dispatch] = useReducer(formReducer, initialState);
const handleTextChange = useCallback(e => {
dispatch({ [e.target.name]: e.target.value });
}, []);
const buttonDisabled =
!Object.values(form).every(Boolean) // are all values filled
|| form.password !== form.repeatedPassword; // are the password identical
return {
form,
handleTextChange,
buttonDisabled
};
};
const SignUpPage = () => {
const {
form,
handleTextChange,
buttonDisabled
} = useLoginForm();
return (
<div>
<h1>Sign Up</h1>
<label htmlFor="username">Username</label>
<input type="text" name="userName" value={form.userName} onChange={handleTextChange} id="username"/>
<label htmlFor="email">E-mail</label>
<input type="text" name="email" value={form.email} onChange={handleTextChange} id="email"/>
<label htmlFor="password">Password</label>
<input name="password" value={form.password} onChange={handleTextChange} type="password" id="password"/>
<label htmlFor="repeatedPassword">Repeat Password</label>
<input name="repeatedPassword" value={form.repeatedPassword} onChange={handleTextChange} type="password" id="repeatedPassword"/>
<button className="btn-primary" disabled={buttonDisabled}>Sign Up</button>
</div>
)
};
ReactDOM.createRoot(root)
.render(<SignUpPage />)
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id="root"></div>

Maximum update depth exceeded with useEffect & map

I am facing this when I am trying to set form error object. Basically, I want to show the errors below each input field. In response, I am getting an array of objects how do I set to my error object?
Error - Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
import axios from "axios";
import React, { useState, useEffect, useCallback } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { register } from "../actions/userActions";
const Register = () => {
const [countriesList, setCountriesList] = useState("");
const [userRegistration, setUserRegistration] = useState({
firstName: "",
lastName: "",
email: "",
password: "",
fullAddress: "",
city: "",
zipCode: "",
country: "",
phone: "",
terms: true,
});
const [userRegistrationError, setUserRegistrationError] = useState({
firstNameError: "",
lastNameError: "",
emailError: "",
passwordError: "",
fullAddressError: "",
cityError: "",
zipCodeError: "",
countryError: "",
phoneError: "",
termsError: "",
});
const dispatch = useDispatch();
const userRegister = useSelector((state) => state.userRegister);
const { loading, errors, success } = userRegister;
useEffect(() => {
const countries = async () => {
try {
const { data } = await axios.get(
`https://restcountries.eu/rest/v2/all`
);
setCountriesList(data);
} catch (err) {
console.error(err);
}
};
countries();
}, []);
useEffect(() => {
const handleErrors = (errors) => {
errors.map((error) => {
if (error.param === "firstname") {
setUserRegistrationError({
...userRegistrationError,
firstNameError: error.msg,
});
}
if (error.param === "email") {
setUserRegistrationError({
...userRegistrationError,
emailError: error.msg,
});
}
return null;
});
};
if (errors) {
handleErrors(errors);
}
}, [errors, setUserRegistrationError]);
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setUserRegistration({ ...userRegistration, [name]: value });
};
const handleChkChange = (e) => {
const checked = e.target.checked;
console.log(checked);
setUserRegistration({ ...userRegistration, terms: checked });
};
const handleSubmit = (e) => {
e.preventDefault();
try {
dispatch(register());
} catch (error) {
console.error(error);
}
};
return (
<div className="form_container">
<form action="" onSubmit={handleSubmit}>
<div className="row no-gutters">
<div className="col-6 pr-1">
<div className="form-group">
<div className="form-group">
<input
type="text"
name="firstName"
className="form-control"
placeholder="First Name*"
value={userRegistration.firstName}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.firstNameError &&
userRegistrationError.firstNameError}
</p>
</div>
</div>
</div>
<div className="col-6 pr-1">
<div className="form-group">
<input
type="text"
className="form-control"
name="lastName"
placeholder="Last Name*"
value={userRegistration.lastName}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.lastNameError &&
userRegistrationError.lastNameError}
</p>
</div>
</div>
</div>
<hr />
<div className="private box">
<div className="row no-gutters">
<div className="col-6 pr-1">
<div className="form-group">
<input
type="email"
className="form-control"
name="email"
id="email_2"
placeholder="Email*"
value={userRegistration.email}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.emailError &&
userRegistrationError.emailError}
</p>
</div>
</div>
<div className="col-6 pl-1">
<div className="form-group">
<input
type="password"
className="form-control"
name="password"
id="password_in_2"
placeholder="Password*"
value={userRegistration.password}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.passwordError &&
userRegistrationError.passwordError}
</p>
</div>
</div>
<div className="col-12">
<div className="form-group">
<input
type="text"
name="fullAddress"
className="form-control"
placeholder="Full Address*"
value={userRegistration.fullAddress}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.fullAddressError &&
userRegistrationError.fullAddressError}
</p>
</div>
</div>
</div>
{/* /row */}
<div className="row no-gutters">
<div className="col-6 pr-1">
<div className="form-group">
<input
type="text"
className="form-control"
placeholder="City*"
name="city"
value={userRegistration.city}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.cityError &&
userRegistrationError.cityError}
</p>
</div>
</div>
<div className="col-6 pl-1">
<div className="form-group">
<input
type="text"
className="form-control"
placeholder="Postal Code*"
name="zipCode"
value={userRegistration.zipCode}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.zipCodeError &&
userRegistrationError.zipCodeError}
</p>
</div>
</div>
</div>
{/* /row */}
<div className="row no-gutters">
<div className="col-6 pr-1">
<div className="form-group">
<div className="custom-select-form">
<select
className="wide add_bottom_10 form-control"
name="country"
id="country"
value={userRegistration.country}
onChange={handleChange}
>
<option>Country*</option>
{countriesList &&
countriesList.map((country) => (
<option
key={country.alpha2Code}
value={country.alpha2Code}
>
{country.name}
</option>
))}
</select>
<p className="form-vald-error">
{userRegistrationError.countryError &&
userRegistrationError.countryError}
</p>
</div>
</div>
</div>
<div className="col-6 pl-1">
<div className="form-group">
<input
type="text"
className="form-control"
placeholder="Telephone *"
name="phone"
value={userRegistration.phone}
onChange={handleChange}
/>
<p className="form-vald-error">
{userRegistrationError.phoneError &&
userRegistrationError.phoneError}
</p>
</div>
</div>
</div>
{/* /row */}
</div>
<hr />
<div className="form-group">
<label className="container_check">
Accept <Link to="#0">Terms and conditions</Link>
<input
type="checkbox"
name="terms"
checked={userRegistration.terms}
onChange={handleChkChange}
/>
<span className="checkmark" />
<p className="form-vald-error">
{userRegistrationError.termsError &&
userRegistrationError.termsError}
</p>
</label>
</div>
<div className="text-center">
<input
type="submit"
defaultValue="Register"
className="btn_1 full-width"
/>
</div>
</form>
</div>
);
};
export default Register;
your effect depends on userRegistrationError which is an object, reference based. Each time useEffect runs,setUserRegistrationError
creates a new object reference, which leads to an infinite loop since references won't be the same as the previous one.
One approach to avoid this issue and keep the right references, is to pass a callback function to setUserRegistrationError instead than a value. This way userRegistrationError is no longer a dependency, it will be an argument to your function instead:
useEffect(() => {
const handleErrors = (errors) => {
errors.forEach((error) => {
if (error.param === "firstName") {
// here you pass a callback function instead, and userRegistrationError is no longer a dependency
// and returns the next state as expected
setUserRegistrationError(userRegistrationError => ({
...userRegistrationError,
firstNameError: error.msg,
}));
}
if (error.param === "email") {
setUserRegistrationError(userRegistrationError => ({
...userRegistrationError,
emailError: error.msg,
}));
}
});
};
if (errors) {
handleErrors(errors);
}
}, [errors, setUserRegistrationError]);
You have a problem with the second useEffect, the first time you update your state userRegistrationError, the component re-rendered and re-executed the useeffect because the dependency userRegistrationError has changed and the process gets repeated again because the state gets updated every render.
useEffect(() => {
const handleErrors = (errors) => {
errors.map((error) => {
if (error.param === "firstname") {
setUserRegistrationError({
...userRegistrationError,
firstNameError: error.msg,
});
}
if (error.param === "email") {
setUserRegistrationError({
...userRegistrationError,
emailError: error.msg,
});
}
return null;
});
};
if (errors) {
handleErrors(errors);
}
}, [errors, setUserRegistrationError ]); //replace userRegistrationError by setUserRegistrationError

How to get different values from another component every time when it is added?

I have a form that contain 3 text box 2 of them are input and third one get the value from the map component. when i select the map address it shows in next map address text box also, for clear view my text box is like :
[1 branch][1]
when I click add branch the three text is added again but the map value is presetted like this:
[after add branch][2]
My code is :
import React from 'react';
import '../css/test.css';
import Header from './Header';
import SimpleModal from './modal';
import Branch from './branch';
import axios from 'axios';
import { Link } from 'react-router-dom';
const TOUR_STEPS = [
{
target: ".step1",
content: "View the cart you’ve added here",
disableBeacon: true,
},
{
target: ".step2",
content:
"View the cart you’ve added here",
},
{
target: ".step3",
content: "Contact the developer",
},
{
target: ".step4",
content: "We accept returns after 14 days max",
},
];
class Communication extends React.Component {
constructor(props) {
super(props);
this.state = {
input: {},
errors: {},
counter:0,
values: [
{ address1: { value: ''}, address2: { value: ''} }
]
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.appendDiv = this.appendDiv.bind(this);
this.mapFunctionHere = this.mapFunctionHere.bind(this);
}
handleChange(event) {
let input = this.state.input;
input[event.target.name] = event.target.value;
this.setState({
input
});
}
handleChangeInput = (counter, key, value) => {
const newValues = [...this.state.values]
newValues[counter][key].value = value
this.setState({ values: newValues })
}
mapFunctionHere(param) {
this.setState({
MapAddr:param[0],
});
}
handleSubmit(event) {
event.preventDefault();
if(!this.validate()){
console.log(this.state.values);
let input = {};
input["phoneNumber"] = "";
input["password"] = "";
this.setState({input:input});
console.log(this.state.MapAddr);
console.log(this.state.input);
const formData = new FormData();
formData.append("mobile", this.state.input.phoneNumber);
formData.append("password",this.state.input.password);
formData.append("fcm_token", 1);
formData.append("device_id", 1);
formData.append("source", 1);
formData.append("device_name", 1);
formData.append("os_version", 1);
axios({
method: 'post',
url: 'url',
data: formData,
config: { headers: {'Content-Type': 'multipart/form-data','Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS', }}
})
.then(function (response) {
//handle success
console.log(response);
if(response.data.result === true){
window.location.href = "/Detail";
}
else{
alert(response.data.msg);
}
console.log(response.data.msg);
console.log(response.data.result);
})
.catch(function (response) {
console.log(response);
});
}
};
renderBranches = () => {
const { counter } = this.state
const result = []
for (let i = 0; i <= counter; i++) {
result.push(this.renderBranch(i))
}
return result
}
appendDiv = () => {
this.setState({
counter: this.state.counter + 1,
values: [
...this.state.values,
{ address1: { value: ''}, address2: { value: '' } }
]
})
}
validate(){
let input = this.state.input;
let errors = {};
let isValid = true;
if (!input["fullname"]) {
isValid = false;
errors["fullname"] = "Please enter your fullname.";
}
if (typeof input["fullname"] !== "undefined") {
const re = /^\S*$/;
if(input["fullname"].length < 1 || !re.test(input["fullname"])){
isValid = false;
errors["fullname"] = "Please enter fullname.";
}
}
if (!input["address1"]) {
isValid = false;
errors["address1"] = "Please enter your address.";
}
if (typeof input["address1"] !== "undefined") {
if(input["address1"].length < 4){
isValid = false;
errors["address1"] = "Please add at least 4 address.";
}
}
if (!input["address2"]) {
isValid = false;
errors["address2"] = "Please enter your address.";
}
if (typeof input["address2"] !== "undefined") {
if(input["address2"].length < 4){
isValid = false;
errors["address2"] = "Please add at least 4 address.";
}
}
if (!input["address3"]) {
isValid = false;
errors["address3"] = "Please enter your address.";
}
if (typeof input["address3"] !== "undefined") {
if(input["address3"].length < 4){
isValid = false;
errors["address3"] = "Please add at least 4 address.";
}
}
if (!input["branch"]) {
isValid = false;
errors["branch"] = "Please Enter No of branch.";
}
if (typeof input["branch"] !== "undefined") {
if(input["branch"].length < 6){
isValid = false;
errors["branch"] = "Please Enter No of branch.";
}
}
this.setState({
errors: errors
});
return isValid;
}
renderBranch = counter => {
const { values,MapAddr } = this.state
return (
<>
<div className="form-group">
<label>Store Address</label>
<input type="text"
value={values[counter].address1.value}
onChange={event => this.handleChangeInput(counter, 'address1', event.target.value)}
className="form-control code"
name="address1"
placeholder="Pincode"
/>
<span className="form-text" id="errtext">
{values[counter].address1.error}
</span>
</div>
<div className="form-group">
<div className="row">
<div className="col">
<input type="text" className="form-control code"
value={values[counter].address2.value}
onChange={event => this.handleChangeInput(counter, 'address2', event.target.value)}
name="address2"
placeholder="address" />
<span className="form-text" id="errtext">
{values[counter].address2.error}
</span>
</div>
<div className="col-md-auto">
<p style={{margin:"5px"}}>and</p>
</div>
<div className="col">
<SimpleModal className="form-control" mapFunctionHere={this.mapFunctionHere}/>
</div>
</div>
</div>
<div className="form-group">
<input type="text"
className="form-control code"
value={MapAddr}
onChange={event => this.handleChangeInput(counter, 'address3', MapAddr)}
name="address3"
placeholder="address"
readOnly
/>
<span className="form-text" id="errtext">
</span>
</div>
</>
)
}
render() {
var rows = [];
for (var i = 0; i < 1; i++) {
rows.push(<Branch key={i} />);
}
return <>
<Header data={TOUR_STEPS}/>
<div id="kt_body" className="header-fixed header-mobile-fixed subheader-enabled subheader-fixed aside-enabled aside-fixed aside-minimize-hoverable page-loading">
<div className="d-flex flex-column-fluid">
<div className="container">
<div className="card card-custom">
<div className="card-body p-0">
<div className="wizard wizard-3" id="kt_wizard_v3" data-wizard-state="step-first" data-wizard-clickable="true">
<div className="wizard-nav">
<div className="wizard-steps px-8 py-8 px-lg-15 py-lg-3">
<div className="wizard-step full" data-wizard-type="step">
<div className="wizard-label">
<h3 className="wizard-title">
<span>1.</span>Verify Your Details</h3>
<div className="wizard-bar"></div>
</div>
</div>
<div className="wizard-step full" data-wizard-type="step">
<div className="wizard-label">
<h3 className="wizard-title">
<span>2.</span>classification</h3>
<div className="wizard-bar"></div>
</div>
</div>
<div className="wizard-step full" data-wizard-type="step" >
<div className="wizard-label">
<h3 className="wizard-title">
<span>3.</span>Authentication</h3>
<div className="wizard-bar"></div>
</div>
</div>
<div className="wizard-step full" data-wizard-type="step" data-wizard-state="current">
<div className="wizard-label">
<h3 className="wizard-title">
<span>4.</span>Communication</h3>
<div className="wizard-bar"></div>
</div>
</div>
<div className="wizard-step full" data-wizard-type="step">
<div className="wizard-label">
<h3 className="wizard-title">
<span>5.</span>Documentaion</h3>
<div className="wizard-bar"></div>
</div>
</div>
<div className="wizard-step mob" data-wizard-type="step" data-wizard-state="current">
<div className="wizard-label">
<h3 className="wizard-title">
<span>(4/5)</span>Communication</h3>
<div className="wizard-bar"></div>
</div>
</div>
</div>
</div>
<div className="row justify-content-center py-10 px-8 py-lg-12 px-lg-10">
<div className="col-xl-12 col-xxl-7">
<form className="form" id="kt_form">
<div className="pb-5" data-wizard-type="step-content" data-wizard-state="current">
<h4 className="mb-10 font-weight-bold text-dark">Business Communication Details</h4>
<div className="row ">
<div className="col-xl-6">
<div className="form-group">
<label>Store/Brand Name</label>
<input type="text"
value={this.state.input.fullname}
onChange={this.handleChange}
className="form-control code"
name="fullname" placeholder="Brand Name" />
<span className="form-text" id="errtext">{this.state.errors.fullname}</span>
</div>
<div className="form-group">
<label>Does it has Branches ?</label>
<div className="checkbox-inline">
<label className="checkbox">
<input type="checkbox" name="Checkboxes3"/>
<span></span>
Yes
</label>
<label >
<input type="text"
className="form-control code"
name="branch" value={this.state.input.branch}
onChange={this.handleChange}
placeholder="Pincode" />
</label>
</div>
<span className="form-text" id="errtext">{this.state.errors.branch}</span>
</div>
{this.renderBranches()}
<div className="toolti">
<input type="button" className="addbranch" onClick={this.appendDiv} value="Add Branch" />
<span className="tooltitext">You can add branches even after registration
from your dashboard</span>
</div>
</div>
</div>
</div>
<div className="d-flex justify-content-between border-top mt-5 pt-10">
<div className="mr-2">
{/* <button type="button" className="btn btn-light-primary font-weight-bolder text-uppercase px-9 py-4">Previous</button> */}
<Link to="/authentication" class="btn btn-primary font-weight-bolder text-uppercase px-9 py-4" data-wizard-type="action-next" style={{backgroundColor:"#3951A0",borderColor:"#3951A0"}}>Previous</Link>
</div>
<div>
{/* <Link to="/documentation" class="btn btn-primary font-weight-bolder text-uppercase px-9 py-4" data-wizard-type="action-next" style={{backgroundColor:"#3951A0",borderColor:"#3951A0"}}>Next</Link> */}
<button type="button" className="btn btn-primary font-weight-bolder text-uppercase px-9 py-4"
onClick={this.handleSubmit}
style={{backgroundColor:"#3951A0",borderColor:"#3951A0"}}>Next</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</>
}
}
export default Communication;
In select on map i am calling a modal my modal code is:
class SimpleModal extends React.Component {
//export default function SimpleModal() {
constructor(props) {
super(props);
//Set initial state
this.state = {
setOpen: false,
name: ""
}
this.handleOpen = this.handleOpen.bind(this);
this.handleClose = this.handleClose.bind(this);
this.someFunctionHere = this.someFunctionHere.bind(this);
}
// const classes = useStyles();
// // getModalStyle is not a pure function, we roll the style only on the first render
// const [modalStyle] = React.useState(getModalStyle);
// //const [open, setOpen] = React.useState(false);
someFunctionHere(param) {
this.props.mapFunctionHere(param);
}
handleOpen() {
this.setState({
setOpen: true
});
};
handleClose(){
this.setState({
setOpen: false
});
};
render()
{
return <>
<div style={{position:"absolute"}}>
<button type="button" className="form-control map" onClick={this.handleOpen}>
Select on Map
</button>
<Modal
open={this.state.setOpen}
onClose={this.handleClose}
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
<div className="paper" >
<Map someFunctionHere={this.someFunctionHere} />
{/* <SimpleModal /> */}
<button type="button" style={{height: "43px",width: "138px",
borderRadius: "4px",backgroundColor: "#3951A0",color:'white',border:"none",float:"right"}} onClick={this.handleClose}>
Close
</button>
</div>
</Modal>
</div>
</>
}
}
export default SimpleModal;
In modal i am calling my map :
class Map extends React.Component {
//const Map = () => {
constructor(props) {
super(props);
//Set initial state
this.state = {
addres: '',
defaultLocation: DefaultLocation,
location:DefaultLocation,
zoom:DefaultZoom
}
this.handleChangeLocation = this.handleChangeLocation.bind(this);
}
handleChangeLocation (lat, lng){
this.setState({
location: {lat:lat, lng:lng},
})
console.log(lat,lng)
axios.get(`url`)
.then(res => {
console.log(res.data.results[0].formatted_address);
// const numbers = [1, 2, 3, 4, 5];
const setaaddres = [res.data.results[0].formatted_address,lat,lng];
this.setState({addres: res.data.results[0].formatted_address});
this.props.someFunctionHere(setaaddres);
})
}
handleChangeZoom (newZoom){
this.setState({
zoom: newZoom,
})
}
render() {
return (
<>
<div>
<input type='text' style={{width:"100%"}} defaultValue={this.state.addres} />
<MapPicker defaultLocation={this.state.defaultLocation}
zoom={this.state.zoom}
style={{height:'500px'}}
onChangeLocation={this.handleChangeLocation}
onChangeZoom={this.handleChangeZoom}
apiKey='AIzaSyB-tpDLb6LG767qc9ttvDrf23IOqLxheXk'/>
</div>
</>
);
}
}
;
export default Map;
How to get different map values for different text box ?
[1]: https://i.stack.imgur.com/P6LX9.png
[2]: https://i.stack.imgur.com/jpT01.png

React - Phone input produces a huge flag

This is my jsx for the form
import React, { Component } from "react";
import { createUser } from "../HTTPRequests";
import PhoneInput from "react-phone-number-input";
class UserRegForm extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
secondPassword: "",
username: "",
phone: "",
current: 0
};
this.handleEmail = this.handleEmail.bind(this);
this.handlePassword = this.handlePassword.bind(this);
this.handleSecondPassword = this.handleSecondPassword.bind(this);
this.handleUsername = this.handleUsername.bind(this);
this.renderSecondPassword = this.renderSecondPassword.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handlePhone = this.handlePhone.bind(this);
}
handleEmail(event) {
this.setState({ email: event.target.value });
}
handlePassword(event) {
this.setState({ password: event.target.value });
}
handleSecondPassword(event) {
this.setState({ secondPassword: event.target.value });
}
handleUsername(event) {
this.setState({ username: event.target.value });
}
handlePhone(phone) {
this.setState({ phone: phone.value });
}
renderSecondPassword() {
var classN;
if (
this.state.secondPassword.length === 0 ||
this.state.secondPassword === this.state.password
) {
classN = "form-control";
} else {
classN = "form-control is-invalid";
}
return (
<div className="form-group">
<label htmlFor="InputPassword2">Introduza novamente a Password</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handleSecondPassword}
type="password"
className={classN}
id="InputPassword2"
/>
</div>
);
}
handleKeyDown(event) {
if (event.key === "Enter") {
this.handleSubmit();
}
}
handleSubmit() {
createUser(this.state.email, this.state.password, this.state.username).then(
function(r) {
console.log(r);
}
);
}
render() {
return (
<div className="position-relative m-4">
<form>
<div className="form-group">
<label htmlFor="exampleInputUsername">Nome Completo</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handleUsername}
type="username"
className="form-control"
id="exampleInputUsername"
/>
</div>
<div className="form-group">
<label htmlFor="exampleInputEmail1">E-mail</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handleEmail}
type="email"
className="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
/>
<small id="emailHelp" className="form-text text-muted">
Nunca partilharemos o seu e-mail com ninguém.
</small>
</div>
<PhoneInput
placeholder="Enter phone number"
value={this.state.phone}
onChange={phone => this.handlePhone({ phone })}
/>
<div className="form-group">
<label htmlFor="InputPassword1">Password</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handlePassword}
type="password"
className="form-control"
id="InputPassword1"
/>
</div>
{this.renderSecondPassword()}
<button
type="button"
className="btn btn-primary"
onClick={this.handleSubmit}
>
Submit
</button>
</form>
</div>
);
}
}
export default UserRegForm;
And this is the result...
as you can see the flag just expands to the whole screen.
I have programming experience (C and java), but just started learning HTML and React... So i'm still a bit lost. do I have to wrap the phone number component in something so it behaves? According to documentation the flag should be to the left of the input and not below
Any help is very appreciated
As someone who just encountered the same issue as OP after an update, the fix was very simple:
import 'react-phone-number-input/style.css'
According to last version of the docs : https://github.com/catamphetamine/react-phone-number-input

How display this error response from node js in react redux

I am pretty new to react/redux I am pretty confused with this simple form.My error state is always undefined eventhough I am getting the error data from node js server Without error data I can't set my state.
routes/users.js
import express from 'express';
import Validator from 'validator';
import isEmpty from 'lodash/isEmpty'
let router = express.Router();
function ValidateInput(data) {
let errors = {};
if(isEmpty(data.email)){
errors.email = 'This fiels is required'
}
if(!Validator.isEmail(data.email)){
errors.email = "Email is in Valid"
}
if(isEmpty(data.password)){
errors.password = 'This fiels is required'
}
if(isEmpty(data.passwordConfirmation)){
errors.passwordConfirmation = 'This fiels is required'
}
if(!Validator.equals(data.password,data.passwordConfirmation)){
errors.passwordConfirmation = "Password Must Macthc"
}
if(isEmpty(data.timezone)){
errors.timezone = 'This fiels is required'
}
return{
errors,
isValid:isEmpty(errors)
}
}
router.post('/',(req,res) => {
console.log(req)
const {errors,isValid} = ValidateInput(req.body);
if(!isValid){
res.status(400).json(errors)
}
});
export default router
SignupForm.js
import React from 'react';
import timezones from '../../data/timezone';
import map from 'lodash/map';
class SignupForm extends React.Component {
constructor(props){
super(props);
this.state = {
username:'',
email:'',
password:'',
passwordConfirmation:'',
timezone:'',
errors:{}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this)
}
onChange(e){
this.setState({ [e.target.name]:e.target.value })
}
onSubmit(e){
e.preventDefault();
this.setState({ errors:{} });
this.props.userSignupRequest(this.state).then(function (data) {
console.log(data)//Nothing
// this.setState({
// errors:data
// })
})
}
render(){
console.log(this.state)
const options = map(timezones,(val,key) =>
<option key={val} value={val}>{key}</option>
);
return(
<form onSubmit={this.onSubmit}>
<h1>Join our community</h1>
<div className="form-group">
<label className="control-label">Username</label>
<input
type="text"
name="username"
className="form-control"
value={this.state.username}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">Email</label>
<input
type="text"
name="email"
className="form-control"
value={this.state.email}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">Password</label>
<input
type="password"
name="password"
className="form-control"
value={this.state.password}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">passwordConfirmation</label>
<input
type="password"
name="passwordConfirmation"
className="form-control"
value={this.state.passwordConfirmation}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">Time Zone</label>
<select
className="form-control"
name="timezone"
onChange={this.onChange}
value={this.state.timezone}
>
<option value="" disabled>Choose Your Timezone</option>
{options}
</select>
</div>
<div className="form-group">
<button className="btn btn-primary btn-lg">
SignUp
</button>
</div>
</form>
)
}
}
SignupForm.propTypes ={
userSignupRequest:React.PropTypes.func.isRequired
};
export default SignupForm
You need to use catch... so
onSubmit(e){
e.preventDefault();
this.setState({ errors:{} });
this.props.userSignupRequest(this.state)
.then(function (data) {
//Success here
})
.catch(({response}) => console.log(response.data)) //Here you get your errors
})
}

Categories