11
votes

I'm using Select2 now since 2 years and I really enjoy all dev made. however, version 3.5.x has his limit, so I'm moving to version 4.0, which give me headaches!

For your record, I'm using Select2 with large table (> 10.000 entries), so AJAX & infinite data (page set to 50 items).

  1. With version 3.5.2, I can reproduce the underline match when searching for data (using formatSelection and query.term). Any idea how to make it with version 4.0.0 (function templateResult only passes result and not query anymore?

  2. With version 3.x, you can add free entries using search value was not in the list (using createSearchChoice). Version 4.0 does not have this option, any idea how to make it again?

  3. I try to replace the Select bar with an input bar (still using the select dropdown). It seems possible to force the adapter but I was unable to find how.

  4. I need to add either a line (at row 1) or a button (floating to the right) to add new item (similar to createTag, but for an item). has someone made it already?

2

2 Answers

21
votes

I'd highly recommend reading the release notes and the 4.0 release announcement when migrating from Select2 3.5.2 to Select2 4.0.0.

With version 3.5.2, I can reproduce the underline match when searching for data (using formatSelection and query.term).. any idea how to make it with v4.0.0 (function templateResult only pass 'result' and not 'query' anymore ?

This was removed in 4.0 because the results have been separated from the queries, so it didn't make sense to keep passing along the information. Of course, this doesn't mean you can't get the query and store it. All you would need to do is store the query, something like the following might work

var query = {};
var $element = $('#my-happy-select');

function markMatch (text, term) {
  // Find where the match is
  var match = text.toUpperCase().indexOf(term.toUpperCase());

  var $result = $('<span></span>');

  // If there is no match, move on
  if (match < 0) {
    return $result.text(text);
  }

  // Put in whatever text is before the match
  $result.text(text.substring(0, match));

  // Mark the match
  var $match = $('<span class="select2-rendered__match"></span>');
  $match.text(text.substring(match, match + term.length));

  // Append the matching text
  $result.append($match);

  // Put in whatever is after the match
  $result.append(text.substring(match + term.length));

  return $result;
}

$element.select2({
  templateResult: function (item) {
    // No need to template the searching text
    if (item.loading) {
      return item.text;
    }

    var term = query.term || '';
    var $result = markMatch(item.text, term);

    return $result;
  },
  language: {
    searching: function (params) {
      // Intercept the query as it is happening
      query = params;

      // Change this to be appropriate for your application
      return 'Searching…';
    }
  }
});

With version 3.x, you can add free entries using search value was not in the list (using createSearchChoice). V4.0 has not this option, any idea how to make it again ?

This can still be done in 4.0 using the tags option (set it to true). If you want to customize the tag, you can use createTag (similar to createSearchChoice).

var $element = $('#my-happy-select');

$element.select2({
  createTag: function (query) {
    return {
      id: query.term,
      text: query.term,
      tag: true
    }
  },
  tags: true
});
4
votes

Simple way to underline matched results with select2 4.x

$element.select2({

    escapeMarkup: function (markup) { return markup; }
    ,
     templateResult: function (result) {
        return result.htmlmatch ? result.htmlmatch : result.text;
     }
    ,
    matcher:function(params, data) {
        if ($.trim(params.term) === '') {
          return data;
        }
        if (typeof data.text === 'undefined') {
          return null;
        }

        var idx = data.text.toLowerCase().indexOf(params.term.toLowerCase());
        if (idx > -1) {
          var modifiedData = $.extend({
              'htmlmatch': data.text.replace(new RegExp( "(" + params.term + ")","gi") ,"<u>$1</u>")
          }, data, true);

          return modifiedData;
        }

        return null;
    }
})