I am using the official Semantic UI React components to create a web application. I have a form on my sign up page, which contains an email field, a password field, and a confirm password field.
import {Component} from 'react';
import {Button, Form, Message} from 'semantic-ui-react';
import {signUp} from '../../actions/auth';
class SignUp extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e, {formData}) {
e.preventDefault();
//
// Potentially need to manually validate fields here?
//
// Send a POST request to the server with the formData
this.props.dispatch(signUp(formData)).then(({isAuthenticated}) => {
if (isAuthenticated) {
// Redirect to the home page if the user is authenticated
this.props.router.push('/');
}
}
}
render() {
const {err} = this.props;
return (
<Form onSubmit={this.handleSubmit} error={Boolean(err)}>
<Form.Input label="Email" name="email" type="text"/>
<Form.Input label="Password" name="password" type="password"/>
<Form.Input label="Confirm Password" name="confirmPassword" type="password"/>
{err &&
<Message header="Error" content={err.message} error/>
}
<Button size="huge" type="submit" primary>Sign Up</Button>
</Form>
);
}
}
Now, I am used to the regular Semantic UI library, which has a Form Validation addon. Usually, I would define the rules like so in a separate JavaScript file
$('.ui.form').form({
fields: {
email: {
identifier: 'email',
rules: [{
type: 'empty',
prompt: 'Please enter your email address'
}, {
type: 'regExp',
value: "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
prompt: 'Please enter a valid email address'
}]
},
password: {
identifier: 'password',
rules: [{
type: 'empty',
prompt: 'Please enter your password'
}, {
type: 'minLength[8]',
prompt: 'Your password must be at least {ruleValue} characters'
}]
},
confirmPassword: {
identifier: 'confirmPassword',
rules: [{
type: 'match[password]',
prompt: 'The password you provided does not match'
}]
}
}
});
Is there a similar method using the Semantic UI React components for validating the form? I've searched through the documentation without any success, and there doesn't seem to be examples of validation using this Semantic UI React library.
Do I instead need to validate each field by hand in the handleSubmit
function? What is the best way to fix this problem? Thanks for the help!
For the most part, you have to validate forms by hand. However, RSUI includes a couple of tools to make things a bit easier, in particular the error prop on <Form>
and <Form.Input>
Here's an example of a form I put together recently. It could use a bit of refactoring, but it basically works by tying each input to state with an onChange()
function, and passing a callback to the submit function which controls the visibility of the loading screen and the "Success. Thank you for submitting" portion of the form.
export default class MeetingFormModal extends Component {
constructor(props) {
super(props)
this.state = {
firstName: '',
lastName: '',
email: '',
location: '',
firstNameError: false,
lastNameError: false,
emailError: false,
locationError: false,
formError: false,
errorMessage: 'Please complete all required fields.',
complete: false,
modalOpen: false
}
this.submitMeetingForm = this.submitMeetingForm.bind(this);
this.successCallback = this.successCallback.bind(this);
}
successCallback() {
this.setState({
complete: true
})
setTimeout( () => {this.setState({modalOpen: false})}, 5000);
this.props.hideLoading();
}
handleClose = () => this.setState({ modalOpen: false })
handleOpen = () => this.setState({ modalOpen: true })
submitMeetingForm() {
let error = false;
if (this.state.studentFirstName === '') {
this.setState({firstNameError: true})
error = true
} else {
this.setState({firstNameError: false})
error = false
}
if (this.state.studentLastName === '') {
this.setState({lastNameError: true})
error = true
} else {
this.setState({lastNameError: false})
error = false
}
if (this.state.email === '') {
this.setState({emailError: true})
error = true
} else {
this.setState({emailError: false})
error = false
}
if (this.state.location === '') {
this.setState({locationError: true})
error = true
} else {
this.setState({locationError: false})
error = false
}
if (error) {
this.setState({formError: true})
return
} else {
this.setState({formError: false})
}
let meeting = {
first_name: this.state.firstName,
last_name: this.state.lastName,
email: this.state.email,
location: this.state.location,
this.props.createMeeting(meeting, this.successCallback)
this.props.showLoading();
}
capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
render() {
return(
<Modal
trigger={<Button onClick={this.handleOpen} basic color='blue'>Schedule Now</Button>}
open={this.state.modalOpen}
onClose={this.handleClose}
closeIcon={true}
>
<Modal.Header>Schedule Your Interview</Modal.Header>
<Modal.Content>
{!this.state.complete ?
<Modal.Description>
<Form error={this.state.formError}>
<Form.Group widths='equal'>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({firstName: e.target.value})} label='First Name' placeholder="First Name..." error={this.state.firstNameError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({lastName: e.target.value})} label='Last Name' placeholder="Last Name..." error={this.state.lastNameError}/>
</Form.Field>
</Form.Group>
<Form.Field >
<Form.Input required={true} onChange={(e) => this.setState({email: e.target.value})} label='Email' placeholder="Email..." error={this.state.emailError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({location: e.target.value})} label='Location' placeholder='City, State/Province, Country...' error={this.state.locationError}/>
</Form.Field>
</Form>
</Modal.Description>
:
<div className='modal-complete'>
<Image src='/images/check.png' />
<p>Thanks for scheduling a meeting, {this.capitalize(this.state.name)}. We've received your information and we'll be in touch shortly.</p>
</div>
}
</Modal.Content>
{!this.state.complete ?
<Modal.Actions>
<Button color='red' onClick={this.handleClose}>Close</Button>
<Button positive icon='checkmark' labelPosition='right' content="Submit" onClick={this.submitMeetingForm} />
</Modal.Actions>
: null }
</Modal>
)
}
}
Hope that helps!