Bootstrap-select validation error placement

Sasmit picture Sasmit · Jan 25, 2015 · Viewed 8.9k times · Source

I am using the bootstrap-select plugin, and HTML5 validation to validate the <select>.

When the form is submitted without selecting the option, I am able to view the error message. However, the error message is displayed outside the form and not next to the <select>.

This validation is working perfectly fine for other input fields that do not use the plugin, but has issues for any <select> that uses the plugin.

Error displayed outside the form

Any ideas?

Answer

KyleMit picture KyleMit · Jan 25, 2015

The issue is that bootstrap-select will hide your original input and instead style it's own with divs Here's what that looks like:

boostrap-select DOM

So when you submit, you should see the following error when HTML5 Validation tries to focus on your hidden control:

not focusable

According to the specs on hidden input elements

When an input element's type attribute is in the Hidden state [...] The input element represents a value that is not intended to be examined or manipulated by the user.

As a workaround, you can toggle the visibility back on, but collapse the control. This might cause other issues, and wouldn't actually focus the right control, but would cause the validation message to appear in the right place.

You could use the following CSS

select.selectpicker {
  display: block !important;
  float: left;
  overflow: hidden; 
  height: 34px;
  width: 0;
  border: 0; 
  padding: 0; 
  box-shadow: none; 
  color: white; 
}

Also, you'll want a way to transfer focus events from the original, now available, control to bootstrap-select. This will capture both your own tab events on the forum and help redirect focus when HTML5 validation kick in.

$("select.selectpicker").focus(function(){
  $(this).next(".bootstrap-select").find('.selectpicker').focus();
});

Here's a demo in stack snippets:

$("select.selectpicker").focus(function(){
  $(this).next(".bootstrap-select").find('.selectpicker').focus();
});
select.selectpicker {
  display: block !important;
  float: left;
  overflow: hidden; 
  
  height: 34px;
  width: 0;
  border: 0; 
  padding: 0; 
  
  box-shadow: none; 
  color: white; 
}
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.3/css/bootstrap-select.css" rel="stylesheet"/>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.3/js/bootstrap-select.js"></script>


<form >
  <input type="text" name="name" required /><br/>
  
  <select name="select-plain" required>
    <option></option>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
  </select><br/>
  
  <select name="select-boot" class="selectpicker" required>
    <option></option>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
  </select><br/>
  
  <input type="submit" value="Submit"/>
</form>