Toggle visibility of password input fields in login-ftl-based pages
Closes #22067
This commit is contained in:
parent
722422a0cf
commit
86c0e338d9
11 changed files with 209 additions and 92 deletions
|
@ -40,3 +40,35 @@ from the same list of values.
|
||||||
|
|
||||||
In this release, the role and client mappers now map to a single value from the effective roles of a user when
|
In this release, the role and client mappers now map to a single value from the effective roles of a user when
|
||||||
they are marked as single-valued (`Multivalued` disabled).
|
they are marked as single-valued (`Multivalued` disabled).
|
||||||
|
|
||||||
|
= Changes to password fields in Login UI
|
||||||
|
|
||||||
|
In this version we want to introduce a toggle to hide/show password inputs.
|
||||||
|
|
||||||
|
.Affected pages:
|
||||||
|
- login.ftl
|
||||||
|
- login-password.ftl
|
||||||
|
- login-update-password.ftl
|
||||||
|
- register.ftl
|
||||||
|
- register-user-profile.ftl
|
||||||
|
|
||||||
|
In general all `<input type="password" name="password" />` are encapsulated within a div now. The input element is followed by a button which toggles the visibility of the password input.
|
||||||
|
|
||||||
|
Old code example:
|
||||||
|
[source,html]
|
||||||
|
----
|
||||||
|
<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
|
||||||
|
----
|
||||||
|
|
||||||
|
New code example:
|
||||||
|
[source,html]
|
||||||
|
----
|
||||||
|
<div class="${properties.kcInputGroup!}">
|
||||||
|
<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
----
|
||||||
|
|
|
@ -284,12 +284,12 @@ public class RegisterWithUserProfileTest extends RegisterTest {
|
||||||
);
|
);
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
driver.findElement(
|
driver.findElement(
|
||||||
By.cssSelector("form#kc-register-form > div:nth-child(4) > div:nth-child(2) > input#password")
|
By.cssSelector("#password")
|
||||||
).isDisplayed()
|
).isDisplayed()
|
||||||
);
|
);
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
driver.findElement(
|
driver.findElement(
|
||||||
By.cssSelector("form#kc-register-form > div:nth-child(5) > div:nth-child(2) > input#password-confirm")
|
By.cssSelector("#password-confirm")
|
||||||
).isDisplayed()
|
).isDisplayed()
|
||||||
);
|
);
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -434,12 +434,12 @@ public class RegisterWithUserProfileTest extends RegisterTest {
|
||||||
);
|
);
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
driver.findElement(
|
driver.findElement(
|
||||||
By.cssSelector("form#kc-register-form > div:nth-child(3) > div:nth-child(2) > input#password")
|
By.cssSelector("#password")
|
||||||
).isDisplayed()
|
).isDisplayed()
|
||||||
);
|
);
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
driver.findElement(
|
driver.findElement(
|
||||||
By.cssSelector("form#"+htmlFormId+" > div:nth-child(4) > div:nth-child(2) > input#password-confirm")
|
By.cssSelector("#password-confirm")
|
||||||
).isDisplayed()
|
).isDisplayed()
|
||||||
);
|
);
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
|
|
@ -10,10 +10,17 @@
|
||||||
<div class="${properties.kcFormGroupClass!} no-bottom-margin">
|
<div class="${properties.kcFormGroupClass!} no-bottom-margin">
|
||||||
<hr/>
|
<hr/>
|
||||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
||||||
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password"
|
<div class="${properties.kcInputGroup!}">
|
||||||
type="password" autocomplete="on" autofocus
|
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password')>true</#if>"
|
type="password" autocomplete="on" autofocus
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<#if messagesPerField.existsError('password')>
|
<#if messagesPerField.existsError('password')>
|
||||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
||||||
|
@ -33,11 +40,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
||||||
<input tabindex="4" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
<input tabindex="4" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
</@layout.registrationLayout>
|
</@layout.registrationLayout>
|
||||||
|
|
|
@ -7,17 +7,31 @@
|
||||||
<form id="kc-passwd-update-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
<form id="kc-passwd-update-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||||
<input type="text" id="username" name="username" value="${username}" autocomplete="username"
|
<input type="text" id="username" name="username" value="${username}" autocomplete="username"
|
||||||
readonly="readonly" style="display:none;"/>
|
readonly="readonly" style="display:none;"/>
|
||||||
<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
|
<div class="${properties.kcInputGroup!}">
|
||||||
|
<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
<label for="password-new" class="${properties.kcLabelClass!}">${msg("passwordNew")}</label>
|
<label for="password-new" class="${properties.kcLabelClass!}">${msg("passwordNew")}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<input type="password" id="password-new" name="password-new" class="${properties.kcInputClass!}"
|
<div class="${properties.kcInputGroup!}">
|
||||||
autofocus autocomplete="new-password"
|
<input type="password" id="password-new" name="password-new" class="${properties.kcInputClass!}"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
autofocus autocomplete="new-password"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password-new" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password')>
|
<#if messagesPerField.existsError('password')>
|
||||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
@ -32,11 +46,18 @@
|
||||||
<label for="password-confirm" class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
<label for="password-confirm" class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<input type="password" id="password-confirm" name="password-confirm"
|
<div class="${properties.kcInputGroup!}">
|
||||||
class="${properties.kcInputClass!}"
|
<input type="password" id="password-confirm" name="password-confirm"
|
||||||
autocomplete="new-password"
|
class="${properties.kcInputClass!}"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
autocomplete="new-password"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password-confirm" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password-confirm')>
|
<#if messagesPerField.existsError('password-confirm')>
|
||||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
@ -60,5 +81,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
|
||||||
</#if>
|
</#if>
|
||||||
</@layout.registrationLayout>
|
</@layout.registrationLayout>
|
||||||
|
|
|
@ -3,73 +3,80 @@
|
||||||
<#if section = "header">
|
<#if section = "header">
|
||||||
${msg("loginAccountTitle")}
|
${msg("loginAccountTitle")}
|
||||||
<#elseif section = "form">
|
<#elseif section = "form">
|
||||||
<div id="kc-form">
|
<div id="kc-form">
|
||||||
<div id="kc-form-wrapper">
|
<div id="kc-form-wrapper">
|
||||||
<#if realm.password>
|
<#if realm.password>
|
||||||
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
|
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
|
||||||
<#if !usernameHidden??>
|
<#if !usernameHidden??>
|
||||||
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
|
<label for="username" class="${properties.kcLabelClass!}"><#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if></label>
|
||||||
|
|
||||||
|
<input tabindex="1" id="username" class="${properties.kcInputClass!}" name="username" value="${(login.username!'')}" type="text" autofocus autocomplete="off"
|
||||||
|
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<#if messagesPerField.existsError('username','password')>
|
||||||
|
<span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
|
||||||
|
</span>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<label for="username" class="${properties.kcLabelClass!}"><#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if></label>
|
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
||||||
|
|
||||||
<input tabindex="1" id="username" class="${properties.kcInputClass!}" name="username" value="${(login.username!'')}" type="text" autofocus autocomplete="off"
|
<div class="${properties.kcInputGroup!}">
|
||||||
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password" type="password" autocomplete="off"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg("showPassword")}"
|
||||||
|
aria-controls="password" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('username','password')>
|
<#if usernameHidden?? && messagesPerField.existsError('username','password')>
|
||||||
<span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
|
${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
|
||||||
</span>
|
</span>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
|
||||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
<div id="kc-form-options">
|
||||||
|
<#if realm.rememberMe && !usernameHidden??>
|
||||||
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password" type="password" autocomplete="off"
|
<div class="checkbox">
|
||||||
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
<label>
|
||||||
/>
|
<#if login.rememberMe??>
|
||||||
|
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox" checked> ${msg("rememberMe")}
|
||||||
<#if usernameHidden?? && messagesPerField.existsError('username','password')>
|
<#else>
|
||||||
<span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"> ${msg("rememberMe")}
|
||||||
${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
|
</#if>
|
||||||
</span>
|
</label>
|
||||||
</#if>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
|
|
||||||
<div id="kc-form-options">
|
|
||||||
<#if realm.rememberMe && !usernameHidden??>
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<#if login.rememberMe??>
|
|
||||||
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox" checked> ${msg("rememberMe")}
|
|
||||||
<#else>
|
|
||||||
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"> ${msg("rememberMe")}
|
|
||||||
</#if>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
|
||||||
<#if realm.resetPasswordAllowed>
|
|
||||||
<span><a tabindex="5" href="${url.loginResetCredentialsUrl}">${msg("doForgotPassword")}</a></span>
|
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||||
|
<#if realm.resetPasswordAllowed>
|
||||||
|
<span><a tabindex="5" href="${url.loginResetCredentialsUrl}">${msg("doForgotPassword")}</a></span>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
||||||
<input type="hidden" id="id-hidden-input" name="credentialId" <#if auth.selectedCredential?has_content>value="${auth.selectedCredential}"</#if>/>
|
<input type="hidden" id="id-hidden-input" name="credentialId" <#if auth.selectedCredential?has_content>value="${auth.selectedCredential}"</#if>/>
|
||||||
<input tabindex="4" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
<input tabindex="4" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</#if>
|
</#if>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
|
||||||
</div>
|
|
||||||
<#elseif section = "info" >
|
<#elseif section = "info" >
|
||||||
<#if realm.password && realm.registrationAllowed && !registrationDisabled??>
|
<#if realm.password && realm.registrationAllowed && !registrationDisabled??>
|
||||||
<div id="kc-registration-container">
|
<div id="kc-registration-container">
|
||||||
|
|
|
@ -88,6 +88,8 @@ password=Password
|
||||||
passwordConfirm=Confirm password
|
passwordConfirm=Confirm password
|
||||||
passwordNew=New Password
|
passwordNew=New Password
|
||||||
passwordNewConfirm=New Password confirmation
|
passwordNewConfirm=New Password confirmation
|
||||||
|
hidePassword=Hide password
|
||||||
|
showPassword=Show password
|
||||||
rememberMe=Remember me
|
rememberMe=Remember me
|
||||||
authenticatorCode=One-time code
|
authenticatorCode=One-time code
|
||||||
address=Address
|
address=Address
|
||||||
|
|
|
@ -16,10 +16,17 @@
|
||||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label> *
|
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label> *
|
||||||
</div>
|
</div>
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
<div class="${properties.kcInputGroup!}">
|
||||||
autocomplete="new-password"
|
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
autocomplete="new-password"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password')>
|
<#if messagesPerField.existsError('password')>
|
||||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
@ -35,10 +42,17 @@
|
||||||
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label> *
|
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label> *
|
||||||
</div>
|
</div>
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
<div class="${properties.kcInputGroup!}">
|
||||||
name="password-confirm"
|
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
name="password-confirm"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password-confirm" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password-confirm')>
|
<#if messagesPerField.existsError('password-confirm')>
|
||||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
@ -73,5 +87,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
|
||||||
</#if>
|
</#if>
|
||||||
</@layout.registrationLayout>
|
</@layout.registrationLayout>
|
||||||
|
|
|
@ -85,10 +85,18 @@
|
||||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
<div class="${properties.kcInputGroup!}">
|
||||||
autocomplete="new-password"
|
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
autocomplete="new-password"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password')>
|
<#if messagesPerField.existsError('password')>
|
||||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
@ -104,10 +112,17 @@
|
||||||
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
<div class="${properties.kcInputGroup!}">
|
||||||
name="password-confirm"
|
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
||||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
name="password-confirm"
|
||||||
/>
|
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
<button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="password-confirm" data-password-toggle
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password-confirm')>
|
<#if messagesPerField.existsError('password-confirm')>
|
||||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
@ -140,5 +155,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
|
||||||
</#if>
|
</#if>
|
||||||
</@layout.registrationLayout>
|
</@layout.registrationLayout>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
const toggle = (button) => {
|
||||||
|
const passwordElement = document.getElementById(button.getAttribute('aria-controls'));
|
||||||
|
if (passwordElement.type === "password") {
|
||||||
|
passwordElement.type = "text";
|
||||||
|
button.children.item(0).classList.replace("fa-eye", "fa-eye-slash");
|
||||||
|
button.setAttribute("aria-label", button.dataset.labelHide);
|
||||||
|
} else if(passwordElement.type === "text") {
|
||||||
|
passwordElement.type = "password";
|
||||||
|
button.children.item(0).classList.replace("fa-eye-slash", "fa-eye");
|
||||||
|
button.setAttribute("aria-label", button.dataset.labelShow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-password-toggle]')
|
||||||
|
.forEach(button => button.onclick = () => toggle(button));
|
|
@ -24,7 +24,6 @@ p.instruction {
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-button.pf-m-control {
|
.pf-c-button.pf-m-control {
|
||||||
border: solid var(--pf-global--BorderWidth--sm);
|
|
||||||
border-color: rgba(230, 230, 230, 0.5);
|
border-color: rgba(230, 230, 230, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ kcInputClassCheckboxInput=pf-c-check__input
|
||||||
kcInputClassCheckboxLabel=pf-c-check__label
|
kcInputClassCheckboxLabel=pf-c-check__label
|
||||||
kcInputClassRadioCheckboxLabelDisabled=pf-m-disabled
|
kcInputClassRadioCheckboxLabelDisabled=pf-m-disabled
|
||||||
kcInputErrorMessageClass=pf-c-form__helper-text pf-m-error required kc-feedback-text
|
kcInputErrorMessageClass=pf-c-form__helper-text pf-m-error required kc-feedback-text
|
||||||
|
kcInputGroup=pf-c-input-group
|
||||||
kcInputWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
kcInputWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||||
kcFormOptionsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
kcFormOptionsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||||
kcFormButtonsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
kcFormButtonsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
|
||||||
|
|
Loading…
Reference in a new issue