Added HTML5 form.reportValidity() to login screens

This improves browser feedback on form errors
This commit is contained in:
djmaze
2021-03-23 11:28:36 +01:00
parent 612aff4b27
commit cca0fc15da
5 changed files with 74 additions and 105 deletions

View File

@@ -58,10 +58,10 @@ class RemoteUserFetch extends AbstractFetchRemote {
* @param {string=} sAdditionalCode
* @param {boolean=} bAdditionalCodeSignMe
*/
login(fCallback, sEmail, sLogin, sPassword, bSignMe, sLanguage, sAdditionalCode, bAdditionalCodeSignMe) {
login(fCallback, sEmail, sPassword, bSignMe, sLanguage, sAdditionalCode, bAdditionalCodeSignMe) {
this.defaultRequest(fCallback, 'Login', {
Email: sEmail,
Login: sLogin,
Login: '',
Password: sPassword,
Language: sLanguage || '',
AdditionalCode: sAdditionalCode || '',

View File

@@ -31,12 +31,7 @@ class LoginAdminView extends AbstractViewCenter {
this.addSubscribables({
login: () => this.loginError(false),
password: () => this.passwordError(false),
loginError: v => this.formError(!!v),
passwordError: v => this.formError(!!v)
password: () => this.passwordError(false)
});
decorateKoCommands(this, {
@@ -44,33 +39,33 @@ class LoginAdminView extends AbstractViewCenter {
});
}
submitCommand() {
this.loginError(false);
this.passwordError(false);
submitCommand(self, event) {
const valid = event.target.form.reportValidity(),
name = this.login().trim(),
pass = this.password();
this.loginError(!this.login().trim());
this.passwordError(!this.password().trim());
this.loginError(!name);
this.passwordError(!pass);
this.formError(!valid);
if (this.loginError() || this.passwordError()) {
return false;
if (valid) {
this.submitRequest(true);
Remote.adminLogin(
iError => {
if (iError) {
this.submitRequest(false);
this.submitError(getNotification(iError));
} else {
rl.route.reload();
}
},
name,
pass
);
}
this.submitRequest(true);
Remote.adminLogin(
(iError) => {
this.submitRequest(false);
if (iError) {
this.submitError(getNotification(iError));
} else {
rl.route.reload();
}
},
this.login(),
this.password()
);
return true;
return valid;
}
onShow() {
@@ -78,7 +73,7 @@ class LoginAdminView extends AbstractViewCenter {
}
submitForm() {
this.submitCommand();
// return false;
}
}

View File

@@ -95,13 +95,8 @@ class LoginUserView extends AbstractViewCenter {
password: () => this.passwordError(false),
additionalCode: () => this.additionalCodeError(false),
additionalCodeError: bV => this.formError(!!bV),
additionalCodeVisibility: () => this.additionalCodeError(false),
emailError: bV => this.formError(!!bV),
passwordError: bV => this.formError(!!bV),
submitError: value => value || this.submitErrorAddidional(''),
signMeType: iValue => this.signMe(LoginSignMeType.DefaultOn === iValue)
@@ -116,72 +111,53 @@ class LoginUserView extends AbstractViewCenter {
});
}
windowOpenFeatures(wh) {
return `left=200,top=100,width=${wh},height=${wh},menubar=no,status=no,resizable=yes,scrollbars=yes`;
}
submitCommand(self, event) {
let email = this.email().trim(),
valid = event.target.form.reportValidity() && email,
pass = this.password(),
totp = this.additionalCodeVisibility(),
code = totp ? this.additionalCode() : '';
submitCommand() {
this.emailError(false);
this.passwordError(false);
this.emailError(!email);
this.passwordError(!pass);
this.formError(!valid);
this.additionalCodeError(totp && !code);
let error;
if (this.additionalCodeVisibility()) {
this.additionalCodeError(false);
if (!this.additionalCode().trim()) {
this.additionalCodeError(true);
error = '.inputAdditionalCode';
}
}
if (!this.password().trim()) {
this.passwordError(true);
error = '#RainLoopPassword';
}
if (!this.email().trim()) {
this.emailError(true);
error = '#RainLoopEmail';
}
if (error) {
this.querySelector(error).focus();
return false;
}
if (valid) {
this.submitRequest(true);
this.submitRequest(true);
const fLoginRequest = (sLoginPassword) => {
Remote.login(
(iError, oData) => {
this.submitRequest(false);
if (iError) {
this.submitRequest(false);
if (Notification.InvalidInputArgument == iError) {
iError = Notification.AuthError;
}
this.submitError(getNotification(iError, oData.ErrorMessage, Notification.UnknownNotification));
this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || '');
} else if (oData.TwoFactorAuth) {
this.submitRequest(false);
this.additionalCode('');
this.additionalCodeVisibility(true);
let input = this.querySelector('.inputAdditionalCode');
input.required = true;
setTimeout(() => input.focus(), 100);
} else {
if (oData.TwoFactorAuth) {
this.additionalCode('');
this.additionalCodeVisibility(true);
setTimeout(() => this.querySelector('.inputAdditionalCode').focus(), 100);
} else {
rl.route.reload();
}
rl.route.reload();
}
},
this.email(),
'',
sLoginPassword,
email,
pass,
!!this.signMe(),
this.bSendLanguage ? this.language() : '',
this.additionalCodeVisibility() ? this.additionalCode() : '',
this.additionalCodeVisibility() ? !!this.additionalCodeSignMe() : false
code,
!!(totp && this.additionalCodeSignMe())
);
Local.set(ClientSideKeyName.LastSignMe, this.signMe() ? '-1-' : '-0-');
};
}
fLoginRequest(this.password());
return true;
return valid;
}
onShow() {
@@ -234,7 +210,7 @@ class LoginUserView extends AbstractViewCenter {
}
submitForm() {
this.submitCommand();
// return false;
}
selectLanguage() {

View File

@@ -8,10 +8,9 @@
<form class="wrapper submitting-pane loginForm" action="#/" data-bind="submit: submitForm, css: {'errorAnimated': formError, 'submitting': submitRequest()}">
<div class="controls" data-bind="css: {'error': loginError}">
<div class="input-append">
<input type="text" class="input-block-level inputLogin"
name="RainLoopAdminLogin" id="RainLoopAdminLogin"
autofocus=""
autocomplete="username" autocorrect="off" autocapitalize="off" spellcheck="false" data-i18n="[placeholder]LOGIN/LABEL_LOGIN"
<input required="" type="text" class="input-block-level inputLogin"
autofocus="" autocomplete="username" autocorrect="off" autocapitalize="off" spellcheck="false"
data-i18n="[placeholder]LOGIN/LABEL_LOGIN"
data-bind="textInput: login, disable: submitRequest" />
<span class="add-on">
<i class="fontastic">👤</i>
@@ -20,9 +19,9 @@
</div>
<div class="controls" data-bind="css: {'error': passwordError}">
<div class="input-append">
<input type="password" class="input-block-level inputPassword"
placeholder="Password" name="RainLoopAdminPassword" id="RainLoopAdminPassword"
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false" data-i18n="[placeholder]LOGIN/LABEL_PASSWORD"
<input required="" type="password" class="input-block-level inputPassword"
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
data-i18n="[placeholder]LOGIN/LABEL_PASSWORD"
data-bind="textInput: password, disable: submitRequest" />
<span class="add-on" tabindex="-1" data-bind="command: submitCommand, tooltip: 'LOGIN/BUTTON_LOGIN'">
<i class="fontastic" data-bind="visible: '' === password()">🔑</i>
@@ -30,13 +29,13 @@
</span>
</div>
</div>
<div class="controls controls-submit-wrp" data-bind="hidden: hideSubmitButton">
<button type="submit" class="btn btn-large btn-block buttonLogin" data-bind="command: submitCommand">
<span data-i18n="LOGIN/BUTTON_LOGIN"></span>
<div class="controls" data-bind="hidden: hideSubmitButton">
<button type="submit" class="btn btn-large btn-block buttonLogin"
data-bind="command: submitCommand"
data-i18n="LOGIN/BUTTON_LOGIN">
</button>
</div>
</form>
</div>
</div>
<div>

View File

@@ -18,10 +18,9 @@
<div class="controls plugin-mark-Login-TopControlGroup"
data-bind="css: {'error': emailError}">
<div class="input-append">
<input type="email" class="input-block-level inputEmail"
name="RainLoopEmail" id="RainLoopEmail"
autofocus=""
autocomplete="email" autocorrect="off" autocapitalize="off" spellcheck="false"
<input required="" type="text" class="input-block-level inputEmail"
pattern="[^@\s]+(@[^\s]+)?" inputmode="email"
autofocus="" autocomplete="email" autocorrect="off" autocapitalize="off" spellcheck="false"
data-bind="textInput: email, disable: submitRequest"
data-i18n="[placeholder]GLOBAL/EMAIL" />
<span class="add-on">
@@ -31,8 +30,7 @@
</div>
<div class="controls" data-bind="css: {'error': passwordError}">
<div class="input-append">
<input type="password" class="input-block-level inputPassword"
name="RainLoopPassword" id="RainLoopPassword"
<input required="" type="password" class="input-block-level inputPassword"
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
data-bind="textInput: password, disable: submitRequest"
data-i18n="[placeholder]GLOBAL/PASSWORD" />
@@ -46,11 +44,12 @@
<div class="controls"
data-bind="visible: additionalCodeVisibility(), css: {'error': additionalCodeError}">
<div class="input-append">
<input type="text" class="input-block-level inputAdditionalCode" autocomplete="off"
autocorrect="off" autocapitalize="off" spellcheck="false" style="padding-right: 35px;"
<input type="text" class="input-block-level inputAdditionalCode"
inputmode="numeric"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" style="padding-right: 35px;"
data-bind="textInput: additionalCode, disable: submitRequest"
data-i18n="[placeholder]LOGIN/LABEL_VERIFICATION_CODE" />
<span class="add-on fontastic">🔑</span>
<span class="add-on"><i class="fontastic">🔑</i></span>
</div>
</div>
<div class="controls plugin-mark-Login-BottomControlGroup"
@@ -63,7 +62,7 @@
}
}"></div>
</div>
<div class="controls controls-submit-wrp" data-bind="hidden: hideSubmitButton">
<div class="controls" data-bind="hidden: hideSubmitButton">
<button type="submit" class="btn btn-large btn-block buttonLogin" data-bind="command: submitCommand">
<span class="i18n-animation" data-i18n="LOGIN/BUTTON_SIGN_IN"></span>
</button>