Textfields component number validation React js - javascript

I have 3 Textfields, what I want to do is just to accept number so if someone put text and click continue the application should display an error saying that just numbers are allowed.
The following code displays an error message if the Textfield is empty and thats ok but the other validation to check if the user inputs text or numbers is pending and I'm stucked.
import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import TextField from 'material-ui/TextField';
import Divider from 'material-ui/Divider';
import cr from '../styles/general.css';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
buy_: '',
and_: '',
save_: '',
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event, index, value) {
this.setState({value});
}
clear() {
console.info('Click on clear');
this.setState({
buy_: '',
and_: '',
save_: ''
});
}
validate() {
let isError = false;
const errors = {
descriptionError: ''
};
if (this.state.buy_.length < 1 || this.state.buy_ === null) {
isError = true;
errors.buy_error = 'Field requiered';
}
if (this.state.and_.length < 1 || this.state.and_ === null) {
isError = true;
errors.and_error = 'Field requiered';
}
if (this.state.save_.length < 1 || this.state.save_ === null) {
isError = true;
errors.save_error = 'Field requiered';
}
this.setState({
...this.state,
...errors
});
return isError;
}
onSubmit(e){
e.preventDefault();
// this.props.onSubmit(this.state);
console.log('click onSubmit')
const err = this.validate();
if (!err) {
// clear form
this.setState({
buy_error: '',
and_error: '',
save_error: ''
});
this.props.onChange({
buy_: '',
and_: '',
save_: ''
});
}
}
render() {
return (
<div className={cr.container}>
<div className ={cr.boton}>
<Divider/>
<br/>
</div>
<div className={cr.rows}>
<div>
<TextField
onChange={(e) => {this.setState({buy_: e.target.value})}}
value={this.state.buy_}
errorText={this.state.buy_error}
floatingLabelText="Buy"
/>
</div>
<div>
<TextField
onChange={(e) => {this.setState({and_: e.target.value})}}
value={this.state.and_}
errorText={this.state.and_error}
floatingLabelText="And"
/>
</div>
<div>
<TextField
onChange={(e) => {this.setState({save_: e.target.value})}}
value={this.state.save_}
errorText={this.state.save_error}
floatingLabelText="Save"
/>
</div>
</div>
<div className={cr.botonSet}>
<div className={cr.botonMargin}>
<RaisedButton
label="Continue"
onClick={e => this.onSubmit(e)}/>
</div>
<div>
<RaisedButton
label="Clear"
secondary ={true}
onClick={this.clear = this.clear.bind(this)}
/>
</div>
</div>
</div>
);
}
}
Can someone help me on this please.
Thanks in advance.

You can prevent users from input text by using this :
<TextField
onChange={(e) => {
if(e.target.value === '' || /^\d+$/.test(e.target.value)) {
this.setState({and_: e.target.value})
} else {
return false;
}
}}
value={this.state.and_}
errorText={this.state.and_error}
floatingLabelText="And"
/>

The TextField component can restrict users to entering text using the JavaScript test method:
<TextField
onChange={(e) => {
if(e.target.value == '' || (/\D/.test(e.target.value))) {
this.setState({and_: e.target.value})}
}
else {
return false;
}
}
value={this.state.and_}
errorText={this.state.and_error}
floatingLabelText="And"
/>

Try adding this code in your validate function.
You can use regex to validate your fields for text or numbers like :
import * as RegExp from './RegExpression';
validate() {
let isError = false;
const errors = {
descriptionError: ''
};
if (this.state.buy_ && !RegExp.NAME.test(this.state.buy_)) {
// validation check if input is name
isError = true;
errors.buy_error = 'Invalid name';
}
if (this.state.and_ && !RegExp.NUMBER.test(this.state.and_)) {
// validation check if input is number
isError = true;
errors.and_error = 'Invalid Number';
}
this.setState({
...this.state,
...errors
});
return isError;
}
In RegexExpression file add these validations like this :
export const NAME = /^[a-z ,.'-()"-]+$/i;
export const NUMBER = /^[0-9]*$/ ;

You are not initialising error object in state but accessed in TextField as this.state.and_error. Either you should initialise error in constructor like this.state = { and_error: "" } or initialise error object as
this.state = {
error: {
and_error: "",
buy_error: "",
save_error: ""
}
}
So in your TextField
<TextField
onChange={(e) => {
if(e.target.value === "" || (/\D/.test(e.target.value))) {
this.setState({and_: e.target.value})}
}
else {
return false;
}
}
value={this.state.and_}
errorText={this.state.error.and_error} // If initialised error string access as this.state.and_error
floatingLabelText="And"
/>
Your validate function will be like
validate() {
let isError = false;
const errors = this.state.errors;
if (this.state.buy_.toString().length < 1 || this.state.buy_ === null) {
isError = true;
errors.buy_error = 'Field requiered';
}
if (this.state.and_.toString().length < 1 || this.state.and_ === null) {
isError = true;
errors.and_error = 'Field requiered';
}
if (this.state.save_.toString().length < 1 || this.state.save_ === null) {
isError = true;
errors.save_error = 'Field requiered';
}
this.setState({errors});
return isError;
}
Hope this will heps you!

You can use react-validation for all validation and set rules for validation

Related

Variable not displaying on Screen

I've set condition for when a user enters numbers into a text box depending on what the numbers entered start with on screen it should display the name of the card.I seem to be changing the variable name fine but am having issues actually displaying the variable name. I'm wondering whether instead of having the if statements in the CardCheck.js they should maybe be in App.js or CardTypeDisplay.js. Apologies first week on React.
App.js
import "./App.css";
import React from "react";
import CardCheck from "./CardCheck";
import CardTypeDisplay from "./CardTypeDisplay";
class App extends React.Component {
state = {
cardNumber: "",
cardType: "",
};
handleChange = (event) => {
this.setState({ cardNumber: event.target.value });
};
handleClick = () => {
let { cardNumber } = this.state;
let { cardType } = this.state;
this.setState({
cardType: cardType,
cardNumber: "",
});
};
render() {
let { cardNumber } = this.state;
let { cardType } = this.state;
return (
<div className="App">
<h1>Taken Yo Money</h1>
<CardCheck
cardNumber={cardNumber}
handleChange={this.handleChange}
handleClick={this.handleClick}
/>
<CardTypeDisplay cardType={cardType} />
</div>
);
}
}
export default App;
CardCheck.js
function CardCheck(props) {
let { cardNumber, handleChange, handleClick } = props;
let cardType = props;
if (cardNumber.match(/^34/) || cardNumber.match(/^38/)) {
cardType = "AMEX";
console.log(cardType);
} else if (cardNumber.match(/^6011/)) {
cardType = "Discover";
console.log(cardType);
} else if (
cardNumber.match(/^51/) ||
cardNumber.match(/^52/) ||
cardNumber.match(/^53/) ||
cardNumber.match(/^54/) ||
cardNumber.match(/^55/)
) {
cardType = "MasterCard";
console.log(cardType);
} else if (cardNumber.match(/^4/)) {
cardType = "Visa";
console.log(cardType);
}
return (
<div className="TweetInput">
<div className="bar-wrapper"></div>
<textarea onChange={handleChange} value={cardNumber}></textarea>
<footer>
<button onClick={handleClick} value={cardType}>
Enter Card Details
</button>
</footer>
</div>
);
}
export default CardCheck;
CardTypeDisplay.js
function CardTypeDisplay(props) {
let { cardType } = props;
return (
<div className="cardType">
<p> {cardType} </p>
</div>
);
}
export default CardTypeDisplay;
You could use the hook useEffect in CardCheck to perform an action each time that cardNumber changes
Like this
useEffect(() => {
if (cardNumber.match(/^34/) || cardNumber.match(/^38/)) {
cardType = "AMEX";
console.log(cardType);
} else if (cardNumber.match(/^6011/)) {
cardType = "Discover";
console.log(cardType);
} else if (
cardNumber.match(/^51/) ||
cardNumber.match(/^52/) ||
cardNumber.match(/^53/) ||
cardNumber.match(/^54/) ||
cardNumber.match(/^55/)
) {
cardType = "MasterCard";
console.log(cardType);
} else if (cardNumber.match(/^4/)) {
cardType = "Visa";
console.log(cardType);
}
},{cardNumber})
Also you are defining cartType in CardCheck and CardCheck doesn't know that variable. What you could do is pass this value as parameter in handleClick
<button onClick={(e) => handleClick(e,cartType)} >
Enter Card Details
</button>
And in receive it and change the state
handleChange = (event, type) => {
this.setState({ cardNumber: event.target.value, cartType:type });
};

Wrong input validation

I want to validate all of my inputs in react
My validation code looks like this:
let isValid = {
name: false,
address: false,
postcode: false,
phone: false,
email: false
};
const validateInput = (e) => {
let currentInput = e.target
if (currentInput.name === 'name') {
if (currentInput.value !== 'undefined' && currentInput.value.match(/^[a-zA-Z]+$/)) {
isValid.name = true;
} else {
isValid.name = false;
}
}
if (currentInput.name === 'address') {
if (currentInput.value !== 'undefined') {
isValid.address = true;
} else {
isValid.address = false;
}
}
if (currentInput.name === 'postcode') {
if (currentInput.value !== undefined && currentInput.value.match(/^[0-9]+[-]+[0-9]+$/) && currentInput.value.length > 4) {
isValid.postcode = true;
} else {
isValid.postcode = false;
}
}
if (currentInput.name === 'phone') {
if (currentInput.value !== 'undefined' && currentInput.value.match(/^[0-9]+$/) && currentInput.value.length > 7) {
isValid.phone = true;
} else {
isValid.phone = false;
}
}
if (currentInput.name === 'email') {
if (currentInput.value !== 'undefined' && currentInput.value.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,}))$/)) {
isValid.email = true;
} else {
isValid.email = false;
}
}
console.log(isValid)
}
For example when i type correct value in "Name" isValid.name gets value true, then when i write somethink in "address" isValid.address gets true, but isValid.name false
How to fix it?
{requiredInformations.map((el) => (
<>
<Label>{el.label}</Label>
<Input type={el.type} name={el.name} required onChange={(e) => { getInputValue(e); validateInput(e) }} />
</>
))}
I suggest you try to use react-joi library for validation React-Joi-Validation
Its easy and simple to use, and you can achieve what you are trying here in your code by just reading the first page on their npm package main page.
You need to get yourself familiar with terms like "state"
, "props", "component lifecycle", etc. Build a simple component using a guide on youtube, you can find plenty of them.
Meanwhile, here is a simple component that validates inputs:
function App() {
const [name, setName] = React.useState('');
const [address, setAddress] = React.useState('');
const isValid = React.useMemo(() => {
const result = {
name: false,
address: false,
};
if (name.match(/^[a-zA-Z]+$/)) {
result.name = true;
} else {
result.name = false;
}
if (address !== '') {
result.address = true;
} else {
result.address = false;
}
return result;
}, [name, address]);
return (
<div>
<input
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
{isValid.name ? <p>Name is valid</p> : <p>Name is invalid</p>}
<br />
<input
placeholder="Address"
value={address}
onChange={(e) => setAddress(e.target.value)}
/>
{isValid.address ? <p>Adress is valid</p> : <p>Adress is invalid</p>}
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root">
</div>

Validation check in reactjs issue

Why I am not able to see validation alert clicking on the done button when everything is empty once form open even validation checks are proper ?
Basically form opens i don't type anything and click on done button so all validation checks should work and show text 'Required.Please enter your given name.' but it is not showing ?
Where is the issue which causes the state to be blank at the end
const addSecondaryContact = inject('apptContacts')(observer((props) => {
const {
i18n, nbnContact, apptContacts, backButtonContent,
} = props;
const { updatePrimaryContact } = apptContacts;
const CMS = i18n.appointmentManager.editAppointmentContact;
const [state, setState] = useState({
data: {
firstName: '',
lastName: '',
number: '',
},
firstNameValid: '',
lastNameValid: '',
numberValid: '',
});
const validFirstName = () => {
console.log(state.data.firstName);
if (!state.data.firstName) {
console.log('frstname1');
return 'Required.Please enter your given name.';
}
if (!/^[A-Za-z]+$/.test(state.data.firstName)) {
console.log('frstname2');
return 'Invalid entry.Please use letters only.';
} if (state.data.firstName.length === 1) {
console.log('frstname3');
return 'Invalid entry.More than one character is required';
}
console.log('&&&&');
return '';
};
const validLastName = () => {
console.log('988');
if (!state.data.lastName) { console.log('lastname'); return 'Required.Please enter your given name.'; }
if (!/^[A-Za-z]+$/.test(state.data.lastName)) {
return 'Invalid entry.Please use letters only.';
} if (state.data.lastName.length === 1) {
return 'Invalid entry.More than one character is required';
}
return '';
};
const validNumber = async () => {
console.log('777');
if (!state.data.number) { return 'Required.Please enter your mobile number.'; }
if (state.data.number.substr(0, 2) !== '04') {
return 'Invalid entry.Please enter your 10-digit mobile number starting with 04.';
} if (state.data.number.length !== 10) {
return 'Invalid entry.Please enter your 10-digit mobile number starting with 04.';
} if (state.data.number.length === 1) {
return 'Invalid entry.More than one number is required';
}
return '';
};
const valid = async () => {
console.log('milan');
setState({
...state,
firstNameValid: validFirstName(),
lastNameValid: validLastName(),
numberValid: validNumber(),
});
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
};
const handleTextareaChange = (event) => {
console.log('%%%');
const { data } = state;
data[event.target.name] = event.target.value;
setState({
...state,
data,
});
valid();
};
const saveButton = async () => {
console.log(state);
await valid();
if (valid()) {
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
if (!state.firstNameValid && !state.lastNameValid && !state.numberValid) {
const personName = `${state.data.firstName} ${state.data.lastName}`;
const primaryContact = {
name: personName,
phoneNumber: state.data.number,
// updatePrimaryContact(primaryContact)
};
// updatePrimaryContact(primaryContact)
backButtonContent();
}
}
};
return (
<div>
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing4x} />
<h1 tabIndex="-1" className="HeadingB mt-sheet-heading">
{CMS.heading2}
</h1>
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
<TextField id="givenName" name="firstName" label={CMS.name} onChange={handleTextareaChange} value={state.data.firstName} />
{state.firstNameValid && (
<Alert variant="error" inline>
<p>
{state.firstNameValid}
</p>
</Alert>
)}
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
<TextField id="familyName" name="lastName" label={CMS.familyName} onChange={handleTextareaChange} value={state.data.lastName} />
{state.lastNameValid && (
<Alert variant="error" inline>
<p>
{state.lastNameValid}
</p>
</Alert>
)}
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
<TextField id="mobileNumber" name="number" label={CMS.mobile} onChange={handleTextareaChange} value={state.data.number} />
{state.numberValid && (
<Alert variant="error" inline>
<p>
{state.numberValid}
</p>
</Alert>
)}
<VerticalSpacing size={ABLE_SPACING_SIZE.spacing4x} />
<ActionButton className={styles.saveCta} variant="HighEmphasis" label={CMS.saveCTA} onClick={() => saveButton()} />
</div>
);
}));
export default addSecondaryContact;
You had two main issues:
you state update is not proper - you set state on multiple occasions
you had async in your validNumber method - which causes blank output
Here is the code i modify from your code - maybe it can help you. I removed extra components in order to remove dependencies and used only plain html.
Demo: https://codesandbox.io/s/upbeat-feynman-w3odj?file=/App.js
import "./styles.css";
import React from "react";
export default function App() {
const [state, setState] = React.useState({
data: {
firstName: "",
lastName: "",
number: ""
},
firstNameValid: "",
lastNameValid: "",
numberValid: ""
});
const validFirstName = () => {
console.log(state.data.firstName);
let result = "";
if (!state.data.firstName) {
console.log("frstname1");
result = "Required.Please enter your given name.";
}
if (!/^[A-Za-z]+$/.test(state.data.firstName)) {
console.log("frstname2");
result = "Invalid entry.Please use letters only.";
}
if (state.data.firstName.length === 1) {
console.log("frstname3");
result = "Invalid entry.More than one character is required";
}
console.log("&&&&");
return result;
};
const validLastName = () => {
console.log("988");
if (!state.data.lastName) {
console.log("lastname");
return "Required.Please enter your given name.";
}
if (!/^[A-Za-z]+$/.test(state.data.lastName)) {
return "Invalid entry.Please use letters only.";
}
if (state.data.lastName.length === 1) {
return "Invalid entry.More than one character is required";
}
return "";
};
const validNumber = () => {
console.log("777");
if (!state.data.number) {
return "Required.Please enter your mobile number.";
}
if (state.data.number.substr(0, 2) !== "04") {
return "Invalid entry.Please enter your 10-digit mobile number starting with 04.";
}
if (state.data.number.length !== 10) {
return "Invalid entry.Please enter your 10-digit mobile number starting with 04.";
}
if (state.data.number.length === 1) {
return "Invalid entry.More than one number is required";
}
return "";
};
const valid = async () => {
console.log("milan");
setState({
...state,
firstNameValid: validFirstName(),
lastNameValid: validLastName(),
numberValid: validNumber()
});
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
};
const handleTextareaChange = (event) => {
let validRes = "";
let key = "";
if (event.target.name === "firstName") {
validRes = validFirstName();
key = "firstNameValid";
}
if (event.target.name === "lastName") {
validRes = validLastName();
key = "firstNameValid";
}
if (event.target.name === "number") {
validRes = validNumber();
key = "numberValid";
}
console.log("234", validRes);
setState({
...state,
data: { ...state.data, [event.target.name]: event.target.value },
// [key]:
firstNameValid: validFirstName(),
lastNameValid: validLastName(),
numberValid: validNumber()
});
// valid();
};
const saveButton = async () => {
console.log(state);
await valid();
if (valid()) {
console.log(state.firstNameValid);
console.log(state.lastNameValid);
console.log(state.numberValid);
}
};
return (
<div>
<h1 tabIndex="-1" className="HeadingB mt-sheet-heading">
'CMS.heading2'
</h1>
<input
type="text"
id="givenName"
name="firstName"
label="CMS.name"
onChange={handleTextareaChange}
value={state.data.firstName}
/>
{state.firstNameValid && <p>{state.firstNameValid}</p>}
<input
type="text"
id="familyName"
name="lastName"
label="CMS.familyName"
onChange={handleTextareaChange}
value={state.data.lastName}
/>
{state.lastNameValid && <p>{state.lastNameValid}</p>}
<input
type="text"
id="mobileNumber"
name="number"
label="CMS.mobile"
onChange={handleTextareaChange}
value={state.data.number}
/>
{state.numberValid && <p>{state.numberValid}</p>}
<button
variant="HighEmphasis"
label="CMS.saveCTA"
onClick={() => saveButton()}
/>
</div>
);
}

Trying to set up form validation in my basic todo list app

I am trying to set up validations in my todo list app in react; however this doesn't seem to work. Even if the form is empty the process still goes through and I don't know where the problem is coming from. I am just following a tutorial online since I'm pretty new to this and don't know how to do it myself.
import React from "react";
import * as TodoActions from "../actions/TodoActions";
import TodoStore from "../stores/TodoStore";
import Todo from './Todo.js'
import './Todos.css'
const formValid = ({ formErrors, ...rest }) => {
let valid = true;
Object.values(formErrors).forEach(val => {
val.length > 0 && (valid = false);
});
Object.values(rest).forEach(val => {
val === null && (valid = false);
});
return valid;
};
export default class Todos extends React.Component {
constructor() {
super();
this.state = {
todos: TodoStore.getAll(),
loading: true,
formErrors: {
todo: ""
}
};
TodoActions.receiveTodos()
}
componentWillMount() {
TodoStore.addChangeListener(this.getTodos);
}
componentWillUnmount() {
TodoStore.removeChangeListener(this.getTodos);
}
componentDidUpdate() {
TodoActions.receiveTodos();
}
getTodos = () => {
this.setState({
todos: TodoStore.getAll(),
loading: false
});
}
deleteTodo = (id) => {
TodoActions.deleteTodo(id);
}
addItem = (e) => {
e.preventDefault();
TodoActions.createTodo(this._inputElement.value)
}
handleChange = e => {
e.preventDefault();
const { name, value } = e.target;
let formErrors = { ...this.state.formErrors };
switch (name) {
case "todo":
formErrors.todo =
value.length < 0 ? "Task cannot be empty" : "";
break;
default:
break;
}
this.setState({ formErrors, [name]: value }, () => console.log(this.state));
}
render() {
const { todos } = this.state;
const { formErrors } = this.state;
let TodoComponents;
if (this.state.loading) {
TodoComponents = <h1>Loading...</h1>;
} else if(todos.length) {
TodoComponents = todos.map((todo) => {
return (
<div key={todo.id} className="todo-list">
<Todo key={todo.id} name={todo.name}/>
<div className="todo-btn"><a type="button" onClick={() => this.deleteTodo(todo.id)} className="delete-btn"><i class="fas fa-trash-alt"></i></a></div>
</div>
)
});
} else {
TodoComponents = <p>No tasks to show :)</p>
}
return (
<div className="main-container">
<div className="small-container">
<h1 className="title">All Tasks</h1>
<ul>{TodoComponents}</ul>
<form onSubmit={this.addItem}>
<input ref={(a) => this._inputElement = a} placeholder="Enter Task" className="input-form {formErrors.todo.length < 0 ? 'error' : null}"/>
{formErrors.todo.length < 0 && (
<span className="errorMessage">{formErrors.firstName}</span>
)}
<button type="submit" className="input-btn">Add</button>
</form>
</div>
</div>
);
}
}

ReactJS form validation

I have simple form validation for react. I made this from this source
http://www.dotnetawesome.com/2016/02/create-simple-forms-with-validation-in-react-js.html
there is my code. when I submit the form input error occurred inside of the isValid function. please help me to fix this.
AddMember page
class AddMember extends Component {
constructor(props) {
super(props);
this.state = {
loading : true,
formData: {
fname : "",
lname : "",
address1: "",
address2: "",
city : "",
mobile : "",
role : "",
email : "",
gender : ""
},
fields : []
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.register = this.register.bind(this);
}
componentDidMount() {
document.title = globals.title + "Add New Member";
setTimeout(() => {
this.setState({loading: false})
}, 500);
}
handleSubmit = (e) => {
e.preventDefault();
let validForm = true;
this.state.fields.forEach(function (field) {
console.log(field.refs[field.props.name]);
if (typeof field.isValid === "function") {
let validField = field.isValid(field.refs[field.props.name]);
validForm = validForm && validField
}
});
if (validForm) {
console.log(this.state.fields);
}
};
handleChange = (name) => (value) => {
let formData = {
[name]: value
};
this.setState({
formData: formData
})
};
register (field) {
let s = this.state.fields;
s.push(field);
this.setState({fields: s});
console.log("ss");
};
render() {
const {classes} = this.props;
if (this.state.loading) {
return (
<div className={classes.posRelative}>
<CircularProgress size={80} className={classes.progress}/>
</div>
)
}
return (
<Grow in={true} style={{transformOrigin: "0 0 0"}}>
<Paper className={classes.root}>
<form
onSubmit={this.handleSubmit}
noValidate>
<Grid container spacing={16}>
<Grid item xs={12} sm={6}>
<MuiValidator placeholder={"First Name"} name={"fname"} type={"email"}
onChange={this.handleChange("fname")} value={this.state.formData.fname}
inputProps={{required:true}} onComponentMounted={this.register} fullWidth={true}/>
</Grid>
</Grid>
<Button type={"submit"} variant={"raised"} color={"primary"}>Submit</Button>
</form>
</Paper>
</Grow>
);
}
}
validation component
class MuiValidator extends Component {
constructor(props) {
super(props);
this.state = {
error : "",
errorMsg: ""
};
this.isValid = this.isValid.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange (e) {
this.props.onChange(e.target.value);
let isValidField = this.isValid(e.target);
// console.log(e.target.appendChild());
console.log(isValidField);
};
//Validation function
isValid (input) {
console.log(input);
//check required field
if (input.getAttribute("required") !== null && input.value === "") {
this.setState({error: true,errorMsg:'This field is required'});
return false
} else {
this.setState({error: false,errorMsg:''});
// input.nextSibling.textContent = "";
}
if (input.getAttribute("type") === "email" && input.value !== "") {
if (!this.validateEmail(input.value)) {
this.setState({error: true, errorMsg: "Please enter valid email address"})
return false
} else {
this.setState({error: false,errorMsg:''});
}
}
return true;
};
validateEmail = (value) => {
let 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,}))$/;
return re.test(value);
};
componentDidMount() {
if (this.props.onComponentMounted) {
this.props.onComponentMounted(this);
}
}
render() {
const {error,errorMsg} = this.state;
return (
<div>
<FormControl fullWidth={this.props.fullWidth} margin={"normal"} error={!!error}>
<InputLabel>First Name</InputLabel>
<Input name={this.props.name} type={this.props.type} placeholder={this.props.placeholder}
value={this.props.value} onChange={this.handleChange}
inputProps={this.props.inputProps} ref={this.props.name}/>
{error && <FormHelperText>{errorMsg}</FormHelperText>}
</FormControl>
</div>
);
}
}
I have no idea how can fix this please help me...
thanks all. finally, I found a solution. I changed the handle submit function like this
handleSubmit = (e) => {
e.preventDefault();
let validForm = true;
this.state.fields.forEach((field) => {
//create input element
let elm = document.createElement("input");
for (let attr in field.refs[field.props.name].props) {
if (attr !== "onChange" && attr !== "inputProps") {
elm.setAttribute(attr, field.refs[field.props.name].props[attr]);
elm.removeAttribute("onChange");
}
if (attr === "inputProps") {
for (let props in field.refs[field.props.name].props.inputProps) {
elm.setAttribute(props, field.refs[field.props.name].props.inputProps[props]);
}
}
}
if (typeof field.isValid === "function") {
let validField = field.isValid(elm);
validForm = validForm && validField
}
});
if (validForm) {
console.log(this.state.fields);
}
};
The problem resides in the on submit because the input is not retrieved correctly (I need a working code but it seems refs are not set correctly) while on event you pass the exact reference to the field coming directly from event. Check your refs and everything should work ok. As said from #SandipNirmal Formik has a great validation feature that you are substantially replicating.

Categories