PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, September 30, 2022

[FIXED] How can I apply Bootstrap 5 validation to a Razor form?

 September 30, 2022     bootstrap-5, razor-pages, validation     No comments   

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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing