Merge pull request #2672 from jryans/password-validation
Report validity state of all registration fields on any change
This commit is contained in:
commit
426bdafe22
3 changed files with 46 additions and 23 deletions
|
@ -58,6 +58,10 @@ limitations under the License.
|
|||
background-color: $authpage-body-bg-color;
|
||||
}
|
||||
|
||||
.mx_AuthBody input.error {
|
||||
color: $warning-color;
|
||||
}
|
||||
|
||||
.mx_AuthBody_editServerDetails {
|
||||
padding-left: 1em;
|
||||
font-size: 12px;
|
||||
|
|
|
@ -308,7 +308,19 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
onFormValidationFailed: function(errCode) {
|
||||
onFormValidationChange: function(fieldErrors) {
|
||||
// `fieldErrors` is an object mapping field IDs to error codes when there is an
|
||||
// error or `null` for no error, so the values array will be something like:
|
||||
// `[ null, "RegistrationForm.ERR_PASSWORD_MISSING", null]`
|
||||
// Find the first non-null error code and show that.
|
||||
const errCode = Object.values(fieldErrors).find(value => !!value);
|
||||
if (!errCode) {
|
||||
this.setState({
|
||||
errorText: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let errMsg;
|
||||
switch (errCode) {
|
||||
case "RegistrationForm.ERR_PASSWORD_MISSING":
|
||||
|
@ -510,7 +522,7 @@ module.exports = React.createClass({
|
|||
defaultPhoneNumber={this.state.formVals.phoneNumber}
|
||||
defaultPassword={this.state.formVals.password}
|
||||
minPasswordLength={MIN_PASSWORD_LENGTH}
|
||||
onError={this.onFormValidationFailed}
|
||||
onValidationChange={this.onFormValidationChange}
|
||||
onRegisterClick={this.onFormSubmit}
|
||||
onEditServerDetailsClick={onEditServerDetailsClick}
|
||||
flows={this.state.flows}
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = React.createClass({
|
|||
defaultUsername: PropTypes.string,
|
||||
defaultPassword: PropTypes.string,
|
||||
minPasswordLength: PropTypes.number,
|
||||
onError: PropTypes.func,
|
||||
onValidationChange: PropTypes.func,
|
||||
onRegisterClick: PropTypes.func.isRequired, // onRegisterClick(Object) => ?Promise
|
||||
onEditServerDetailsClick: PropTypes.func,
|
||||
flows: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
|
@ -60,15 +60,14 @@ module.exports = React.createClass({
|
|||
getDefaultProps: function() {
|
||||
return {
|
||||
minPasswordLength: 6,
|
||||
onError: function(e) {
|
||||
console.error(e);
|
||||
},
|
||||
onValidationChange: console.error,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
fieldValid: {},
|
||||
// Field error codes by field ID
|
||||
fieldErrors: {},
|
||||
// The ISO2 country code selected in the phone number entry
|
||||
phoneCountry: this.props.defaultPhoneCountry,
|
||||
};
|
||||
|
@ -81,12 +80,12 @@ module.exports = React.createClass({
|
|||
// the error that ends up being displayed
|
||||
// is the one from the first invalid field.
|
||||
// It's not super ideal that this just calls
|
||||
// onError once for each invalid field.
|
||||
// onValidationChange once for each invalid field.
|
||||
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
||||
this.validateField(FIELD_EMAIL, ev.type);
|
||||
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
|
||||
this.validateField(FIELD_PASSWORD, ev.type);
|
||||
this.validateField(FIELD_USERNAME, ev.type);
|
||||
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
||||
this.validateField(FIELD_EMAIL, ev.type);
|
||||
|
||||
const self = this;
|
||||
if (this.allFieldsValid()) {
|
||||
|
@ -134,9 +133,9 @@ module.exports = React.createClass({
|
|||
* @returns {boolean} true if all fields were valid last time they were validated.
|
||||
*/
|
||||
allFieldsValid: function() {
|
||||
const keys = Object.keys(this.state.fieldValid);
|
||||
const keys = Object.keys(this.state.fieldErrors);
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
if (this.state.fieldValid[keys[i]] == false) {
|
||||
if (this.state.fieldErrors[keys[i]]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -206,21 +205,29 @@ module.exports = React.createClass({
|
|||
}
|
||||
break;
|
||||
case FIELD_PASSWORD_CONFIRM:
|
||||
this.markFieldValid(
|
||||
fieldID, pwd1 == pwd2,
|
||||
"RegistrationForm.ERR_PASSWORD_MISMATCH",
|
||||
);
|
||||
if (allowEmpty && pwd2 === "") {
|
||||
this.markFieldValid(fieldID, true);
|
||||
} else {
|
||||
this.markFieldValid(
|
||||
fieldID, pwd1 == pwd2,
|
||||
"RegistrationForm.ERR_PASSWORD_MISMATCH",
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
markFieldValid: function(fieldID, val, errorCode) {
|
||||
const fieldValid = this.state.fieldValid;
|
||||
fieldValid[fieldID] = val;
|
||||
this.setState({fieldValid: fieldValid});
|
||||
if (!val) {
|
||||
this.props.onError(errorCode);
|
||||
markFieldValid: function(fieldID, valid, errorCode) {
|
||||
const { fieldErrors } = this.state;
|
||||
if (valid) {
|
||||
fieldErrors[fieldID] = null;
|
||||
} else {
|
||||
fieldErrors[fieldID] = errorCode;
|
||||
}
|
||||
this.setState({
|
||||
fieldErrors,
|
||||
});
|
||||
this.props.onValidationChange(fieldErrors);
|
||||
},
|
||||
|
||||
fieldElementById(fieldID) {
|
||||
|
@ -240,7 +247,7 @@ module.exports = React.createClass({
|
|||
|
||||
_classForField: function(fieldID, ...baseClasses) {
|
||||
let cls = baseClasses.join(' ');
|
||||
if (this.state.fieldValid[fieldID] === false) {
|
||||
if (this.state.fieldErrors[fieldID]) {
|
||||
if (cls) cls += ' ';
|
||||
cls += 'error';
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue