How to programmatically inject search queries into Select2 v4?
Solution 1
Select2 used to provide a select2('search', 'term')
helper method that would have assisted with this, but it was not brought over to Select2 4.0.0.
There are a couple of ways that this could be done, but in general they all follow the same pattern of steps
- Open the Select2 dropdown
- Enter the search text into the search box
- Trigger the keyboard events necessary for Select2 to start searching (usually
input
)
So, right now, in Select2 4.0.0 the code to do that would look like
$('select').select2();
function select2_search ($el, term) {
$el.select2('open');
// Get the search box within the dropdown or the selection
// Dropdown = single, Selection = multiple
var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
// This is undocumented and may change in the future
$search.val(term);
$search.trigger('keyup');
}
$('button').on('click', function () {
var $select = $($(this).data('target'));
select2_search($select, 'Arizona');
});
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>
<select style="width: 200px;" id="single">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
</select>
<button type="button" data-target="#single">Search for 'Arizona'</button>
<br /><br />
<select style="width: 200px;" id="multiple" multiple="multiple">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
</select>
<button type="button" data-target="#multiple">Search for 'Arizona'</button>
While this example does not use AJAX, it will trigger an AJAX request if Select2 is configured for it.
Solution 2
for me triggering 'keyup' only worked when the user didn't select any option yet. What works every time is to trigger 'input' instead. (only tested on Chrome)
so based on Kevin Brown's answer:
$('select').select2();
function select2_search ($el, term) {
$el.select2('open');
// Get the search box within the dropdown or the selection
// Dropdown = single, Selection = multiple
var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
// This is undocumented and may change in the future
$search.val(term);
$search.trigger('input');
}
$('button').on('click', function () {
var $select = $($(this).data('target'));
select2_search($select, 'Arizona');
});
Solution 3
You can set minimumInputLength
to 0
then in the data
function you may check params.term
length
and if it's 0
, set the filter value to your predefined search value.
It's quite silly, but it works ;)
Solution 4
The answers on this page got me almost there. And because others seem to have the same issues, I am sharing how I solved it.
Some of the comments on Kevin Browns answer asked how to simulate the ENTER after the text has been entered and is highlighted.
I managed to do that only with a timeout:
setTimeout(function() { $('.select2-results__option').trigger("mouseup"); }, 500);
So, the full solution would be this:
$('select').select2();
function select2_search ($el, term) {
$el.select2('open');
// Get the search box within the dropdown or the selection
// Dropdown = single, Selection = multiple
var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
// This is undocumented and may change in the future
$search.val(term);
$search.trigger('input');
setTimeout(function() { $('.select2-results__option').trigger("mouseup"); }, 500);
}
$('button').on('click', function () {
var $select = $($(this).data('target'));
select2_search($select, 'Arizona');
});
Solution 5
As an addition to this answer, we were trying to programmatically add a new 'tag' to a select2 configured for tagging. Instead of triggering a keyup event on the $search box, we had to do the following.
$search.val(tag);
$search.closest('.select2-search--inline')
.trigger($.Event('input', { which: 13 }));
$search.closest('.select2-selection--multiple')
.trigger($.Event('keydown', { which: 13 }));
This first fires an event that causes the 'search' module in select2 to add a 'highlighted' result containing the tag text, then the second event causes select2 to fire the 'select' event internally which adds a new tag to the select2 options and may also trigger other stuff, depending on how you've configured it.
![vgoklani](https://i.stack.imgur.com/xkknZ.jpg?s=256&g=1)
vgoklani
Updated on July 07, 2021Comments
-
vgoklani almost 3 years
I've built a web-app using a Select2 search box, which connects to our backend via AJAX. The search box passes the query (say "APPLES") to the backend, which then updates the page. How do I programmatically inject search queries into the search box? I need to pass in the "val" so that select2 calls the backend via AJAX and updates the page. I'm sure this is obvious, but I couldn't find it in the documentation.
For example, instead of forcing a user to type "APPLES" into the search box, I would like the user to click a button and have the word "APPLES" automatically populated into the search field, and then have the page update.
Thanks!
Following Kevin's comment, I'm not in this state where the text is embedded in the searchbox and the selector has picked the correct item. How do I submit (or trigger) this request, I tried "keydown", "pressdown", "submit", "click" (which clears the box), etc.
-
vgoklani about 9 yearsThanks for response Kevin. Unfortunately I don't see the $search variable after $e1.data('select2').dropdown. I'm also making an AJAX call, so select2 doesn't see all the ids until after the AJAX request. I've been working on this for a few days, hopefully you can clarify things. Thanks
-
vgoklani about 9 yearsI should add that I have two search boxes, and only one is using AJAX. The non-ajax select2 box handles injections seamlessly via $selectionBox.val(23).change('trigger'). I'm guessing that the AJAX version fails since it doesn't have the ids. when i run this function $selectionBoxAJAX.val(47).change('trigger'), an update gets pushed (the screen updates) but the query is empty, and the correct text does not get updated
-
Kevin Brown-Silva about 9 years@vgoklani I think the issue may be that you are using a multiple select, want to just confirm that (and I can update this answer to also support it).
-
vgoklani about 9 yearsYes I am using multiple select
-
Kevin Brown-Silva about 9 yearsI've updated my answer to work for multiple selects as well, and included an example for them.
-
vgoklani about 9 yearsThanks Kevin, it's almost there! The text is now in the selection box and is highlighted in the dropdown, what's the "trigger" to make it submit?
-
vgoklani about 9 yearsI added an image to show you precisely where I'm stuck. Thanks again for your help!
-
goyote about 8 yearsThis is not complete, how do you simulate an ENTER afterwards so the dropdown accepts the entered string and closes?
-
phazei about 8 yearsSo, the trigger('keyup') didn't do anything for me, I ended up using s2Obj.trigger('query', {term:term}); to trigger a search with the term I wanted
-
user3057544 over 7 yearsaccording to @goyote comment/question - "how do you simulate an ENTER afterwards so the dropdown accepts the entered string and closes" - was it answered somewhere ?
-
Johnner over 7 yearsThis is what I was looking for! Thanks for "minimumInputLength: 0" suggestion. My task was to pre-populate select2 with some initial data with ajax call. So all I need to do is to set minimum input to 0 and to filter out request with empty GET param "q=" on the server and return default values. Awesome!
-
Santiago over 7 yearsI can simulate the ENTER with $('.select2-results__option[aria-selected]') .trigger("mouseup");
-
Faizan Anwer Ali Rupani over 5 yearsKey Event triggers blocked by browser as of 2019 for security reason
-
mickmackusa about 3 years@Kevin I am not a javascript SME, how does the trailing
$search
in$search = $el.data('select2').dropdown.$search
work? How are you accessing$search
before it is supplied? I don't follow this part. Can you edit the explanation into your answer? Is it your personal preference not to chainval()
andtrigger()
? -
dahe about 2 yearsGood solution, I am using a data attribute "no-minimum-input-length". If its present at .seelct2({ .. options .. }) initialization the minimumInputLength is set to 0. Resulting in search on click which is useful if there are just a handful of options to choose from loaded via ajax.