Skip to content

Commit

Permalink
Show UI warnings when password does not match confirm
Browse files Browse the repository at this point in the history
  • Loading branch information
hotblac committed Aug 5, 2018
1 parent 9188419 commit 5dd4fb5
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 17 deletions.
35 changes: 35 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"license": "MIT",
"author": "Stuart 'Stevie' Leitch",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.2",
"@fortawesome/free-solid-svg-icons": "^5.2.0",
"@fortawesome/react-fontawesome": "^0.1.0",
"bulma": "^0.7.1",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
Expand Down
39 changes: 25 additions & 14 deletions src/UserRegistration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { Component } from 'react';
import 'bulma/css/bulma.css'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons'

export class UserRegistration extends Component {

Expand All @@ -9,30 +11,34 @@ export class UserRegistration extends Component {
username: '',
password: '',
confirm: '',
submitEnabled: false
passwordMatchesConfirm: true
};
this.handleSubmit = this.handleSubmit.bind(this);
}

submitEnabled = () => {
return this.state.password && this.state.passwordMatchesConfirm;
};

handleInputChange = (event) => {
const target = event.target;

// Logic to check passwords match must check input change against existing field value.
let submitEnabled = false;
let passwordMatchesConfirm = this.state.passwordMatchesConfirm;
if (target.name === 'password') {
submitEnabled = target.value && (target.value === this.state.confirm);
passwordMatchesConfirm = target.value && (target.value === this.state.confirm);
} else if (target.name === 'confirm') {
submitEnabled = target.value && (target.value === this.state.password);
passwordMatchesConfirm = target.value && (target.value === this.state.password);
}

this.setState({
[target.name]: target.value,
submitEnabled: submitEnabled
passwordMatchesConfirm: passwordMatchesConfirm
});
};

handleSubmit = () => {
if (this.state.submitEnabled) {
if (this.submitEnabled()) {
this.props.onSubmit(this.state.username, this.state.password);
} else {
console.error("Attempt to submit form when form has validation errors");
Expand All @@ -43,25 +49,30 @@ export class UserRegistration extends Component {
return (
<div>
<h1 className="title">Create an account</h1>
<div className="field">
<div className="field" id="usernameField">
<label className="label">Username</label>
<div className="control">
<input name="username" type="text" className="input username" onChange={this.handleInputChange}/>
<input name="username" type="text" className="input" onChange={this.handleInputChange}/>
</div>
</div>
<div className="field">
<div className="field" id="passwordField">
<label className="label">Password</label>
<div className="control">
<input name="password" type="password" className="input password" onChange={this.handleInputChange}/>
<input name="password" type="password" className="input" onChange={this.handleInputChange}/>
</div>
</div>
<div className="field">
<div className="field" id="confirmField">
<label className="label">Confirm Password</label>
<div className="control">
<input name="confirm" type="password" className="input confirm" onChange={this.handleInputChange}/>
<div className="control has-icons-right">
<input name="confirm" type="password" className={'input' + (this.state.passwordMatchesConfirm ? '' : ' is-danger')} onChange={this.handleInputChange}/>
{!this.state.passwordMatchesConfirm &&
<span className="icon is-small is-right">
<FontAwesomeIcon icon={faExclamationCircle}/>
</span>
}
</div>
</div>
<button className="button is-primary" onClick={this.handleSubmit} disabled={!this.state.submitEnabled}>Submit</button>
<button className="button is-primary" onClick={this.handleSubmit} disabled={!this.submitEnabled()}>Submit</button>
</div>
);
}
Expand Down
28 changes: 25 additions & 3 deletions src/UserRegistration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,33 @@ describe ('<UserRegistration/>', () => {
expect(onSubmit).not.toBeCalled();
});

it('shows error markers when password does not match confirmation', () => {
const wrapper = shallow(<UserRegistration/>);
setFieldValues(wrapper, username, password, 'mismatch');

const inputField = wrapper.find('#confirmField input')
const errorIcon = wrapper.find('#confirmField .icon');

expect(inputField.hasClass('is-danger')).toBe(true);
expect(errorIcon.exists()).toBe(true);
});

it('hides error marker when password does matches confirmation', () => {
const wrapper = shallow(<UserRegistration/>);
setFieldValues(wrapper, username, password, password);

const inputField = wrapper.find('#confirmField input')
const errorIcon = wrapper.find('#confirmField .icon');

expect(inputField.hasClass('is-danger')).toBe(false);
expect(errorIcon.exists()).toBe(false);
});


function setFieldValues(wrapper, username, password, confirm) {
const usernameField = wrapper.find('input.username');
const passwordField = wrapper.find('input.password');
const confirmField = wrapper.find('input.confirm');
const usernameField = wrapper.find('#usernameField input');
const passwordField = wrapper.find('#passwordField input');
const confirmField = wrapper.find('#confirmField input');

usernameField.simulate('change', stubEvent(usernameField, username));
passwordField.simulate('change', stubEvent(passwordField, password));
Expand Down

0 comments on commit 5dd4fb5

Please sign in to comment.