Select2 with createSearchChoice uses the just created selection for keyboard input, even considering the coincidence, error, or am I missing something?

I am using Select2 (version 3.4.0) to populate the tag list. Tags are mapped to existing ones via an ajax call, and I use createSearchChoice to allow the creation of new tags. The code still works and looks something like this:

 $(mytags).select2({ multiple: true, placeholder: "Please enter tags", tokenSeparators: [ "," ], ajax: { multiple: true, url: myurl, dataType: "json", data: function(term, page) { return { q: term }; }, results: function(data, page) { return data; } }, createSearchChoice: function(term) { return { id: term, text: term + ' (new)' }; }, }); 

Everything is pretty standard, except for adding (new) to createSearchChoice . I need to let users know that this is no longer an existing tag.

It works as expected: if I start typing a "new tag", I get a "new tag (new)", which is offered at the top of the list, and if I select it, the tag list contains a "new-tag (new) ", as expected. If the tag already exists, Select2 determines the match, and a "(new)" selection is not created. Clicking on a return or clicking on a match works as expected.

The problem occurs when I enter a comma (my only tokenSeparators entry) when there is a match. Select2 closes this token and adds the tag to the list, but with the "(new)" label added, that is, it uses the return value from createSeachChoice , even if it is not necessary.

Is this a bug in Select2, or am I using it incorrectly (and what should I do instead)?

+16
jquery-select2
May 17 '13 at 9:48
source share
3 answers

I'm not sure if this is a mistake or not - in any case there is no open problem related to this behavior in the GitHub tracker problem at the moment.

In most cases, you can correct your behavior. The idea is that the createSearchChoice should be able to determine whether the term refers to the search result or not. But createSearchChoice does not have direct access to search results, so how can we enable this? Well, keeping the last batch of search results inside the results callback.

 var lastResults = []; $(...).select2({ ajax: { multiple: true, url: "/echo/json/", dataType: "json", type: "POST", data: function (term, page) { return { json: JSON.stringify({results: [{id: "foo", text:"foo"},{id:"bar", text:"bar"}]}), q: term }; }, results: function (data, page) { lastResults = data.results; return data; } }, createSearchChoice: function (term) { if(lastResults.some(function(r) { return r.text == term })) { return { id: term, text: term }; } else { return { id: term, text: term + " (new)" }; } } }); 

This code uses Array.some , so you need something better than IE8 (which is the minimum requirement for select2) to run it, but of course you can emulate the behavior.

Look at the action .

There is, however, a fly in maz: this code only works if the search results matching the current search query have already been received.

This should be obvious: if you type very quickly and create a search createSearchChoice that matches an existing tag, but strikes a comma before the search results that include this tag, createSearchChoice will test for the presence of the tag among the previously received search results. If these results do not include the tag, then the tag will be displayed as "new", even if it is not.

Unfortunately, I do not believe that you can do something to prevent this from happening.

+16
May 31 '13 at 13:00
source share

Instead of teasing the result, I think it's better to work on the server side.

If the server does not find the tag, it returns a json response with the new tag

 {"more":false,"results":[{"id":"whatever","text":"new-tag (new)"}]} 
+4
Feb 24 '14 at 16:08
source share

There is another parameter for 'createSearchChoice' - 'page', it lists all the options, you can easily find cheats with it.

 createSearchChoice = function (term, page) { if( page.some(function(item) { return item.text.toLowerCase() === term.toLowerCase(); }) ){ return { val: term, name: term + '*' }; } } 
+2
Oct 16 '14 at 14:45
source share



All Articles