So, you want to query the server to check to see if the package is not in the DB? What is your backend? Are you using Laravel, Node, SSR React or something else?
Jan 28, 2018
3
Level 5
React Async validation
Hello All,
Anyone have any experience with React / async validation? I'm trying to figure out how to do an async validation with JOI.
I can do client side validation, but not sure how to add the async validation. I basically have a required field called package. I want it to server side validation onBlur to see if the package is taken. Can some one give me a hand?
Here's what my code looks like
'use strict';
import axios from 'axios'
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import validation from 'react-validation-mixin';
import strategy from 'joi-validation-strategy';
import Joi from 'joi';
import { Row, Col, Button, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, Card, CardHeader, CardFooter, CardBody, Form, FormGroup, FormText, Label, Input,
InputGroup, InputGroupAddon, InputGroupButton} from 'reactstrap';
class Step1 extends Component {
constructor(props) {
super(props)
// sets state of package name
this.state = {
packagename: props.getStore().packagename
};
this.validatorTypes = {
packagename: Joi.string().required().min(3).label("The Package Name")
};
this.getValidatorData = this.getValidatorData.bind(this);
this.renderHelpText = this.renderHelpText.bind(this);
this.isValidated = this.isValidated.bind(this);
}
isValidated() {
return new Promise((resolve, reject) => {
this.props.validate((error) => {
if (error) {
reject(); // form contains errors
console.log("Error fired");
return;
}
if (this.props.getStore().packagename != this.getValidatorData().packagename) { // only update store of something changed
this.props.updateStore({
...this.getValidatorData(),
savedToCloud: true // use this to notify step4 that some changes took place and prompt the user to save again
}); // Update store here (this is just an example, in reality you will do it via redux or flux)
// Ajax send response to server goes here!
console.log("Validation fired");
}
resolve(); // form is valid, fire action
});
});
}
getValidatorData() {
return {
packagename: this.refs.packagename.value,
}
};
onChange(e) {
let newState = {};
newState[e.target.name] = e.target.value;
this.setState(newState);
}
renderHelpText(message, id) {
return (<div className="val-err-tooltip" key={id}><span>{message}</span></div>);
};
render() {
// explicit class assigning based on validation
let notValidClasses = {};
notValidClasses.packagenameCls = this.props.isValid('packagename') ?
'no-error col-md-8' : 'has-error col-md-8';
return (
<div className="step step1">
<div className="row">
<form id="Form" className="form-horizontal">
<div id="stepscontainer" className="form-group">
<label className="col-md-12 control-label">
<h2>Please provide a unique name for the package</h2>
</label>
<div className="row content">
<div className="col-md-12">
Give a short name that can identify the package with, using underscore and no spaces.
<br /><br />
<FormGroup row>
<Col xs="12" md="9">
<div className={notValidClasses.packagenameCls}>
<input
ref="packagename"
name="packagename"
autoComplete="off"
type="text"
className="form-control"
placeholder="Package name"
required
defaultValue={this.state.packagename}
id="packagename"
onBlur={this.props.handleValidation('packagename')}
onChange={this.onChange.bind(this)}
size="145" />
{this.props.getValidationMessages('packagename').map(this.renderHelpText)}
</div>
</Col>
</FormGroup>
</div>
<div className="col-md-12 eg-jump-lnk">
</div>
</div>
</div>
</form>
</div>
</div>
)
}
}
Step1.propTypes = {
errors: PropTypes.object,
validate: PropTypes.func,
isValid: PropTypes.func,
handleValidation: PropTypes.func,
getValidationMessages: PropTypes.func,
clearValidations: PropTypes.func,
getStore: PropTypes.func,
updateStore: PropTypes.func
};
export default validation(strategy)(Step1);
Thanks, Dan
Please or to participate in this conversation.