Set focus to search text field when we click on select 2 drop down
Asked Answered
K

14

44

I am using select2.js Version: 3.4.3 with bootstrap I have one dropdown.

enter image description here

When I click on dropdown, I get a list with search text fields.

But I my cursor is not focused on search text fields.

enter image description here

<form:select path="yearAge" id="yearAgeId"
    cssClass="form-control search-select static-select">
    <form:option value="">Years</form:option>
    <c:forEach var="i" begin="1" end="125"  >
    <form:option value="${i}" label="${i}"></form:option>
    </c:forEach>     
</form:select>


$(".search-select.static-select").select2({
    placeholder: $(this).attr('placeholder'),
    allowClear: true
});

When I click on dropdown, pointer focus should set to search text field automatically.

Kielce answered 17/9, 2014 at 5:35 Comment(0)
B
4

This issue can be resolve by using the setTimeout() fucntion to delay the focus() execute time, we can achieve this by modifying a function in select2.js at line # 3321

container.on('open', function () {
  self.$search.attr('tabindex', 0);
  //self.$search.focus(); remove this line
  setTimeout(function () { self.$search.focus(); }, 10);//add this line

});
Bode answered 18/4, 2015 at 20:30 Comment(2)
This is correct answer either the page have one or multiple select2-select boxes.+1Mumps
Whether it works or not, this can't be the correct answer. Dist files should not be modified, and select2.js should not be used in production in favor of its minified version. Moreover line numbers are expected to change between each release so giving a line number without release version is pointless...Gametophyte
F
87

If jQuery 3.6.0 is causing this you can use this:

 $(document).on('select2:open', () => {
    document.querySelector('.select2-search__field').focus();
  });
Fanatical answered 3/5, 2021 at 4:43 Comment(5)
Change the selector to input.select2-search__field when your using selects with the multiple flag.Hockey
This saved me a lot of time. As this is likely an issue with the version combination of select2 and jQuery 3.6.0, chances are some future release will allow you to do this using just jQuery selectors again. I couldn't work out why jQuery selectors weren't working until I saw this answer, and found github.com/select2/select2/issues/5993#issuecomment-800927000Politesse
Small but useful improvement. It avoids issue with tags if (!event.target.multiple) { $('.select2-container--open .select2-search--dropdown .select2-search__field').last()[0].focus() }Trombley
Its not working in case page have multiple select-2 select-boxes and you are switching betwwen them.Mumps
This unfortunately broke for mobile safari in iOS / iPadOS 15.4. See my answer for an alternative.Glomerulus
N
24

Try this

$(document).on('select2:open', (e) => {
    const selectId = e.target.id

    $(".select2-search__field[aria-controls='select2-" + selectId + "-results']").each(function (
        key,
        value,
    ){
        value.focus();
    })
})
Ngocnguyen answered 25/5, 2021 at 15:58 Comment(1)
This is the only solution for a page with a mix of single- and multi-select boxed. @hammad-ahmed-khan 's answer above is excellent when you only have single-select dropdowns but makes a mess of multi-select. This has to do with the way select2 only has one search box for all single-selects and reuses it for each dropdown, but multi-selects always have their search box visible.Inebriant
P
16

Tested and worked with jQuery 3.6.0:

$(document).on("select2:open", () => {
  document.querySelector(".select2-container--open .select2-search__field").focus()
})
Proclamation answered 19/11, 2021 at 15:41 Comment(2)
It is worked for me. My jQuery version is 3.6.0 and select2 version is 4.1.0-rc.0Inexpiable
works only if you have ONE select2 in the pageDrusilla
T
12

This how i fix globally

$(document).on('select2:open', (e) => {
        const selectId = e.target.id;
        $(".select2-search__field[aria-controls='select2-"+selectId+"-results']").each(function (key,value,){
            value.focus();
        });
    });
Torrie answered 21/6, 2022 at 17:41 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Interjection
B
9

Do not search for the element in the DOM. Instead, get the $search element directly from the instance that caused the select2:open event. Since the bug only occurs with single selects, you should also exclude multiple selects:

$(document).on('select2:open', e => {
    const select2 = $(e.target).data('select2');
    if (!select2.options.get('multiple')) {
        select2.dropdown.$search.get(0).focus();
    }
});
Brazilin answered 6/3, 2023 at 17:26 Comment(0)
G
5

The method in this answer broke in iOS/iPadOS 15.4.

A working alternative is listening for the click event on the parent directly and firing focus from there:

document.querySelector("#your-select-field-id").parentElement.addEventListener("click", function(){
    const searchField = document.querySelector('.select2-search__field');
    if(searchField){
        searchField.focus();
    }
});
Glomerulus answered 15/3, 2022 at 16:43 Comment(2)
And it also fixes the issue mentioned above by Anant Kumar Singh when working with many Select 2 on the same page.Brucie
I agree with Apex. This solved two issues. This really should be the accepted answer at this point.Powys
P
5

I try all suggestions from google and stackoverflow and spend 4 hours for that. Only what work is downgrade jQuery from 3.6 to 3.5

"jquery": "^3.6.0" -> "jquery": "3.5.1"

Just put this and save time

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js
Plasmodium answered 17/11, 2022 at 0:5 Comment(2)
This worked... but now i'm curious what defect in jquery/select2 caused this :-)Stinnett
finnaly and i don't wana know why tnx so much !!!Vagarious
B
4

This issue can be resolve by using the setTimeout() fucntion to delay the focus() execute time, we can achieve this by modifying a function in select2.js at line # 3321

container.on('open', function () {
  self.$search.attr('tabindex', 0);
  //self.$search.focus(); remove this line
  setTimeout(function () { self.$search.focus(); }, 10);//add this line

});
Bode answered 18/4, 2015 at 20:30 Comment(2)
This is correct answer either the page have one or multiple select2-select boxes.+1Mumps
Whether it works or not, this can't be the correct answer. Dist files should not be modified, and select2.js should not be used in production in favor of its minified version. Moreover line numbers are expected to change between each release so giving a line number without release version is pointless...Gametophyte
S
2

For NPM or Laravel: As I rely on NPM package manager in my Laravel Application, I had to revert jQuery from 3.6 to 3.5.1 in package.json, then run npm install and npm run prod. Then the problem is fixed.

"jquery": "^3.6.0" -> "jquery": "3.5.1",
Sextan answered 16/6, 2021 at 11:27 Comment(0)
L
1

Just add a custom line of jQuery after you call the select2 function to force focus to the specific search field. Just replace '#target' with the ID of the search inputfield.

$( "#target" ).focus();
Lengthwise answered 17/9, 2014 at 6:21 Comment(3)
$(".search-select.static-select").select2(....); Above line call after page load (only once) But I need to focus when I click on DropdownKielce
Add a click event to the select, when clicked add focus to the input field. $('select').click(function () { $( "#target" ).focus() });Lengthwise
I am not able to get target ,because it is created when i click on drop downKielce
N
1
$(document).on('select2:open', (e) => {
    var c = e.target.parentElement.children
    for (var i = 0; i < c.length; i++) {
        if (c[i].tagName === 'SPAN') {
            c = c[i].children
            break
        }
    }
    for (var i = 0; i < c.length; i++) {
        if (c[i].tagName === 'SPAN' && c[i].className === 'selection') {
            c = c[i].children
            break
        }
    }
    for (var i = 0; i < c.length; i++) {
        c = c[i]
    }

    $(
        ".select2-search__field[aria-controls='select2-" +
            c.getAttribute('aria-owns').replace('select2-', '').replace('-results', '') +
            "-results']",
    ).each(function (key, value) {
        value.focus()
    })
})
Ngocnguyen answered 7/10, 2021 at 14:50 Comment(0)
G
1

Another way to do it is:

// Find all existing Select2 instances
$('.select2-hidden-accessible')
    // Attach event handler with some delay, waiting for the search field to be set up
    .on('select2:open', event => setTimeout(
        // Trigger focus using DOM API
        () => $(event.target).data('select2').dropdown.$search.get(0).focus(),
        10));

NB: Trigger focus writing .get(0).focus() instead of .trigger('focus') (for using DOM API) because this wouldn't work with JQuery 3.6.0

Gametophyte answered 15/7, 2022 at 14:12 Comment(0)
P
0

I resolved for a web app like this

 $(document).on('select2:open', '.select2', function (e) {
    setTimeout(() => {
        const $elem = $(this).attr("id");
        document.querySelector(`[aria-controls="select2-${$elem}-results"]`).focus();
    });
});
Prudhoe answered 30/3, 2022 at 13:4 Comment(0)
O
-1

Maybe this helps:

$(document).on('select2:open', () => {
  document.querySelector('.select2-container--open .select2-search__field').focus();
});
Openeyed answered 3/12, 2022 at 3:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.