Search code examples
javascriptjquery-select2jquery-select2-4

Dynamically set select2 options with formatting


Select2 v4.0 lets you add options to the dropdown dynamically by creating new Option objects and appending them. How can you dynamically add data which has more than just an id and text?

More specifically, if the select2 uses the templateResult configuration to style data with more than just plain text then adding Options is too restrictive. This callback only works with the library's own data format.

$('#select2').select2({
    templateResult: function(data) {
        return data.text + ' - ' + data.count;
    }
});
$('#select2').append(new Option('Item', 1, false, false));

I'd like to add more complex data when the dropdown is opened and template the results.

I've tried some ugly workarounds, such as

var opt = new Option('Item', 1, false, false);
opt.innerHTML = '<div>Item</div><div>Count</div>';

But the HTML gets stripped and select2 displays plain text.


Solution

  • The library's maintainer states there is not going to be any support for this feature, as reported in a closed Github issue . The only reasonable workaround I've found is to re-initialize the element after it's populated:

    function initSelect2(data) {
      var select = $('#select2');
      select.select2({
        templateResult: function(data) {
          return data.text + ' - ' + data.count;
      });
      if (data.length) {
        select.data('loaded', 1);
        select.select2('open');
      } else {
        select.on('select2.opening', fillSelect2);
    }
    
    function fillSelect2() {
      var select = $('#select2');
      if (select.data('loaded')) {
        return;
      }
      var data = [];
      var data.push({id: 1, text: 'One', count: 1});
      var data.push({id: 2, text: 'Two', count: 2});
      var data.push({id: 3, text: 'One', count: 3});
      initSelect2(data);
    }
    
    initSelect2();