Issue
I have Razor Pages form like this:
<form id="account" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating mb-3">
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" />
<label asp-for="Input.Email" class="form-label"></label>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
...
in the output i get the following render:
<form id="account" method="post">
<div class="form-floating mb-3">
<input class="form-control" autocomplete="username" aria-required="true" type="email" data-val="true"
data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required."
id="Input_Email" name="Input.Email" value="">
<label class="form-label" for="Input_Email">Email</label>
<span class="text-danger field-validation-valid" data-valmsg-for="Input.Email" data-valmsg-replace="true"></span>
</div>
...
But Bootstrap v5 uses the :invalid
and :valid
styles applied to form controls.
At the same time, data-val-
attributes are not taken into account in any way.
Is it possible to seamlessly connect the Bootstrap 5 validation functionality on the client while retaining all the power of customizing the Razor Pages validation model?
Solution
After reading the documentation for the ValidityState object and the JS Forms API. And by combining this with Bootstrap Validation, we got the following solution for the following validation properties: valueMissing
, typeMismatch
(email), tooLong
, tooShort
. The list is not complete, the solution can be developed to suit your needs.
<script type="text/javascript">
(() => {
'use strict'
function validateControl(c) {
c.addEventListener('input', (event) => setErrMessage(c));
}
function setErrMessage(c) {
const name = c.getAttribute('name');
const errMsg = Array.from(c.parentElement
.querySelectorAll(`[data-valmsg-for="${name}"]`))
.filter(msg => !!msg.getAttribute('data-valmsg-replace'));
errMsg.forEach(msg => msg.innerText = '');
c.required = !!c.getAttribute('aria-required');
const requiredErrorMessage = c.getAttribute('data-val-required');
if (requiredErrorMessage && c.validity.valueMissing)
errMsg.forEach(msg => msg.innerText = requiredErrorMessage);
const typeMismatchErrorMessage = c.getAttribute('data-val-email');
if (typeMismatchErrorMessage && c.validity.typeMismatch)
errMsg.forEach(msg => msg.innerText = typeMismatchErrorMessage);
const lengthMax = c.getAttribute('data-val-length-max');
const lengthMin = c.getAttribute('data-val-length-min');
if (lengthMin)
c.setAttribute('minlength', +lengthMin)
const lengthErrorMessage = c.getAttribute('data-val-length');
if (lengthErrorMessage && (c.validity.tooLong || c.validity.tooShort))
errMsg.forEach(msg => msg.innerText = lengthErrorMessage);
}
// Fetch all the forms we want to apply custom Bootstrap validation styles to
const forms = document.querySelectorAll('form')
// Loop over them and prevent submission
Array.from(forms).forEach(form => {
form.noValidate = true;
const controls = form.querySelectorAll('[data-val="true"]');
Array.from(controls).forEach(validateControl);
form.addEventListener('submit', event => {
Array.from(controls).forEach(setErrMessage);
const isValid = form.checkValidity();
if (!isValid) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
Answered By - Igor N. Answer Checked By - Senaida (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.