lostintheriver lostintheriver - 5 months ago 26
jQuery Question

Bootstrap-select not working with dynamically populated options



'use strict';
var PS = (function(){
var municipes = [{
"cod_prov": "01",
"cod_mun": "001",
"id": 0,
"name": "Alegría-Dulantzi"
}, {
"code": "47",
"name": "VALLADOLID"
}, {
"code": "48",
"name": "BIZKAIA"
}, {
"code": "49",
"name": "ZAMORA"
}, {
"code": "50",
"name": "ZARAGOZA"
}, {
"code": "51",
"name": "CEUTA"
}, {
"code": "52",
"name": "MELILLA"
}];

var provinceCssSelector = '.ps-prov';
var municipeCssSelector = '.ps-mun';
var provinceDefaultText = 'Provincia';
var municipeDefaultText = 'Municipio';


$().ready(function() {
// Set default text
$(provinceCssSelector).append($('<option>').text(provinceDefaultText).attr('value', -1));
$(municipeCssSelector).append($('<option>').text(municipeDefaultText).attr('value', -1));

// Populate province select
$.each(provinces, function(number, province) {
$(provinceCssSelector).append($('<option>').text(province.name).attr('value', province.code));
});

// When selected province changes, populate municipe select
$(provinceCssSelector).change(function() {
var selectedProvince = this.value;
$(municipeCssSelector).empty();
$(municipeCssSelector).append($('<option>').text(municipeDefaultText).attr('value', -1));
$.each(municipes, function(number, municipe) {
if (municipe.cod_prov == selectedProvince) {
$(municipeCssSelector).append($('<option>').text(municipe.name).attr('value', number.toString()));

}

});



});
$('.selectpicker').selectpicker('refresh');



});

}());

<html lang="en">
<head>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</head>
<body>



<tr>
<td>Select where happenings occurred</td>
<td>

<select id="province" name="province" class="ps-prov selectpicker show-tick form-control" data-live-search="true" ></select>



</td>
</tr>

<tr>
<td>Select city</td>
<td>

<select id="city" name="city" class="ps-mun selectpicker show-tick form-control" data-live-search="true"></select>
</td>

</tr>








</table>

</form>


</div>

</html>





I am trying to use bootstrap-select to improve the style of one my projects but when the options of the select are built dynamically the plugin does not work and I do not find the error. I have included the
$('.selectpicker').selectpicker('refresh');
as proposed by this answer but still I am not able to achieve what I want. The HTML is the following and works perfectly:

<tr>
<td>Select where happenings occurred</td>
<td>
<select id="province" name="province" class="ps-prov selectpicker show-tick form-control" data-live-search="true"></select>
</td>
</tr>
<tr>
<td>Select city</td>
<td>
<select id="city" name="city" class="ps-mun selectpicker show-tick form-control" data-live-search="true"></select>
</td>
</tr>


The javascript works in the following way

var provinceCssSelector = '.ps-prov';
var municipeCssSelector = '.ps-mun';
var provinceDefaultText = 'Provincia';
var municipeDefaultText = 'Municipio';


$().ready(function() {
// Set default text
$(provinceCssSelector).append($('<option>').text(provinceDefaultText).attr('value', -1));
$(municipeCssSelector).append($('<option>').text(municipeDefaultText).attr('value', -1));

// Populate province select
$.each(provinces, function(number, province) {
$(provinceCssSelector).append($('<option>').text(province.name).attr('value', province.code));
});

// When selected province changes, populate municipe select
$(provinceCssSelector).change(function() {
var selectedProvince = this.value;
$(municipeCssSelector).empty();
$(municipeCssSelector).append($('<option>').text(municipeDefaultText).attr('value', -1));
$.each(municipes, function(number, municipe) {
if (municipe.cod_prov == selectedProvince) {
$(municipeCssSelector).append($('<option>').text(municipe.name).attr('value', number.toString()));
}
});
$('.selectpicker').selectpicker('refresh');
});
});


Does anyone know how to make the combo select works?

Answer

The problem here is that the plugin bootstrap-select is creating a new element (div) that has every class from your original element (select).

So when your code tries to append the options in the select using the css selector, you are both appending in the original element (select) and in the element that the plugin created (div), causing the erratic behavior.

You have many ways to prevent this behavior, one is to use the ID selector for example.

Here's a snippet a possible solution:

var provinceCssSelector = '#province';
var municipeCssSelector = '#city';
var provinceDefaultText = 'Provincia';
var municipeDefaultText = 'Municipio';

var provinces = [{
  name: '1',
  code: 1
}, {
  name: '2',
  code: 2
}, {
  name: '3',
  code: 3
}];

var municipes = [{
  name: '1-1',
  cod_prov: 1
}, {
  name: '1-2',
  cod_prov: 1
}, {
  name: '1-3',
  cod_prov: 1
}, {
  name: '2-1',
  cod_prov: 2
}, {
  name: '2-2',
  cod_prov: 2
}, {
  name: '2-3',
  cod_prov: 2
}, {
  name: '3-1',
  cod_prov: 3
}, {
  name: '3-2',
  cod_prov: 3
}, {
  name: '3-3',
  cod_prov: 3
}];

$().ready(function() {

  // Set default text
  $(provinceCssSelector).append($('<option>').text(provinceDefaultText).attr('value', -1));
  $(municipeCssSelector).append($('<option>').text(municipeDefaultText).attr('value', -1));

  // Populate province select
  $.each(provinces, function(number, province) {
    $(provinceCssSelector).append($('<option>').text(province.name).attr('value', province.code));
  });

  // When selected province changes, populate municipe select
  $(provinceCssSelector).change(function() {
    var selectedProvince = this.value;
    $(municipeCssSelector).empty();
    $(municipeCssSelector).append($('<option>').text(municipeDefaultText).attr('value', -1));
    $.each(municipes, function(number, municipe) {
      if (municipe.cod_prov == selectedProvince) {
        $(municipeCssSelector).append($('<option>').text(municipe.name).attr('value', number.toString()));
      }
    });
    $(municipeCssSelector).selectpicker('refresh');
    $(municipeCssSelector).selectpicker('render');
  });
});
<link rel="stylesheet" href="http://getbootstrap.com/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="http://silviomoreto.github.io/bootstrap-select/bootstrap-select.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script>
<script src="http://silviomoreto.github.io/bootstrap-select/bootstrap-select.min.js"></script>

<table>
  <tr>
    <td>Select where happenings occurred</td>
    <td>
      <select id="province" name="province" class="ps-prov selectpicker show-tick form-control" data-live-search="true"></select>
    </td>
  </tr>
  <tr>
    <td>Select city</td>
    <td>
      <select id="city" name="city" class="ps-mun selectpicker show-tick form-control" data-live-search="true"></select>
    </td>
  </tr>
</table>

Hope it helps!

Comments