Focus the first invalid field
This adjusts the submission step to focus the first invalid field and redisplay validation. This also rearranges the older style field error handling on registration which is slated for removal once we convert all fields to the new style.
This commit is contained in:
parent
62a01e7a37
commit
5d95c31875
2 changed files with 60 additions and 21 deletions
|
@ -89,15 +89,19 @@ module.exports = React.createClass({
|
||||||
// is the one from the first invalid field.
|
// is the one from the first invalid field.
|
||||||
// It's not super ideal that this just calls
|
// It's not super ideal that this just calls
|
||||||
// onValidationChange once for each invalid field.
|
// onValidationChange once for each invalid field.
|
||||||
// TODO: Change this to trigger new-style validation for an invalid fields.
|
// TODO: Remove these calls once converted to new-style validation.
|
||||||
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
||||||
this.validateField(FIELD_EMAIL, ev.type);
|
this.validateField(FIELD_EMAIL, ev.type);
|
||||||
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
|
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
|
||||||
this.validateField(FIELD_PASSWORD, ev.type);
|
this.validateField(FIELD_PASSWORD, ev.type);
|
||||||
this.validateField(FIELD_USERNAME, ev.type);
|
this.validateField(FIELD_USERNAME, ev.type);
|
||||||
|
|
||||||
|
const allFieldsValid = this.verifyFieldsBeforeSubmit();
|
||||||
|
if (!allFieldsValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
if (this.allFieldsValid()) {
|
|
||||||
if (this.state.email == '') {
|
if (this.state.email == '') {
|
||||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
||||||
|
@ -117,7 +121,6 @@ module.exports = React.createClass({
|
||||||
} else {
|
} else {
|
||||||
self._doSubmit(ev);
|
self._doSubmit(ev);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_doSubmit: function(ev) {
|
_doSubmit: function(ev) {
|
||||||
|
@ -138,6 +141,27 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
verifyFieldsBeforeSubmit() {
|
||||||
|
if (this.allFieldsValid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidField = this.findFirstInvalidField([
|
||||||
|
FIELD_USERNAME,
|
||||||
|
FIELD_PASSWORD,
|
||||||
|
FIELD_PASSWORD_CONFIRM,
|
||||||
|
FIELD_EMAIL,
|
||||||
|
FIELD_PHONE_NUMBER,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!invalidField) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidField.focus();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {boolean} true if all fields were valid last time they were validated.
|
* @returns {boolean} true if all fields were valid last time they were validated.
|
||||||
*/
|
*/
|
||||||
|
@ -158,6 +182,15 @@ module.exports = React.createClass({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
findFirstInvalidField(fieldIDs) {
|
||||||
|
for (const fieldID of fieldIDs) {
|
||||||
|
if (!this.state.fieldValid[fieldID] && this[fieldID]) {
|
||||||
|
return this[fieldID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
validateField: function(fieldID, eventType) {
|
validateField: function(fieldID, eventType) {
|
||||||
const pwd1 = this.state.password.trim();
|
const pwd1 = this.state.password.trim();
|
||||||
const pwd2 = this.state.passwordConfirm.trim();
|
const pwd2 = this.state.passwordConfirm.trim();
|
||||||
|
@ -362,6 +395,7 @@ module.exports = React.createClass({
|
||||||
return <Field
|
return <Field
|
||||||
className={this._classForField(FIELD_USERNAME)}
|
className={this._classForField(FIELD_USERNAME)}
|
||||||
id="mx_RegistrationForm_username"
|
id="mx_RegistrationForm_username"
|
||||||
|
ref={field => this[FIELD_USERNAME] = field}
|
||||||
type="text"
|
type="text"
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
label={_t("Username")}
|
label={_t("Username")}
|
||||||
|
|
|
@ -86,6 +86,10 @@ export default class Field extends React.PureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
focus() {
|
||||||
|
this.input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
validate({ value, focused }) {
|
validate({ value, focused }) {
|
||||||
if (!this.props.onValidate) {
|
if (!this.props.onValidate) {
|
||||||
return;
|
return;
|
||||||
|
@ -107,6 +111,7 @@ export default class Field extends React.PureComponent {
|
||||||
|
|
||||||
// Set some defaults for the <input> element
|
// Set some defaults for the <input> element
|
||||||
inputProps.type = inputProps.type || "text";
|
inputProps.type = inputProps.type || "text";
|
||||||
|
inputProps.ref = input => this.input = input;
|
||||||
inputProps.placeholder = inputProps.placeholder || inputProps.label;
|
inputProps.placeholder = inputProps.placeholder || inputProps.label;
|
||||||
|
|
||||||
inputProps.onFocus = this.onFocus;
|
inputProps.onFocus = this.onFocus;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue