Select 2 version 4.0 allow user to enter free text
Asked Answered
L

1

12

I am using the latest version of Select2: Select2 4.0.

I would like to allow users to enter free text. In other words if a user cannot find a option in the drop down (data returned by ajax), I want them to be able to 'select' whatever text they have typed in.

This is my markup:

<select class="required form-control" id="businessName" data-placeholder="Choose An Name" > </select> 

And this is the JavaScript that I am using to initialize Select2:

$("#businessName").select2({
    ajax: {
      url: "/register/namelookup",
      dataType: 'json',
      delay: 250,
      type: 'post',
      data: function (params) {
        return {
          businessName: params.term, // search term
          page: params.page
        };
      },
      processResults: function (data, page) {
        return {
          results: data.items
        };
      },
      cache: false
    },
    escapeMarkup: function (markup) { return markup; },
    minimumInputLength: 4,
    createSearchChoice:function(term, data) {
        if ( $(data).filter( function() {
          return this.text.localeCompare(term)===0;
        }).length===0) {
          return {id:term, text:term};
        }
    },
});

I added createSearchChoice but it doesn't work. I have looked at this answer as well but so far no luck.

Lapierre answered 3/5, 2015 at 21:22 Comment(1)
Possible duplicate of Select2 dropdown but allow new values by user?Skeen
S
29

This was a change in 4.0.0 that resulted from undocumented behaviour in 3.x. In 3.x, if you were using createSearchChoice you also should have been using tags (setting it to true or an empty array). This is because createSearchChoice and tags were tied together.

In 4.x, createSearchChoice was renamed to createTag because it was really creating the tag. This was documented in the 4.0.0-beta.2 release notes. Additionally, the second (also undocumented) parameter to createSearchChoice was never implemented - but you don't actually need it in this case.

So, with those two changes noted, the working code to allow for new options to be added by the user is

$("#businessName").select2({
    ajax: {
      url: "/register/namelookup",
      dataType: 'json',
      delay: 250,
      type: 'post',
      data: function (params) {
        return {
          businessName: params.term, // search term
          page: params.page
        };
      },
      processResults: function (data, page) {
        return {
          results: data.items
        };
      },
      cache: false
    },
    escapeMarkup: function (markup) { return markup; },
    minimumInputLength: 4,
    tags: true
});

Notice that I did not implement createTag, this is because the default implementation matched what your old createSearchChoice was trying to do. I did add tags: true though, because that is still required in order to make it work.

On top of that, you do have some invalid markup now that you have changed to a <select>.

<select class="required form-control" id="businessName" data-placeholder="Choose An Name" ></select>

The type attribute (previously set to hidden) is only required if you are using an <input /> and is not valid on a <select>. This shouldn't make any noticeable change to you.

Skeen answered 3/5, 2015 at 22:8 Comment(5)
Hi Kevin, thank you very much for your extensive answer, I should have spent more time on reading the release notes. Now it's working fine.Lapierre
Thank you I was sitting here like a berk wondering what was going on using code that worked in my last app before realising I was using the new version of select2.Trengganu
@kevin-brown, would you mind suggesting how to remove some of the free text after it's been added through createSearchChoice? I created a new question here: stackoverflow.com/q/39784421/1299792Limnology
Some additions: If you are using templateResult or templateSelection as options, you have to keep in mind to check index.text. All added select options with createTag are structured as {id: '', text: ''}. If your are creating a template and using other than item.text, the new select option will not set to the select.Grajeda
If I create a tag with free text, when I next select an existing option from the same select then my selected free text tag is removed from the selected options.Limnology

© 2022 - 2024 — McMap. All rights reserved.