Validation in HTML5. :invalid classe after submit

2020-08-09 06:06发布

问题:

I'm building a form and I want to use the :invalid selector to give the "required" input fields a red border if the user presses submit without filling them, but using this makes them appear highlighted right when the page loads. It seems unfriendly to give this kind of warning to the user before even giving him the chance to fill them at least once.

Is there a way that these fields appear highlighted only after trying to submit the form, said in another way, is there a way to run the validation only after clicking submit (or at least losing focus on the required input fields?)

回答1:

No there is nothing out of the box.

Mozilla has its own pseudoclass for something very similiar called ':-moz-ui-invalid'. If you want to achieve something like this, you have to use the constraint validation DOM-API:

if(document.addEventListener){
    document.addEventListener('invalid', function(e){
        e.target.className += ' invalid';
    }, true);
}

You can also use webshims lib polyfill, which will not only polyfill incapable browsers, but also adds something similiar like -moz-ui-invalid to all browser (.form-ui-invalid).



回答2:

I used this approach for a project of mine, so the invalid fields would be highlighted only after submit:

HTML:

<form>
  <input type="email" required placeholder="Email Address">
  <input type="password" required placeholder="Password">
  <input type="submit" value="Sign in">
</form>

CSS:

input.required:invalid {
    color: red;
}

JS (jQuery):

$('[type="submit"]').on('click', function () {
    // this adds 'required' class to all the required inputs under the same <form> as the submit button
    $(this)
        .closest('form')
        .find('[required]')
        .addClass('required');
});


回答3:

Very simple just use #ID:invalid:focus

This only does the validation when focused on and not on page load



回答4:

Another way is to add a hide-hints class to the inputs with JavaScript on load. When a user modifies a field you remove the class.

In your CSS you then apply styling to input:not(.hide-hints):invalid. This means the error styling will be shown for users without JavaScript as well.



回答5:

Old question, but for people that might might find it useful: I made a little script that adds a class to a form when it's attempted to be submitted, so that you can style forms that have and haven't been attempted to be submitted differently:

window.addEventListener('load', function() {

    /**
     * Adds a class `_submit-attempted` to a form when it's attempted to be
     * submitted.
     *
     * This allows us to style invalid form fields differently for forms that
     * have and haven't been attemted to submit.
     */
    function addFormSubmitAttemptedTriggers() {

        var formEls = document.querySelectorAll('form');

        for (var i = 0; i < formEls.length; i++) {

            function addSubmitAttemptedTrigger(formEl) {

                var submitButtonEl = formEl.querySelector('input[type=submit]');

                if (submitButtonEl) {
                    submitButtonEl.addEventListener('click', function() {
                        formEl.classList.add('_submit-attempted');
                    });
                }

            }

            addSubmitAttemptedTrigger(formEls[i]);

        }

    }

    addFormSubmitAttemptedTriggers();

});

Now forms that are attempted to be submitted will get a class _submit-attempted, so you can only give these fields a red box shadow:

input {
    box-shadow: none;
}

form._submit-attempted input {
    box-shadow: 0 0 5px #F00;
}


回答6:

In addition to @Alexander Farkas' post, Dave Rupert has a very workable solution here: Happier HTML5 Form Validation.

Essentially, what it does is add a CSS class to form input elements that only displays after a user attempts to submit the form. This is much better UX, in that these elements won't show the invalid styling by default, or when a user tabs through them, which enhances accessibility.

Prior to finding this, I tried styling elements with :invalid:focus and other pseudo-elements, but didn't get the desired effect. Although I try to do my styling with pure CSS as much as possible, this looks like a use case where efficient JS is the practical solution.



回答7:

for 'required' validation

way 1 - set 'required' attribute for each element on form submit

// submit button event
$('#form-submit-btn').click(function(event) {
    // set required attribute for each element
    $('#elm1, #elm2').attr('required','true');

    // since required attribute were not set (before this event), prevent form submission
    if(!$('#form')[0].checkValidity())
        return;

    // submit form if form is valid
    $('#form').submit();

});

way 2 - use 'data' attribute

<input type="text" data-required="1">

<script type="text/javascript">
// submit button event
$('#form-submit-btn').click(function(event) {
    // set required attribute based on data attribute
    $(':input[data-required]').attr('required','true');

    // since required attribute were not set (before this event), prevent form submission
    if(!$('#form')[0].checkValidity())
        return;

    // submit form if form is valid
    $('#form').submit();

});
</script>


回答8:

You can achieve this by chaining pseudo-classes:

<style>
  input:required:focus:invalid {
    ...
   }
</style>

that way the input field will just show invalid styles only when that input field required and focused.

Here is a helpful article: https://alistapart.com/article/forward-thinking-form-validation/

Another stack overflow thread on this: https://stackoverflow.com/a/7921385/11102617



标签: forms html css