Skip to content
This repository has been archived by the owner on Oct 1, 2019. It is now read-only.

Commit

Permalink
Remove Password form's SubmitEvent hack. New validation interface
Browse files Browse the repository at this point in the history
  • Loading branch information
artkravchenko committed Jun 1, 2016
1 parent 5fdf491 commit ee2227d
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 122 deletions.
209 changes: 101 additions & 108 deletions src/components/settings/password-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,126 +16,119 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { PropTypes } from 'react';
import { form as inform, from } from 'react-inform';

// TODO: Consider using redux-form or formsy-react or another form library.
export default class PasswordForm extends React.Component {
import Message from '../message';

class PasswordForm extends React.Component {
static displayName = 'PasswordForm';

static propTypes = {
onSubmit: PropTypes.func
};

static defaultProps = {
onSubmit: () => {}
};

constructor(props) {
super(props);

this.state = {
errors: {
old_password: null,
new_password: null,
new_password_repeat: null
}
};
}

_validateOldPassword = () => {
const errors = this.state.errors;
const { old_password } = this.form;

if (old_password.value.length === 0) {
errors.old_password = 'Enter your current password';
} else {
errors.old_password = null;
}

this.setState({ errors });
};

_validateNewPassword = () => {
const errors = this.state.errors;
const { new_password } = this.form;

if (new_password.value.length < 8) {
errors.new_password = 'Password must be at least 8 characters';
} else {
errors.new_password = null;
}

this.setState({ errors });
};

_validateNewPasswordRepeat = () => {
const errors = this.state.errors;
const { new_password, new_password_repeat } = this.form;

if (new_password_repeat.value.length > 0 && new_password.value !== new_password_repeat.value) {
errors.new_password_repeat = 'Passwords do not match';
} else {
errors.new_password_repeat = null;
}

this.setState({ errors });
};

_handleSubmit = (event) => {
const { old_password, new_password, new_password_repeat } = this.state.errors;
const valid = !old_password && !new_password && !new_password_repeat;

if (valid) {
this.props.onSubmit(event);
} else {
event.preventDefault();
}
fields: PropTypes.shape({
oldPassword: PropTypes.shape({
error: PropTypes.string
}).isRequired,
newPassword: PropTypes.shape({
error: PropTypes.string
}).isRequired,
newPasswordRepeat: PropTypes.shape({
error: PropTypes.string
}).isRequired
}).isRequired,
form: PropTypes.shape({
forceValidate: PropTypes.func.isRequired,
isValid: PropTypes.func.isRequired,
onValues: PropTypes.func.isRequired
}).isRequired
};

render() {
const { errors } = this.state;
const { fields, form } = this.props;

return (
<form action="" className="paper__page" ref={c => this.form = c} onSubmit={this._handleSubmit}>
<form action="" className="paper__page">
<h2 className="content__sub_title layout__row">Password</h2>

<label className="layout__row layout__row-small" htmlFor="old_password">Current password</label>
<input
className="input input-block layout__row layout__row-small"
id="old_password"
name="old_password"
placeholder="secret"
required
type="password"
onChange={this._validateOldPassword}
/>
{errors.old_password && <div className="validation_error">{errors.old_password}</div>}

<label className="layout__row layout__row-small" htmlFor="new_password">New password</label>
<input
className="input input-block layout__row layout__row-small"
id="new_password"
name="new_password"
placeholder="mystery"
required
type="password"
onChange={this._validateNewPassword}
/>
{errors.new_password && <div className="validation_error">{errors.new_password}</div>}

<label className="layout__row layout__row-small" htmlFor="new_password_repeat">Repeat new password...</label>
<input
className="input input-block layout__row layout__row-small"
id="new_password_repeat"
name="new_password_repeat"
placeholder="mystery"
required
type="password"
onChange={this._validateNewPasswordRepeat}
/>
{errors.new_password_repeat && <div className="validation_error">{errors.new_password_repeat}</div>}

<input className="hidden" ref={c => this.submit = c} type="submit" />
<div className="layout__row">
<label className="layout__row layout__row-small" htmlFor="oldPassword">Current password</label>
<input
className="input input-block layout__row layout__row-small"
id="oldPassword"
name="oldPassword"
placeholder="secret"
required
type="password"
onChange={this._validateOldPassword}
{...fields.oldPassword}
/>
{fields.oldPassword.error &&
<Message message={fields.oldPassword.error} />
}
</div>

<div className="layout__row">
<label className="layout__row layout__row-small" htmlFor="newPassword">New password</label>
<input
className="input input-block layout__row layout__row-small"
id="newPassword"
name="newPassword"
placeholder="mystery"
required
type="password"
onChange={this._validateNewPassword}
{...fields.newPassword}
/>
{fields.newPassword.error &&
<Message message={fields.newPassword.error} />
}
</div>

<div className="layout__row">
<label className="layout__row layout__row-small" htmlFor="newPasswordRepeat">Repeat new password</label>
<input
className="input input-block layout__row layout__row-small"
id="newPasswordRepeat"
name="newPasswordRepeat"
placeholder="mystery"
required
type="password"
onChange={this._validateNewPasswordRepeat}
{...fields.newPasswordRepeat}
/>
{fields.newPasswordRepeat.error &&
<Message message={fields.newPasswordRepeat.error} />
}
</div>
</form>
);
}
}

const validateNewPassword = (password) => {
if (password && password.length < 8) {
return false;
}
return true;
};

const validateNewPasswordRepeat = (newPasswordRepeat, form) => {
if (form.newPassword !== newPasswordRepeat) {
return false;
}
return true;
};

const WrappedPasswordForm = inform(from({
oldPassword: {
'Enter your current password': o => o
},
newPassword: {
'Enter new password': n => n,
'Password must contain at least 8 symbols': validateNewPassword
},
newPasswordRepeat: {
'Passwords don\'t match': validateNewPasswordRepeat
}
}))(PasswordForm);

export default WrappedPasswordForm;
27 changes: 13 additions & 14 deletions src/pages/settings-password.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,25 @@ class SettingsPasswordPage extends React.Component {
}

onSave = () => {
const event = document.createEvent("HTMLEvents");
event.initEvent('submit', true, true);
event.eventType = 'submit';
const form = this.form.formProps();

this.form.dispatchEvent(event);
form.forceValidate();
if (form.isValid()) {
this.save();
}
};

save = (e) => {
e && e.preventDefault();

save = () => {
const client = new ApiClient(API_HOST);
const triggers = new ActionsTrigger(client, this.props.dispatch);

const form = this.form.formProps();
const fields = form.values();

const promise = triggers.changePassword(
this.form.old_password.value,
this.form.new_password.value,
this.form.new_password_repeat.value
fields.oldPassword,
fields.newPassword,
fields.newPasswordRepeat
);

promise.catch(e => {
Expand Down Expand Up @@ -101,10 +103,7 @@ class SettingsPasswordPage extends React.Component {
onSave={this.onSave}
>
<Helmet title="Change Password for " />
<SettingsPasswordForm
ref={c => this.form = c}
onSubmit={this.save}
/>
<SettingsPasswordForm ref={c => this.form = c} />

{false &&
<div className="paper__page">
Expand Down

0 comments on commit ee2227d

Please sign in to comment.