@patricktahumegmail-com
@patricktahumegmail-com
Forum Replies Created
-
AuthorPosts
-
Patrick HumeParticipant
ah I see, thank you that helps explain it, I understand why it wasn’t working now, 🙂
November 22, 2022 at 11:00 pm in reply to: password input field complexity validation and strength example #104014Patrick HumeParticipantI thought I would update this with a complete solution with a few weeks for a better UXI experience.
This ensures the password field is not red on page load, then if the user types in it and then deletes its contents it will then appear red to indicate that it is required the same behaviour as other required fields, also fix the styling so that the password *’s are indented and appears the same as the default blazor form-control class, also adds the field highlight when password field is selected. The submit button is only enabled when the complexity is ‘Strong’, and when the submit is clicked it displays a spinning bootstrap icon on the submit button and disables it to prevent re-clicking. Assumes the submit action will call a service that returns a result object or response, this can then be used to display the smart blazor badge to give feedback on the Ui to the user.
I hope this helps someone one day
complexityCheck.js
const symbols = /['<>@!#$%^&*()_+\]\[\{}?:;|'"\\,.\/~`\-=']+/; const numerical = /.*[0-9].*/; const upperCase = /.*[A-Z].*/; const lowerCase = /.*[a-z].*/; (function (global) { global.customStrength = function (dotNetObject) { const allowedSymbols = '<>@!#$%^&*()_+[]{}?:;|\'"\\,./~`-='; const passwordField = document.querySelectorAll("smart-password-text-box")[0]; const passwordConfirm = document.querySelectorAll("smart-password-text-box")[1]; // Remove the red border on the page load passwordConfirm.style.border = ''; // Set the border to red if the field is cleared and outline green if the field has a value // Assumes that any value will be the same is the same as the first password field & relies on // MVC data attestations [Compare( to enforce this at time of form submit passwordConfirm.addEventListener('change', function (event) { if (event.detail.value) { this.style.border = "#26b050 solid 1.5px"; } else { this.style.border = "red solid 3px"; } }); passwordField.messages = { 'en': { 'passwordStrength': 'Password strength', 'short': 'Short', 'init': 'init', 'weak': 'complexity Week - missing at least 1 symbol, ' + allowedSymbols, 'far': 'complexity Fair - missing at least 1 numerical value, 0 - 9', 'better': 'complexity Better - missing at least 1 upper case characture, A- Z', 'good': 'complexity Good - missing at least 1 lower case characture, a - z', 'strong': 'Strong =)', 'showPassword': 'Show password' } }; // indent password text to match the styling of other from controls passwordField.style.textIndent = '0.7rem' setTimeout(function () { passwordField.passwordStrength = function (password, allowableSymbols) { const passwordLength = password.length; let message = null; //debugger; passwordField.children[0].classList.remove("smart-password-better"); if (passwordLength < 7) { message = 'short'; } else if (!new RegExp(symbols).exec(password)) { message = 'weak'; } else if (!new RegExp(numerical).exec(password)) { message = 'far'; } else if (!new RegExp(upperCase).exec(password)) { message = 'better'; } else if (!new RegExp(lowerCase).exec(password)) { message = 'good'; } //console.log(message); if (message) { dotNetObject.invokeMethodAsync('CallbackComplexityCheck', false) return message; } dotNetObject.invokeMethodAsync('CallbackComplexityCheck', true) return 'strong'; } }, 0); // remove red border on page load, the timer allows js to wire up before removing the class that's added by the js setTimeout(function () { passwordField.children[0].classList.remove("smart-password-short"); }, 10); return true; } })(window);
index.html
<script src="js/complexityCheck.js"></script> <script src="_content/Smart.Blazor/js/smart.blazor.js"></script> <script src="_content/Smart.Blazor/js/smart.elements.js"></script>
razor page example
<EditForm Model="SomeModel" OnValidSubmit="ProcessMyForm"> <DataAnnotationsValidator /> <div class="mb-3"> <label for="password">New Password</label> <template id="tooltip-password"> <span>{{value}}</span> </template> <PasswordTextBox Required id="password" TooltipArrow TooltipTemplate="tooltip-password" Placeholder="Enter password" @bind-Value="SomeModel.Password" ShowPasswordIcon ShowPasswordStrength Name="password"></PasswordTextBox> <ValidationMessage For="@(() => SomeModel.Password)" /> </div> <div class="mb-3"> <label for="confirmPassword">Confirm New Password</label> <PasswordTextBox Class="form-control" Required Placeholder="Confirm password" @bind-Value="SomeModel.ConfirmPassword" ShowPasswordIcon Name="confirmPassword"></PasswordTextBox> <ValidationMessage For="@(() => SomeModel.ConfirmPassword)" /> </div> <button type="submit" id="submit" disabled="@(!isComplexityValid || loading)" class="btn btn-primary"> @if (loading) { <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> <span class="sr-only">Processing...</span> } else { <span class="sr-only">Submit</span> } </button> </EditForm> <div> <span class="@($"smart-badge {messageCssClass}")">@message</span> </div> <br /> @code { private string message = string.Empty; private bool isComplexityValid = false; private bool loading = false; private string messageCssClass = string.Empty; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeAsync<bool>("customStrength", DotNetObjectReference.Create(this)); } await base.OnAfterRenderAsync(firstRender); } private async Task ProcessMyForm() { loading = true; var result = await // call some service here ! if (result.Success) { messageCssClass = "smart-badge-success"; } else { messageCssClass = "smart-badge-danger"; } loading = false; message = result.Message; StateHasChanged(); } [JSInvokable, EditorBrowsable(EditorBrowsableState.Never)] public void CallbackComplexityCheck(bool valid) { if (isComplexityValid != valid) { isComplexityValid = valid; StateHasChanged(); } }
- This reply was modified 2 years ago by Patrick Hume.
- This reply was modified 2 years ago by Patrick Hume.
November 16, 2022 at 5:14 pm in reply to: password input field complexity validation and strength example #104002Patrick HumeParticipantseams i got the cass wrong to make that work poperly –
smart-password-text-box { background-clip: content-box; box-sizing: border-box; } smart-password-text-box[show-password-strength] { border: red solid 3px; } smart-password-text-box[show-password-strength] .smart-password-short { border: red solid 3px; } smart-password-text-box[show-password-strength] .smart-password-weak { border: #C27BA0 solid 3px; } smart-password-text-box[show-password-strength] .smart-password-far { border: orange solid 3px; } smart-password-text-box[show-password-strength] .smart-password-better { border: yellow solid 3px; } smart-password-text-box[show-password-strength] .smart-password-good { border: deepskyblue solid 3px; } smart-password-text-box[show-password-strength] .smart-password-strong { border: green solid 3px; } smart-password-text-box smart-tooltip .smart-tooltip-content { border-radius: 3px; }
then the js file needs to be
(function (global) { global.customStrength = function (dotNetObject) { let allowedSymbols = '<>@!#$%^&*()_+[]{}?:;|\'"\\,./~`-='; const passwordTextBox = document.querySelector("smart-password-text-box").messages = { 'en': { 'passwordStrength': 'Password strength', 'short': 'Short', 'weak': 'complexity Week - missing art least 1 symbol, ' + allowedSymbols, 'far': 'complexity Fair - missing at least 1 numerical value, 0 - 9', 'better': 'complexity Better - missing at least 1 upper case characture, A- Z', 'good': 'complexity Good - missing at least 1 lower case characture, a - z', 'strong': 'Strong =)', 'showPassword': 'Show password' } }; setTimeout(function () { passwordTextBox.passwordStrength = function (password, allowedSymbols) { const passwordLength = password.length; let message = null; // debugger; if (passwordLength < 7) { message = 'short'; } else if (!new RegExp(symbols).exec(password)) { message = 'weak'; } else if (!new RegExp(numerical).exec(password)) { message = 'far'; } else if (!new RegExp(upperCase).exec(password)) { message = 'better'; } else if (!new RegExp(lowerCase).exec(password)) { message = 'good'; } if (message) { dotNetObject.invokeMethodAsync('CallbackComplexityCheck', false) return message; } dotNetObject.invokeMethodAsync('CallbackComplexityCheck', true) return 'strong'; } }, 0); return true; } })(window);
This will allow one to customise the message in the tooltip template whilst still applying styling the the input
Patrick HumeParticipantnever mind I worked it out, I was just been a total idiot and just had to take a step back, id delete this redundant post but seems I can’t …how annoying, any way please disregard the above
-
AuthorPosts