7

With select2 dropdown, how do I get a default option to appear if no options match the user's typed input?

$("something").select2({
  formatNoMatches: function(term) {
    //return a search choice
  }
});

I haven't been able to find anything that really matches this desired functionality within the select2 documentation or Stack Overflow.

Edit I'm getting closer with this

$("something").select2({
  formatNoMatches: function(term) {
    return "<div class='select2-result-label'><span class='select2-match'></span>Other</div>"
  }
});

But this is pretty hacky off the bat, and also isn't clickable.

varatis
  • 14,494
  • 23
  • 71
  • 114
  • 1
    Not too familiar with `select2`, but this posting might help: https://github.com/ivaynberg/select2/issues/448 – tymeJV Jul 30 '13 at 14:43
  • Are you using it attached to a `select` or `hidden` input? – Fabrício Matté Jul 30 '13 at 14:45
  • Reading last documentation (I used an old version) I see there's a way to do it with a function, but indicating the action after an underscore, it could be $("something_get") for example. I only had to use basic matching. – Maximiliano Rios Jul 30 '13 at 14:52
  • @MaximilianoRios Can you elaborate, or point me to the documentation you're viewing? – varatis Jul 30 '13 at 14:54
  • Of course, find it here: http://ivaynberg.github.io/select2/ – Maximiliano Rios Jul 31 '13 at 14:14
  • Come on -- I've looked at the select2 documentation ;). I meant "can you point me to the documentation that references `$("something_get")`"? – varatis Jul 31 '13 at 17:04
  • http://ivaynberg.github.io/select2/#documentation. Look for Programmatic Access, there're examples for _get and _set. I think it's not necessary to vote me down, just point if I'm wrong to help everybody – Maximiliano Rios Jul 31 '13 at 18:07

7 Answers7

9

To complement on @vararis's answer:

Select2 attached to a <select> element does not allow for custom createSearchChoice nor query functions, hence we will need to manually add an option element (I'll add it as the last option of the element so we can easily .pop it out of the results set):

<select>
  ...
  <option value="0">Other</option>
</select>

Then pass a custom matcher function so that this "Other" option is always matched.

NOTE: Select2 3.4+ uses a different default matcher than the one currently shown in the documentation, this new one has a call to the stripDiacritics function so that a matches á for instance. Therefore I'll apply the default matcher that comes with the Select2 version included in the page to apply its default matching algorithm to any option that's not the "Other" option:

matcher: function(term, text) {
  return text==='Other' || $.fn.select2.defaults.matcher.apply(this, arguments);
},

Finally, we need to remove the "Other" option from the results set when there's any result besides the "Other" result (which is initially always in the results set):

sortResults: function(results) {
  if (results.length > 1) results.pop();
  return results;
}

Demo

Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166
  • Note that I don't think the second part of this will work if 'other' is not at the end of the result set (like ['apples', 'other', 'trees'], but it's pretty obvious how to precede from here. – varatis Aug 05 '13 at 18:54
  • Yeah, I commented that part on the beginning. `=]` Even if you have some kind of sorting, I'd append the `Other` option afterwards for conveniently `.pop()`ing it out. But it is not hard to iterate over the result set array and `.splice()` the `Other` result out either. – Fabrício Matté Aug 05 '13 at 19:18
  • The matcher signature changed for Select2 version 4+, see https://stackoverflow.com/a/55281227/729324 – marcovtwout Mar 21 '19 at 13:12
1

I solved it by changing the matcher.

$('#activity_log_industry_name').select2
  matcher: (term, text) ->
    if text=="Other"
      return true
    text.toUpperCase().indexOf(term.toUpperCase())>=0

(this is in coffeescript.) The only problem is that "Other" will pop up for any search -- but this can be easily solved by modifying the sortResults function.

varatis
  • 14,494
  • 23
  • 71
  • 114
1

In version 4+ of Select2, the matcher should be passed like this:

$("something").select2({
    matcher: function(params, data) {
        if (data.id === "0") { // <-- option value of "Other", always appears in results
            return data;
        } else {
            return $.fn.select2.defaults.defaults.matcher.apply(this, arguments);
        }
    },
});

the "Other" option should be appended to the option list like this:

<select>
  ...
  <option value="0">Other</option>
</select>
marcovtwout
  • 5,230
  • 4
  • 36
  • 45
1

To customize formatNoMatches use following code in your view

ui-select2="{formatNoMatches:'No Results Found'}"

0

Try this answer on stackoverflow

createSearchChoice: function (term) {
  return { id: term, text: term };
}
Community
  • 1
  • 1
Adrian P.
  • 5,060
  • 2
  • 46
  • 47
0

Use following code to display the message as 'Other' when no matches found

$("select").select2({ 
formatNoMatches   :    function(term) {       
    return   "Other";
}
});
Reeno
  • 5,720
  • 11
  • 37
  • 50
Imamudin Naseem
  • 1,604
  • 18
  • 21
0

try it, this work in newer version ( Select2 4.0.3 ) without add a new variable.

>>>> Fiddle here <<<<

first you need to download javascript name "github/alasql" to search like query in data

<select id="something">
  ...
  <option value="other">Other</option> <!-- or put this in "dataItemsList" for dynamic option -->
</select>

then in your javascript

// other than this array we will give "other" option
var ajax_search_array = ['your', 'item', 'for', 'search'];

$("#something").select2({
   placeholder: "Choose your something",
   //data: dataItemsList, //your dataItemsList for dynamic option
   //...
   //...
   tags: true,
   createTag: function (tag) {
        // here we add %search% to search like in mysql
        var name_search  = "%"+tag.term.toString().toLowerCase()+"%";

        // alasql search
        var result = alasql('SELECT COLUMN * FROM [?] WHERE [0] LIKE ?',[ajax_search_array, name_search]);

        // if no result found then show "other"
        // and prevent other to appear when type "other"
        if(result==false && tag.term != "other"){
            return {
               id: "other",
               text: "Other"
            };
        }
});

hope this work.

Anthony Kal
  • 2,729
  • 1
  • 20
  • 18
  • HI .. i just need to add other option when there is not matching element in result. can you please help me – Dhrumil Shah Jun 01 '17 at 12:42
  • @DhrumilShah here we go, check the link there, i have updates my fiddle. i have used javascript name alasql. – Anthony Kal Jun 01 '17 at 16:42
  • Thanks a lot @KingGeneral.. But i am having "Other" as one option. when i am typing other there are two result is matching. i just need one result. Can you please suggest – Dhrumil Shah Jun 02 '17 at 06:04
  • did you mean when typing other , it displaying 2 other ?? ah already fixed that, see the code above / fiddle – Anthony Kal Jun 02 '17 at 07:49
  • Hi @KingGeneral. its still visible two other option. i think below code is not comparing other value. Please help... if(result==false && tag.term != "other"){ return { id: "other", text: "Other" }; } – Dhrumil Shah Jun 03 '17 at 05:53
  • can you give me your fiddle here. – Anthony Kal Jun 03 '17 at 06:52
  • Hi @kingGeneral.. I am referring to your fiddle only http://jsfiddle.net/kinggeneral/gt8j1d82/ – Dhrumil Shah Jun 04 '17 at 18:23
  • Hi @KingGeneral.. After adding below code its working as i want.. Thanks for your help.. // other than this array we will give "other" option var ajax_search_array = ['other','zone', 'kg', 'windows', 'uac']; – Dhrumil Shah Jun 05 '17 at 04:50