Disable dropdown opening on select2 clear
Asked Answered
E

5

38

Seems that select2 4 opens by default the dropdown when clearing the current selected item. Previous versions of select2 didn't seem to have that behaviour and I'm trying to achieve it but no luck for now.

Does anyone know how to hook into the clear event so we can disable it's default behaviour and clear the selected option without opening the dropdown?

Cheers, Al

Endbrain answered 14/4, 2015 at 2:52 Comment(4)
Assuming that this is a single select, you can preventDefault on the select2:closing event that is triggered right after select2:unselect. At another time I can write up a more complete answer.Haem
Thanks Kevin, I had a try but I get the error "Cannot set property 'prevented' of undefined" when preventDefault on select2:closing. I've put together a quick fiddle at jsfiddle.net/r56zh872 any help will be appreciated.Endbrain
@KevinBrown Is there any upstream issue created for this situation?Deas
@VladislavRastrusny Not that I consider it a bug, but this ticket was opened about it.Haem
H
21

Can confirm, preventing events seems to not work for some reason, so you can just close the dropdown after some timeout:

$("select").select2({
    allowClear: true
}).on("select2:unselecting", function(e) {
    $(this).data('state', 'unselected');
}).on("select2:open", function(e) {
    if ($(this).data('state') === 'unselected') {
        $(this).removeData('state'); 

        var self = $(this);
        setTimeout(function() {
            self.select2('close');
        }, 1);
    }    
});

Here's a working fiddle: http://jsfiddle.net/obq3yLf2/

Holmen answered 17/4, 2015 at 1:21 Comment(3)
Cheers Sam. Good workaround until the preventing issue gets solved.Endbrain
Its better the second solution, without timeOutSynonymy
I also had to go this route, but it still showed for a brief moment, which I didn't like. To fix that, I added a style like this: "body.hide-select2-dropdown .select2-dropdown { display: none; }". Then, where we remove the "state" data, I added this class to my body element. Finally, after calling "select2('close')", I removed this class from my body element. That seemed to resolve the issue.Nader
C
88

You don't require a timeout to make this work, here's my example:

$('#my-select').select2({
    allowClear: true
}).on('select2:unselecting', function() {
    $(this).data('unselecting', true);
}).on('select2:opening', function(e) {
    if ($(this).data('unselecting')) {
        $(this).removeData('unselecting');
        e.preventDefault();
    }
});
Cadaverine answered 4/3, 2016 at 22:38 Comment(2)
What if I have multiple select2 in a page ?Desolate
I assume you mean applying the above to multiple select2 elements? In that case you replace #my-select with maybe .selects and add the class to your select elements.Cadaverine
H
21

Can confirm, preventing events seems to not work for some reason, so you can just close the dropdown after some timeout:

$("select").select2({
    allowClear: true
}).on("select2:unselecting", function(e) {
    $(this).data('state', 'unselected');
}).on("select2:open", function(e) {
    if ($(this).data('state') === 'unselected') {
        $(this).removeData('state'); 

        var self = $(this);
        setTimeout(function() {
            self.select2('close');
        }, 1);
    }    
});

Here's a working fiddle: http://jsfiddle.net/obq3yLf2/

Holmen answered 17/4, 2015 at 1:21 Comment(3)
Cheers Sam. Good workaround until the preventing issue gets solved.Endbrain
Its better the second solution, without timeOutSynonymy
I also had to go this route, but it still showed for a brief moment, which I didn't like. To fix that, I added a style like this: "body.hide-select2-dropdown .select2-dropdown { display: none; }". Then, where we remove the "state" data, I added this class to my body element. Finally, after calling "select2('close')", I removed this class from my body element. That seemed to resolve the issue.Nader
B
3

I had a problem with a short delay after deselecting one of the items and this solution fixed that issue for me:

$(this).select2({
    multiple: 'multiple',
}).on("select2:unselecting", function(e) {
    var self = $(this);
    setTimeout(function() {
        self.select2('close');
    }, 0);
});
Biquadratic answered 23/3, 2017 at 14:30 Comment(0)
L
1

Another simple Implementation:

$('select').on('select2:unselect', function(evt) {
    $(this).select2({
        placeholder : {
            id : '',
            text : '---None Selected---'
        },
        allowClear : true,
        theme : "bootstrap"
    }).select2('close');
});
Legpull answered 16/3, 2017 at 15:48 Comment(0)
V
0

Here is your answer:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>


<select id="my-select">
<option>Test1</option>
<option>Test2</option>
<option>Test3</option>
</select>



<script>
$('#my-select').select2().on('select2:opening', function(currentEvent) {
  currentEvent.preventDefault();
});
</script>
Vitrification answered 5/12, 2021 at 8:21 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.Seductress

© 2022 - 2024 — McMap. All rights reserved.