Commit f0c2280f authored by Matthew Taylor's avatar Matthew Taylor

Updates to registration UX for teachers

1. Phone too long validation occurs before submit now.
2. Organization “other” type is now being required
3. Organization type required now shows up at the same time as other organization validation errors
4. Username check now occurs earlier, on blur rather than on submit
parent 2407f1d6
var allCountries = require('react-telephone-input/lib/country_data').allCountries;
var classNames = require('classnames');
var React = require('react');
var ComponentMixin = require('formsy-react-components').ComponentMixin;
var FormsyMixin = require('formsy-react').Mixin;
var React = require('react');
var ReactPhoneInput = require('react-telephone-input/lib/withStyles');
var allCountries = require('react-telephone-input/lib/country_data').allCountries;
var defaultValidationHOC = require('./validations.jsx').defaultValidationHOC;
var validationHOCFactory = require('./validations.jsx').validationHOCFactory;
var Row = require('formsy-react-components').Row;
var ComponentMixin = require('formsy-react-components').ComponentMixin;
var defaultValidationHOC = require('./validations.jsx').defaultValidationHOC;
var inputHOC = require('./input-hoc.jsx');
var intl = require('../../lib/intl.jsx');
var validationHOCFactory = require('./validations.jsx').validationHOCFactory;
var allIso2 = allCountries.map(function (country) {return country.iso2;});
......@@ -23,7 +25,8 @@ var PhoneInput = React.createClass({
getDefaultProps: function () {
return {
validations: {
isPhone: true
isPhone: true,
phoneLength: true
},
flagsImagePath: '/images/flags.png',
defaultCountry: 'us'
......@@ -62,7 +65,8 @@ var PhoneInput = React.createClass({
});
var phoneValidationHOC = validationHOCFactory({
isPhone: 'Please enter a valid phone number'
isPhone: <intl.FormattedMessage id="teacherRegistration.validationPhoneNumber" />,
phoneLength: <intl.FormattedMessage id="teacherRegistration.validationPhoneNumber" />
});
module.exports = inputHOC(defaultValidationHOC(phoneValidationHOC(PhoneInput)));
......@@ -21,6 +21,14 @@ module.exports.validations = {
return false;
}
return phoneNumberUtil.isValidNumber(parsed);
},
phoneLength: function (values, value) {
if (typeof value === 'undefined') return true;
if (value && value.national_number === '+') return true;
if (value && value.national_number.length === value.country_code.format.length) {
return true;
}
return false;
}
};
......
......@@ -82,38 +82,53 @@ module.exports = {
onChangeShowPassword: function (field, value) {
this.setState({showPassword: value});
},
onValidSubmit: function (formData, reset, invalidate) {
this.setState({waiting: true});
validateUsername: function (username) {
api({
host: '',
uri: '/accounts/check_username/' + formData.user.username + '/'
uri: '/accounts/check_username/' + username + '/'
}, function (err, res) {
var formatMessage = this.props.intl.formatMessage;
this.setState({waiting: false});
if (err) return invalidate({all: err});
if (err) {
this.refs.form.refs.formsy.updateInputsWithError({all: err});
return false;
}
res = res[0];
switch (res.msg) {
case 'valid username':
this.setState({
validUsername: 'pass'
});
return this.props.onNextStep(formData);
return true;
case 'username exists':
return invalidate({
this.refs.form.refs.formsy.updateInputsWithError({
'user.username': formatMessage({id: 'registration.validationUsernameExists'})
});
return false;
case 'bad username':
return invalidate({
this.refs.form.refs.formsy.updateInputsWithError({
'user.username': formatMessage({id: 'registration.validationUsernameVulgar'})
});
return false;
case 'invalid username':
default:
return invalidate({
this.refs.form.refs.formsy.updateInputsWithError({
'user.username': formatMessage({id: 'registration.validationUsernameInvalid'})
});
return false;
}
}.bind(this));
},
onUsernameBlur: function (event) {
this.validateUsername(event.currentTarget.value);
},
onValidSubmit: function (formData) {
this.setState({waiting: true});
this.validateUsername(formData.user.username);
this.setState({waiting: false});
if (this.state.validUsername === 'pass') {
this.props.onNextStep(formData);
}
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
return (
......@@ -139,7 +154,7 @@ module.exports = {
)}
</p>
<Card>
<Form onValidSubmit={this.onValidSubmit}>
<Form onValidSubmit={this.onValidSubmit} ref="form">
<div>
<div className="username-label">
<b>{formatMessage({id: 'registration.createUsername'})}</b>
......@@ -152,6 +167,7 @@ module.exports = {
<Input className={this.state.validUsername}
type="text"
name="user.username"
onBlur={this.onUsernameBlur}
validations={{
matchRegexp: /^[\w-]*$/,
minLength: 3,
......@@ -473,8 +489,21 @@ module.exports = {
onChooseOrganization: function (name, values) {
this.setState({otherDisabled: values.indexOf(this.organizationL10nStems.indexOf('orgChoiceOther')) === -1});
},
onValidSubmit: function (formData, reset, invalidate) {
validateOrganizationType: function (formData) {
if (formData.organization.type.length < 1) {
return false;
}
return true;
},
onSubmit: function (formData, reset, invalidate) {
if (!this.validateOrganizationType(formData)) {
return invalidate({
'organization.type': this.props.intl.formatMessage({id: 'teacherRegistration.validationRequired'})
});
}
},
onValidSubmit: function (formData, reset, invalidate) {
if (!this.validateOrganizationType(formData)) {
return invalidate({
'organization.type': this.props.intl.formatMessage({id: 'teacherRegistration.validationRequired'})
});
......@@ -494,7 +523,7 @@ module.exports = {
tipContent={formatMessage({id: 'registration.nameStepTooltip'})} />
</p>
<Card>
<Form onValidSubmit={this.onValidSubmit}>
<Form onValidSubmit={this.onValidSubmit} onSubmit={this.onSubmit}>
<Input label={formatMessage({id: 'teacherRegistration.organization'})}
type="text"
name="organization.name"
......@@ -515,10 +544,11 @@ module.exports = {
required />
</div>
<div className="other-input">
<Input type="text"
name="organization.other"
<Input name="organization.other"
type="text"
disabled={this.state.otherDisabled}
required="isFalse"
required={!this.state.otherDisabled}
help={null}
placeholder={formatMessage({id: 'general.other'})} />
</div>
<div className="url-input">
......@@ -532,7 +562,7 @@ module.exports = {
placeholder={'http://'} />
</div>
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="registration.nextStep" />} />
text={<intl.FormattedMessage id="registration.nextStep" />} />
</Form>
</Card>
<StepNavigation steps={this.props.totalSteps - 1} active={this.props.activeStep} />
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment