Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bootstrap 4 and Bootstrap 5 validation #42

Open
thewebartisan7 opened this issue Oct 12, 2020 · 15 comments
Open

Bootstrap 4 and Bootstrap 5 validation #42

thewebartisan7 opened this issue Oct 12, 2020 · 15 comments

Comments

@thewebartisan7
Copy link

thewebartisan7 commented Oct 12, 2020

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
Copy link
Author

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 added a commit to thewebartisan7/Pristine that referenced this issue Oct 12, 2020
Proposed solution for fix issue sha256#42
@thewebartisan7
Copy link
Author

I make here a PR: #43

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

@sha256
Copy link
Owner

sha256 commented Oct 12, 2020

@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.

@thewebartisan7
Copy link
Author

thewebartisan7 commented Oct 12, 2020

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
Copy link
Author

thewebartisan7 commented Oct 12, 2020

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

@sha256
Copy link
Owner

sha256 commented Oct 12, 2020

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
Copy link
Owner

sha256 commented Oct 12, 2020

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.

@thewebartisan7
Copy link
Author

thewebartisan7 commented Oct 12, 2020

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
Copy link
Author

thewebartisan7 commented Oct 12, 2020

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

@mikkeltschentscher
Copy link

mikkeltschentscher commented Oct 14, 2020

+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 :-)

@SasSam
Copy link

SasSam commented Feb 10, 2021

+1

Any ETA for this fix, @sha256 ?

@TheROPFather
Copy link

Also wondering if an update is coming for this

@MirazMac
Copy link

any updates regarding this?

@sandipbhambre
Copy link

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);
}

@shuaibjaff
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants