mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
UX: don't disable "create account" button & display error message for required fields. (#9643)
This commit is contained in:
@@ -6,6 +6,16 @@ export default Component.extend({
|
||||
classNameBindings: [":user-field", "field.field_type", "customFieldClass"],
|
||||
layoutName: fmt("field.field_type", "components/user-fields/%@"),
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
let element = this.element.querySelector(
|
||||
".user-field.dropdown .select-kit-header"
|
||||
);
|
||||
element = element || this.element.querySelector("input");
|
||||
this.field.element = element;
|
||||
},
|
||||
|
||||
@discourseComputed
|
||||
noneLabel() {
|
||||
return "user_fields.none";
|
||||
|
||||
@@ -61,27 +61,9 @@ export default Controller.extend(
|
||||
this._createUserFields();
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"passwordRequired",
|
||||
"nameValidation.failed",
|
||||
"emailValidation.failed",
|
||||
"usernameValidation.failed",
|
||||
"passwordValidation.failed",
|
||||
"userFieldsValidation.failed",
|
||||
"formSubmitted",
|
||||
"inviteCode"
|
||||
)
|
||||
@discourseComputed("formSubmitted")
|
||||
submitDisabled() {
|
||||
if (this.formSubmitted) return true;
|
||||
if (this.get("nameValidation.failed")) return true;
|
||||
if (this.get("emailValidation.failed")) return true;
|
||||
if (this.get("usernameValidation.failed") && this.usernameRequired)
|
||||
return true;
|
||||
if (this.get("passwordValidation.failed") && this.passwordRequired)
|
||||
return true;
|
||||
if (this.get("userFieldsValidation.failed")) return true;
|
||||
|
||||
if (this.requireInviteCode && !this.inviteCode) return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
@@ -114,18 +96,26 @@ export default Controller.extend(
|
||||
// Check the email address
|
||||
@discourseComputed("accountEmail", "rejectedEmails.[]")
|
||||
emailValidation(email, rejectedEmails) {
|
||||
const failedAttrs = {
|
||||
failed: true,
|
||||
element: document.querySelector("#new-account-email")
|
||||
};
|
||||
|
||||
// If blank, fail without a reason
|
||||
if (isEmpty(email)) {
|
||||
return EmberObject.create({
|
||||
failed: true
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
message: I18n.t("user.email.required")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (rejectedEmails.includes(email)) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.email.invalid")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.email.invalid")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -149,10 +139,11 @@ export default Controller.extend(
|
||||
});
|
||||
}
|
||||
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.email.invalid")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.email.invalid")
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
@@ -312,6 +303,34 @@ export default Controller.extend(
|
||||
},
|
||||
|
||||
createAccount() {
|
||||
this.clearFlash();
|
||||
|
||||
const validation = [
|
||||
this.emailValidation,
|
||||
this.usernameValidation,
|
||||
this.nameValidation,
|
||||
this.passwordValidation,
|
||||
this.userFieldsValidation
|
||||
].find(v => v.failed);
|
||||
|
||||
if (validation) {
|
||||
if (validation.message) {
|
||||
this.flash(validation.message, "error");
|
||||
}
|
||||
|
||||
const element = validation.element;
|
||||
if (element.tagName === "DIV") {
|
||||
if (element.scrollIntoView) {
|
||||
element.scrollIntoView();
|
||||
}
|
||||
element.click();
|
||||
} else {
|
||||
element.focus();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (new Date() - this._challengeDate > 1000 * this._challengeExpiry) {
|
||||
this.fetchConfirmationValue().then(() =>
|
||||
this.performAccountCreation()
|
||||
|
||||
@@ -18,7 +18,11 @@ export default Mixin.create({
|
||||
@discourseComputed("accountName")
|
||||
nameValidation() {
|
||||
if (this.siteSettings.full_name_required && isEmpty(this.accountName)) {
|
||||
return EmberObject.create({ failed: true });
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
message: I18n.t("user.name.required"),
|
||||
element: document.querySelector("#new-account-name")
|
||||
});
|
||||
}
|
||||
|
||||
return EmberObject.create({ ok: true });
|
||||
|
||||
@@ -43,44 +43,57 @@ export default Mixin.create({
|
||||
accountEmail,
|
||||
passwordMinLength
|
||||
) {
|
||||
const failedAttrs = {
|
||||
failed: true,
|
||||
element: document.querySelector("#new-account-password")
|
||||
};
|
||||
|
||||
if (!passwordRequired) {
|
||||
return EmberObject.create({ ok: true });
|
||||
}
|
||||
|
||||
if (rejectedPasswords.includes(password)) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason:
|
||||
this.rejectedPasswordsMessages.get(password) ||
|
||||
I18n.t("user.password.common")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason:
|
||||
this.rejectedPasswordsMessages.get(password) ||
|
||||
I18n.t("user.password.common")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// If blank, fail without a reason
|
||||
if (isEmpty(password)) {
|
||||
return EmberObject.create({ failed: true });
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
message: I18n.t("user.password.required")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// If too short
|
||||
if (password.length < passwordMinLength) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.password.too_short")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.password.too_short")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (!isEmpty(accountUsername) && password === accountUsername) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.password.same_as_username")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.password.same_as_username")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (!isEmpty(accountEmail) && password === accountEmail) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.password.same_as_email")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.password.same_as_email")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Looks good!
|
||||
|
||||
@@ -27,12 +27,17 @@ export default Mixin.create({
|
||||
userFields = userFields.filterBy("field.required");
|
||||
}
|
||||
if (!isEmpty(userFields)) {
|
||||
const anyEmpty = userFields.any(uf => {
|
||||
const emptyUserField = userFields.find(uf => {
|
||||
const val = uf.get("value");
|
||||
return !val || isEmpty(val);
|
||||
});
|
||||
if (anyEmpty) {
|
||||
return EmberObject.create({ failed: true });
|
||||
if (emptyUserField) {
|
||||
const userField = emptyUserField.field;
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
message: I18n.t("user_fields.required", { name: userField.name }),
|
||||
element: userField.element
|
||||
});
|
||||
}
|
||||
}
|
||||
return EmberObject.create({ ok: true });
|
||||
|
||||
@@ -31,6 +31,10 @@ export default Mixin.create({
|
||||
|
||||
@discourseComputed("accountUsername")
|
||||
basicUsernameValidation(accountUsername) {
|
||||
const failedAttrs = {
|
||||
failed: true,
|
||||
element: document.querySelector("#new-account-username")
|
||||
};
|
||||
this.set("uniqueUsernameValidation", null);
|
||||
|
||||
if (accountUsername && accountUsername === this.prefilledUsername) {
|
||||
@@ -42,31 +46,38 @@ export default Mixin.create({
|
||||
|
||||
// If blank, fail without a reason
|
||||
if (isEmpty(accountUsername)) {
|
||||
return EmberObject.create({ failed: true });
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
message: I18n.t("user.username.required")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// If too short
|
||||
if (accountUsername.length < this.siteSettings.min_username_length) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.username.too_short")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.username.too_short")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// If too long
|
||||
if (accountUsername.length > this.maxUsernameLength) {
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.username.too_long")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.username.too_long")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
this.checkUsernameAvailability();
|
||||
// Let's check it out asynchronously
|
||||
return EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.username.checking")
|
||||
});
|
||||
return EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.username.checking")
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
shouldCheckUsernameAvailability() {
|
||||
@@ -93,23 +104,30 @@ export default Mixin.create({
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const failedAttrs = {
|
||||
failed: true,
|
||||
element: document.querySelector("#new-account-username")
|
||||
};
|
||||
|
||||
if (result.suggestion) {
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create({
|
||||
failed: true,
|
||||
reason: I18n.t("user.username.not_available", result)
|
||||
})
|
||||
EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.username.not_available", result)
|
||||
})
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create({
|
||||
failed: true,
|
||||
reason: result.errors
|
||||
? result.errors.join(" ")
|
||||
: I18n.t("user.username.not_available_no_suggestion")
|
||||
})
|
||||
EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: result.errors
|
||||
? result.errors.join(" ")
|
||||
: I18n.t("user.username.not_available_no_suggestion")
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user