Pristine icon indicating copy to clipboard operation
Pristine copied to clipboard

Bootstrap 4 and Bootstrap 5 validation

Open thewebartisan7 opened this issue 5 years ago • 15 comments

I would like to use bootstrap 4 and bootstrap 5 default validation classes, but seem not possible.

For display .invalid-feedback the input must have .is-invalid or .valid-feedback with .is-valid, example:


<div class="form-group">
      <input type="text" class="form-control is-invalid" required="">
      <div class="invalid-feedback">This field is required</div>
</div>

<div class="form-group">
      <input type="text" class="form-control is-valid" required="">
      <div class="valid-feedback">Looks good</div>
</div>

If I change the default class name like so:

    let validator = new Pristine(form, {
        classTo: 'form-group',
        errorClass: 'is-invalid',
        successClass: 'is-valid',
        errorTextParent: 'form-group',
        errorTextTag: 'div',
        errorTextClass: 'invalid-feedback'
    })

The errors is not visible because class .is-invalid is not added to input but to form-group, example:

<div class="form-group is-invalid">
            <label for="email">E-Mail Address</label>
            <input type="email" id="email" name="email" class="form-control" required="">
            <div class="pristine-error invalid-feedback">This field is required</div>
</div>

I could solve this by adding extra CSS like .is-invalid .invalid-feedback {display: block} (not completely because need also to consider input group border, dark theme of bootstrap 5, etc). Would be good to have a way to do this without extra CSS, if possible without breaking change.

Bootstrap has also a class .was-validated, that show invalid feedback depending on HTML5 validation, like .was-validated :invalid ~ .invalid-feedback {display: block}

But this doesn't work for example with input type email where HTML5 consider valid email@example while pristine correctly mark this as invalid.

thewebartisan7 avatar Oct 12 '20 08:10 thewebartisan7

Here is mixin of form state that should be used to change style: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_forms.scss

There are different other things to consider if changing style to cover this.

thewebartisan7 avatar Oct 12 '20 08:10 thewebartisan7

I make here a PR: https://github.com/sha256/Pristine/pull/43

I just add success/error class to input, by keeping the same on parent.

thewebartisan7 avatar Oct 12 '20 09:10 thewebartisan7

@thewebartisan7, I think there's an easier way to solve this problem. error & success classes are added to the element you specify in classTo property. So if you change from classTo: 'form-group' to classTo: 'form-control' it should work but there's one problem: It looks for an ancestor of the input field with class classTo. This can be easily solved by fixing the findAncestor method.

sha256 avatar Oct 12 '20 09:10 sha256

Ah, let me try.

I think that we can fix findAncestor like this:

export function findAncestor (el, cls) {

    // Check before in current el before check in parent
    if(!el.classList.contains(cls))
        while ((el = el.parentElement) && !el.classList.contains(cls));

    return el;
}

This was first thing that I looks into, but didn't test.

I will check now.

Anyway, I notice that when I install via NPM is not the actual version that I see here in github, for example is missing equals and some other change.

thewebartisan7 avatar Oct 12 '20 09:10 thewebartisan7

Nope, this doesn't work. Almost not how I change findAncestor.

First the errors is not added, only input receive class is-invalid.

But another error is that checkbox or radio input has not form-control but form-check-input

Then is not found by findAncestor and appear error:

TypeError: errorClassElement is null

thewebartisan7 avatar Oct 12 '20 09:10 thewebartisan7

checkbox or radio input not having form-control can be solved by giving all inputs a custom class and specify it in classTo.

Errors are added based on errorTextParent.

I'll create a codepen and check in detail. If you already have something, please share it with me.

sha256 avatar Oct 12 '20 14:10 sha256

I think I got the issue: Apart from the findAncestor change, the following code:

        if (self.config.classTo === self.config.errorTextParent){
            errorTextParent = errorClassElement;
        } else {
            errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent);
        }

needs to be changed to:

var errorTextParent = findAncestor(field.input, self.config.errorTextParent),
      errorTextElement = null;

I'll check if there's any side effects and make the change. The solution you proposed may have side effects because of adding the same class to parent and child. That's why I'm looking for a different approach.

sha256 avatar Oct 12 '20 15:10 sha256

checkbox or radio input not having form-control can be solved by giving all inputs a custom class and specify it in classTo.

Yes this can be a solution also to fix issue that happen right now where also fields that doesn't require validation, example a not required input, receive a is-valid class, then become green. But I don't like really the idea to add new class to input...

The solution you proposed may have side effects because of adding the same class to parent and child.

I understand what you mean, but if you think about, usually a parent invalid class check child, like .has-error .form-control and if .form-control has .has-error it will not impact on style.

I don't see how can impact on style since is never used alone.

Better this than adding custom classes to input.

Looking for your update. Thanks

thewebartisan7 avatar Oct 12 '20 16:10 thewebartisan7

Maybe add new options, like classToSelf = true|false when is true, just use field.input, otherwise use classTo

thewebartisan7 avatar Oct 12 '20 16:10 thewebartisan7

+1

A classToSelf = true|false or an added extra classToInput = 'js-form-input' would be appreciated. I work with TailwindCSS as my framework of choice and the same applies here :-)

mikkeltschentscher avatar Oct 14 '20 14:10 mikkeltschentscher

+1

Any ETA for this fix, @sha256 ?

SasSam avatar Feb 10 '21 14:02 SasSam

Also wondering if an update is coming for this

TheROPFather avatar Apr 08 '21 15:04 TheROPFather

any updates regarding this?

MirazMac avatar May 23 '21 12:05 MirazMac

I have found a workaround! Tested on Bootstrap 4.

/* PristineJS Bootstrap Fix */
.input-group.is-invalid > input.form-control,
.form-group.is-invalid > input.form-control {
    border-color: #dc3545;
    padding-right: 2.25rem !important;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right calc(0.375em + 0.1875rem) center;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}
.input-group.is-valid > input.form-control,
.form-group.is-valid > input.form-control {
    border-color: #28a745;
    padding-right: 2.25rem !important;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right calc(0.375em + 0.1875rem) center;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

sandy2196 avatar Oct 02 '22 18:10 sandy2196

still waiting for classToSelf everything else conflicts with other parts of my app.

shuaibjaff avatar Nov 27 '22 23:11 shuaibjaff