How to make select2 work with jquery.validation plugin?
Asked Answered
H

15

49

I'm trying to validate select2 field using jquey.validation plugin but nothing happens.

I want to make select required field.

I'm using this custom validation function:

$.validator.addMethod("requiredcountry", function(value, element, arg){
              return arg != value;
         }, "Value must not equal arg.");

and this is the rule:

rules:
{
 country:
 {
         required: true,
         requiredcountry: ""
 }
}

What select2 field should I use for the rule to match?

I appreciate any idea how to make select2 working together with jquery.validation

10x

Herwig answered 23/5, 2014 at 9:7 Comment(0)
S
47

Just add ignore: [], in Your form validation function. It will enable hidden field validation.So You will get validation for Select 2

$("#ContactForm").validate({
  ignore: [],       
  rules: {
    //Rules
  },
  messages: {
    //messages
  }
});
Skidproof answered 28/4, 2015 at 12:49 Comment(5)
That is so simple - yet couldn't find any mention in the docs for Select2Errantry
Fantastic, fixed my problem after a long time trying myself! +1Derris
I just encountered the same issue and in case anyone is wondering why it is occurring and why ignore: [] is fixing it - here is my story: 1. I added "hidden" class to the select which applies display: none to the element 2. This makes Validation to interpret the <select> as type="hidden" 3. Which by default it is not being validated 4. Therefore the need for ignore: []Moiety
EDIT: I think the issue comes from the "hidden" keyword, not the css styles because when I change the class to something else the issue is no longer reproducible.Moiety
When i added ignore:[], it is validating but the form does not submit.Ophiology
S
34

As a tip, please consider that the validate js bind itself to changes of select not select 2. This cause problem in below case:

  1. There is a required select box which is converted to select2
  2. You click the submit and the error shows that the select box is required.
  3. You select some option from select 2.
  4. The validation error does not hide automatically

You can fix it with:

     $("select").on("select2:close", function (e) {  
        $(this).valid(); 
    });
Semela answered 17/6, 2015 at 3:38 Comment(1)
$("select").on("select2-close", function (e) { $(this).valid(); });Adopted
G
24

In Addition to ABIRAMAN's answer here is some code that

  • Makes the select2 box red when errors appear
  • List the error below the select2 box

<style>
  span.error{
    outline: none;
    border: 1px solid #800000;
    box-shadow: 0 0 5px 1px #800000;
  }
</style>

<script>
 $("#form").validate({
     rules: {
       email: "required"
     },
     highlight: function (element, errorClass, validClass) {
       var elem = $(element);
       if (elem.hasClass("select2-hidden-accessible")) {
           $("#select2-" + elem.attr("id") + "-container").parent().addClass(errorClass); 
       } else {
           elem.addClass(errorClass);
       }
     },    
     unhighlight: function (element, errorClass, validClass) {
         var elem = $(element);
         if (elem.hasClass("select2-hidden-accessible")) {
              $("#select2-" + elem.attr("id") + "-container").parent().removeClass(errorClass);
         } else {
             elem.removeClass(errorClass);
         }
     },
     errorPlacement: function(error, element) {
       var elem = $(element);
       if (elem.hasClass("select2-hidden-accessible")) {
           element = $("#select2-" + elem.attr("id") + "-container").parent(); 
           error.insertAfter(element);
       } else {
           error.insertAfter(element);
       }
     }
   });

$('select').select2({}).on("change", function (e) {
  $(this).valid()
});
</script>
Gigantism answered 26/10, 2017 at 11:40 Comment(3)
If I'm not mistaken, "unhighlight" has been replaced by "success" in the newest version of the jQuery Validate script. I also had to change the if statement in the "unhighlight" section to the following: if (elem.parent().hasClass("select2")) { Because the select2-hidden-accessible class seems to disappear if a field is invalid. This is using the most recent versions of everything.Hassiehassin
I would add that if you have a background-color or some CSS that Select2 overrides, you need to add !important to your error CSS styles. I had a background-color: yellow for error and Select2 was overriding that.Taphole
@Hassiehassin no, unhighliht and success are still distinct from one to another as described in jqueryvalidation.org/validatePinero
M
17

I have detailed this in a blog post: http://chadkuehn.com/jquery-validate-select2/

When you place a Select2 on a SELECT tag it hides the original element. So in the validation plugin you must adjust the proper wrapping markup when highlighting and unhighlighting.

    highlight: function (element, errorClass, validClass) {
        var elem = $(element);
        if (elem.hasClass("select2-offscreen")) {
            $("#s2id_" + elem.attr("id") + " ul").addClass(errorClass);
        } else {
            elem.addClass(errorClass);
        }
    },

    unhighlight: function (element, errorClass, validClass) {
        var elem = $(element);
        if (elem.hasClass("select2-offscreen")) {
            $("#s2id_" + elem.attr("id") + " ul").removeClass(errorClass);
        } else {
            elem.removeClass(errorClass);
        }
    }

View a DEMO here.

Multivibrator answered 6/6, 2014 at 14:26 Comment(3)
any chance of an update for select2 4.0.x. Doesn't seem to work.Asylum
@Asylum you find an update in my answer https://mcmap.net/q/349592/-how-to-make-select2-work-with-jquery-validation-pluginGigantism
Many thanks @Adam, your answer is still compatible to this day!Pinero
D
15

Found an answer on the forums @ https://github.com/select2/select2/issues/215 posted by corinnaerin. Worked perfectly for me. Sample code at http://plnkr.co/edit/4QaSguIiYsJtLpuPF8Rc?p=preview

      var $select = $('select').select2({
        placeholder: 'Choose',
        allowClear: true
      });

      /*
       * When you change the value the select via select2, it triggers
       * a 'change' event, but the jquery validation plugin
       * only re-validates on 'blur'
       */
      $select.on('change', function() {
        $(this).trigger('blur');
      });

      $('#myForm').validate({
        ignore: 'input[type=hidden], .select2-input, .select2-focusser'
      });
Damson answered 29/3, 2016 at 9:49 Comment(3)
up vote for : $select.on('change', function() { $(this).trigger('blur'); });Thievery
Perfect logical answer. ThanksGushy
Exactly what I was looking for, worked like a charm. Thank you!Stoltzfus
G
5

I've found that getting Select2 to work with jQuery Validate very much depends on the markup used in creating the Select2 control.

For the most practical use of the plugin, you'll probably be using dynamically loaded data (data obtained via web service vs. static <option/> elements in the page). And per their spec, the way to accomplish this is by attaching Select2 to an <input type="hidden"/> element. However, elements of type="hidden" are not validated by jQuery Validate by default.

In order to validate hidden elements using jQuery Validate, one must tinker with the ignore property in jQuery Validate's configuration object. See the ignore option in their spec. Try initializing the ignore value as null to get the validation to trigger.

Grozny answered 10/10, 2014 at 14:16 Comment(1)
My current strategy has been to assign the ignore property to a class named "ignore-validation" like so: ignore: '.ignore-validation' Doing it this way enables you to turn validation on and off for a particular element at will simply by adding/removing that class name on the input element.Grozny
L
3

just add a line in your validation function.

$('#_form_id').validate({

       ignore: 'input[type=hidden]',
            rules: {
                //Rules
            },
            messages: {
               //messages
            },
}
Lundgren answered 16/10, 2015 at 6:33 Comment(1)
It's my pleasure DamithLundgren
D
2

check out my code. I solve my problem by using those codes... few(css,jquery) codes only

$(document).ready(function() {

  //form validations---------------------------------------------------------
  $('#sample').validate({
    ignore: [],
    errorClass: "error",
    errorElement: "span"
  });

  $("#receiver_name").select2({
    placeholder: "Receiver Name"
  });

  $("#receiver_name").select2().change(function() {
    $(this).valid();
  });
});
.error .select2-choice.select2-default,
.error .select2-choices {
  color: #a94442;
  border-color: #a94442;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.error:focus,
.error .select2-choice.select2-defaultLfocus,
.error .select2-choicesLfocus {
  border-color: #843534;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
}
.select2-container .select2-choices .select2-search-field input,
.select2-container .select2-choice,
.select2-container .select2-choices,
.error {
  border-radius: 1px;
}
<html>

<head>
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

  <!-- Optional theme -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">

  <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.css" rel="stylesheet" />

  <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2-bootstrap.css" rel="stylesheet" />


</head>

<body>
  <form id='sample'>
    <select class="form-control" name="receiver_name[]" id="receiver_name" multiple required>
      <option value="1">1</option>
      <option value="2">2</option>
    </select>
  </form>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <!-- Latest compiled and minified JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.js"></script>


</body>

</html>
Depth answered 8/1, 2016 at 3:3 Comment(0)
N
2

This doesn't work in Bootstrap Validator() because the validator includes all the inputs in the form. This means it will validate the input search field of the select2 plugin. which will interfere with the multiselect validation

To fix this simply go to the validator.js Add the select2 input search class .select2-search__field to the ignore list:

Validator.INPUT_SELECTOR = ':input:not([type="submit"], button, .select2-search__field):enabled:visible'
Nevers answered 6/4, 2016 at 8:6 Comment(0)
K
0

When you create a custom rule, you also must properly declare it. Since your custom rule depends on an argument, then you must pass the argument when declaring the rule

rules: {
   country: {
       required: true,
       requiredcountry: "your argument here"  // <- declare the custom rule
   }
}
Katha answered 23/5, 2014 at 13:19 Comment(0)
E
0
$("select.select2-me").each(function(index, el) {

    if ($(this).is("[data-rule-required]") && 
    $(this).attr("data-rule-required") == "true") {
        $(this).on('select2-close', function(e) {
            $(this).valid()
        });
    }
});

work for me.

Envious answered 11/9, 2014 at 11:49 Comment(0)
N
0

You can check this link: https://github.com/rkeshmir/select2-validation Here you can find the simplest way to validate select2 components. The idea id trigger validation for all <select> items in DOM on their change event. Also I have added required CSS rules to highlight error and success states of input.

Neall answered 18/10, 2015 at 9:13 Comment(0)
R
0

To validate 'select2' inputs you first must tell jquery validate to consider hidden elements:

$.validator.setDefaults({ 
ignore: [],
});

This is custom highlight / unhighlight that i use for pointing select2 and tagit errors with jquery validate:

$("#someform").validate({
        rules: {
            nazwa: {
                required: true
            },
            ilosc_w_opakowaniu: {
                required: "#czy_opakowanie_zbiorcze:checked"
            }
        },
        messages: {
            nazwa: "Musisz wypełnić pole [Nazwa]",
            ilosc_w_opakowaniu: "Musisz podać ilość produktu w opakowaniu zbiorczym",
        },

        highlight: function( element, errorClass, validClass ) {
            if ( element.type === "radio" ) {
                this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
            } else {
                $( element ).addClass( errorClass ).removeClass( validClass );
            }

            // select2
            if( $(element).hasClass('select2-hidden-accessible') ){
                dzik = $(element).next('span.select2');
                if(dzik)
                    dzik.addClass( errorClass ).removeClass( validClass );
            }

            // tagit
            dzik2 = $(element).parent().find('ul.tagit') 
            if( dzik2.length == 1 )
                dzik2.addClass( errorClass ).removeClass( validClass );

        },
        unhighlight: function( element, errorClass, validClass ) {
            if ( element.type === "radio" ) {
                this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
            } else {
                $( element ).removeClass( errorClass ).addClass( validClass );
            }

            // select2
            if( $(element).hasClass('select2-hidden-accessible') ){
                dzik = $(element).next('span.select2');
                if(dzik)
                    dzik.removeClass( errorClass ).addClass( validClass );
            }

            // tagit
            dzik2 = $(element).parent().find('ul.tagit') 
            if( dzik2.length == 1 )
                dzik2.removeClass( errorClass ).addClass( validClass );
        }
     });

And some CSS:

/** select2 error hightight **/
.select2.error .select2-selection--single{
    border-color:red !important;
    color:red !important;
}

/** tagit error highlight **/
.tagit.error{
   border-color:red !important;
   color:red !important;
}
Relativize answered 13/10, 2016 at 10:42 Comment(0)
M
0

I solved the problem, the solution is to modify the highlight, unhighlight and above all errorPlacement methods for each instance of validate. However, in order not to modify each file, I put the modifications in the file jquery.validate.js

highlight: function( element, errorClass, validClass ) {
        if ( element.type === "radio" ) {
            this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
        } else {
            var elem = $(element);
            if (elem.attr('readonly') == 'readonly') {
                if (elem.hasClass("input-group-addon")) {
                   $("#" + elem.attr("id")).parent().addClass(errorClass);
                } else {
                    $( element ).addClass( errorClass ).removeClass( validClass );
                }
            } else {
                if (elem.hasClass("select2-hidden-accessible")) {
                   $("#select2-" + elem.attr("id") + "-container").parent().addClass(errorClass);
                } else {
                    $( element ).addClass( errorClass ).removeClass( validClass );
                }
            }
        }
    },
    unhighlight: function( element, errorClass, validClass ) {
        if ( element.type === "radio" ) {
            this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
        } else {
            var elem = $(element);
            if (elem.attr('readonly') == 'readonly') {
                if (elem.hasClass("input-group-addon")) {
                   $("#" + elem.attr("id")).parent().removeClass(errorClass);
                } else {
                    $( element ).addClass( errorClass ).removeClass( validClass );
                }
            } else {
                if (elem.hasClass("select2-hidden-accessible")) {
                    $("#select2-" + elem.attr("id") + "-container").parent().removeClass(errorClass);
                } else {
                    $( element ).removeClass( errorClass ).addClass( validClass );
                }
            }
        }
    },
    errorPlacement: function(error, element) {
        var elem = $(element);
        if (elem.attr('readonly') == 'readonly') {
            element = $("#" + elem.attr("id")).parent();
            error.insertAfter(element);
        } else {
            if (elem.hasClass("select2-hidden-accessible")) {
                element = $("#select2-" + elem.attr("id") + "-container").parent().parent().parent();
                error.insertAfter(element);
            } else {
                error.insertAfter(element);
            }
        }
    }
Matias answered 1/2, 2018 at 21:14 Comment(0)
C
0

According to the error placement logic of jQuery validator, you may use the markup like below.

<div class="input-group col-sm-12">
  <select class="form-control select2" id="ELEMENT ID" name="ELEMENT NAME">
  </select>
</div>

It will place the error block below the select2 box and make the error block visible.

Chaco answered 18/12, 2019 at 7:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.