Bootstrap and Select2 form validation
Asked Answered
C

4

7

Explanation

I'm trying to use Bootstrap's form validation with Select2's select boxes, but for some reason, it doesn't work properly. It does show this feedback text, but not the green/red border color, as you can see in the code below.

Codes

You can also see it in this JSFiddle.

$(".select").select2({
  minimumResultsForSearch: Infinity
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://rawgit.com/select2/select2/master/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://rawgit.com/select2/select2/master/dist/js/select2.js"></script>
<form class="was-validated">

  <div class="form-group">
    <select class="custom-select" required>
      <option value="">Open this select menu</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
    <div class="invalid-feedback">Example invalid custom select feedback</div>
  </div>

  <div class="form-group">
    <select class="select custom-select" required>
      <option value="">Open this select menu</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
    <div class="invalid-feedback">Example invalid custom select feedback</div>
  </div>

</form>

Thanks in advance,
Luiz.

Criminate answered 4/2, 2019 at 4:10 Comment(0)
S
12

You need to apply css for override and select2 generate dynamic select so

.was-validated .custom-select:invalid + .select2 .select2-selection{
    border-color: #dc3545!important;
}
.was-validated .custom-select:valid + .select2 .select2-selection{
    border-color: #28a745!important;
}
*:focus{
  outline:0px;
}

$(".select").select2({
  minimumResultsForSearch: Infinity
});
.was-validated .custom-select:invalid + .select2 .select2-selection{
    border-color: #dc3545!important;
}
.was-validated .custom-select:valid + .select2 .select2-selection{
    border-color: #28a745!important;
}
*:focus{
  outline:0px;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://rawgit.com/select2/select2/master/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://rawgit.com/select2/select2/master/dist/js/select2.js"></script>
<form class="was-validated">

  <div class="form-group">
    <select class="custom-select" required>
      <option value="">Open this select menu</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
    <div class="invalid-feedback">Example invalid custom select feedback</div>
  </div>

  <div class="form-group">
    <select class="select custom-select" required>
      <option value="">Open this select menu</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
    <div class="invalid-feedback">Example invalid custom select feedback</div>
  </div>

</form>
Strobotron answered 4/2, 2019 at 4:28 Comment(4)
Wow had no idea what/how/why to use the + sign in CSS...now I know and what a great way to use it.Dud
Legend, saved me :)Wendelin
thank you, many years later, still the solutionSikata
Using select2 after ages, saved my a$$$$ thanks dude!Phenix
C
3

I had the same issue today, and I added validation styles to Select2 using CSS only - much like Hiren's answer.

The benefit of my answer is that it also applies the styling when you use the 'is-valid' and 'is-invalid' classes (which you might use when you have server side validation). My CSS also adds the tick and cross icons to remain consistent with the rest of the Bootstrap validation styling.

Just add the following to your CSS file:

.was-validated select.select2:invalid + .select2.select2-container.select2-container--default span.select2-selection, select.select2.is-invalid + .select2.select2-container.select2-container--default span.select2-selection {
    border-color: #fa5c7c;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fa5c7c' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23fa5c7c' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%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);
}
.was-validated select.select2:invalid + .select2.select2-container.select2-container--default .select2-selection__arrow, select.select2.is-invalid + .select2.select2-container.select2-container--default .select2-selection__arrow {
    right: 25px!important;
}
.was-validated select.select2:valid + .select2.select2-container.select2-container--default span.select2-selection, select.select2.is-valid + .select2.select2-container.select2-container--default span.select2-selection {
    border-color: #0acf97;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%230acf97' 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);
}
.was-validated select.select2:valid + .select2.select2-container.select2-container--default .select2-selection__arrow, select.select2.is-valid + .select2.select2-container.select2-container--default .select2-selection__arrow {
    right: 25px!important;
}

Here's a demo:

$('.select2').select2();

$(".needs-validation").on('submit', function (event) {
  $(this).addClass('was-validated');

  if ($(this)[0].checkValidity() === false) {
    event.preventDefault();
    event.stopPropagation();
    return false;
  } else {
  	alert('form submitted');
    event.preventDefault();
    event.stopPropagation();
    return true;
  };
});
.was-validated select.select2:invalid + .select2.select2-container.select2-container--default span.select2-selection, select.select2.is-invalid + .select2.select2-container.select2-container--default span.select2-selection {
    border-color: #fa5c7c;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fa5c7c' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23fa5c7c' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%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);
}
.was-validated select.select2:invalid + .select2.select2-container.select2-container--default .select2-selection__arrow, select.select2.is-invalid + .select2.select2-container.select2-container--default .select2-selection__arrow {
    right: 25px!important;
}
.was-validated select.select2:valid + .select2.select2-container.select2-container--default span.select2-selection, select.select2.is-valid + .select2.select2-container.select2-container--default span.select2-selection {
    border-color: #0acf97;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%230acf97' 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);
}
.was-validated select.select2:valid + .select2.select2-container.select2-container--default .select2-selection__arrow, select.select2.is-valid + .select2.select2-container.select2-container--default .select2-selection__arrow {
    right: 25px!important;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://rawgit.com/select2/select2/master/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://rawgit.com/select2/select2/master/dist/js/select2.js"></script>

<form class="needs-validation" novalidate>
  <div class="form-group">
    <label>Validated Client Side</label>
    <select class="form-control select2" data-placeholder="Select an option" required>
      <option value=""></option>
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
      <option value="3">Option 3</option>
    </select>
    <div class="invalid-feedback">
      Please select an option.
    </div>
  </div>
  
  <div class="form-group">
    <label>Validated Server Side</label>
    <select class="form-control select2 is-valid" data-placeholder="Select an option" required>
      <option value=""></option>
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
      <option value="3">Option 3</option>
    </select>
    <div class="invalid-feedback">
      Please select an option.
    </div>
  </div>
  
  <button class="btn btn-sm btn-primary" type="submit">Submit</button>
</form>
Coterie answered 20/1, 2020 at 23:43 Comment(1)
Great! Works perfect. I had a little trouble with your example cause I'm not using .select2 class to initialize it. Just add a tip that is mandatory to use .select2 for this code works without changes.Panache
H
2

try this

$(".select").select2({
  minimumResultsForSearch: Infinity
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://rawgit.com/select2/select2/master/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://rawgit.com/select2/select2/master/dist/js/select2.js"></script>
<form class="was-validated">

  <div class="form-group">
    <select class="form-control select2" required>
      <option value="">Open this select menu</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
    <div class="invalid-feedback">Example invalid custom select feedback</div>
  </div>

  <div class="form-group">
    <select class="form-control select2" required>
      <option value="">Open this select menu</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
    <div class="invalid-feedback">Example invalid custom select feedback</div>
  </div>

</form>
Historiographer answered 4/2, 2019 at 4:15 Comment(2)
This doesn't work because you are not using Select2 :(Criminate
To make it work with Select2. I explained it in the question above.Criminate
B
0

I borrowed and modified this css code from Bootstrap 4 custom-file-input. That way validation on select2 should behave as on any common form control.

.was-validated .ls-select2:valid ~ .select2 .select2-selection, .ls-select2.is-valid ~ .select2 .select2-selection {
    border-color: #4fc47f;
}
.was-validated .ls-select2:valid ~ .select2 .select2-selection::before, .ls-select2.is-valid ~ .select2 .select2-selection::before {
    border-color: inherit;
}
.was-validated .ls-select2:valid ~ .valid-feedback,
.was-validated .ls-select2:valid ~ .valid-tooltip, .ls-select2.is-valid ~ .valid-feedback,
.ls-select2.is-valid ~ .valid-tooltip {
    display: block;
}
.was-validated .ls-select2:valid:focus ~ .select2 .select2-selection, .ls-select2.is-valid:focus ~ .select2 .select2-selection {
    box-shadow: 0 0 0 0.2rem rgba(79, 196, 127, 0.25);
}

.was-validated .ls-select2:invalid ~ .select2 .select2-selection, .ls-select2.is-invalid ~ .select2 .select2-selection {
    border-color: #f35a3d;
}
.was-validated .ls-select2:invalid ~ .select2 .select2-selection::before, .ls-select2.is-invalid ~ .select2 .select2-selection::before {
    border-color: inherit;
}
.was-validated .ls-select2:invalid ~ .invalid-feedback,
.was-validated .ls-select2:invalid ~ .invalid-tooltip, .ls-select2.is-invalid ~ .invalid-feedback,
.ls-select2.is-invalid ~ .invalid-tooltip {
    display: block;
}
.was-validated .ls-select2:invalid:focus ~ .select2 .select2-selection, .ls-select2.is-invalid:focus ~ .select2 .select2-selection {
    box-shadow: 0 0 0 0.2rem rgba(243, 90, 61, 0.25);
}
Bufordbug answered 29/1, 2020 at 13:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.