yourlabs / django-autocomplete-light

A fresh approach to autocomplete implementations, specially for Django. Status: v4 alpha, v3 stable, v2 & v1 deprecated.
https://django-autocomplete-light.readthedocs.io
MIT License
1.79k stars 467 forks source link

Autocomplete widget does not receive focus when clicked #1283

Open bpepple opened 2 years ago

bpepple commented 2 years ago

With django-autocomplete-light-3.9.1, I've noticed the widget doesn't receive focus when selected. This necessitates having to use the mouse to get focus, since it can't be done with the keyboard.

davy39 commented 2 years ago

Maybe its a duplicate... But, for me, it does focus when it's on the first wizard step, but not on other one. Are you using formtools ? Or maybe bootstrap modal (https://github.com/select2/select2/issues/1645) ? Is it working with previous DAL versions ?

bpepple commented 2 years ago

Maybe its a duplicate... But, for me, it does focus when it's on the first wizard step, but not on other one. Are you using formtools ? Or maybe bootstrap modal (select2/select2#1645) ? Is it working with previous DAL versions ?

No, this is with the standard ModelSelect2 widget (no formtools), which worked fine with the previous stable version (3.8.2).

bernd-wechner commented 2 years ago

I just landed here because I noticed exactly the same. I just upgraded to Django 4 and along with that upgraded all the django- packages, this one included (I don't even know what version I had alas and it might even be hard to find). But in testing tbhe system now for changes and breaks and fixing them, I notice this one.

The DAL widget now, when clicked does not put the text filter box in focus. So a second click is needed to focus on it. It drops down below the select box. To illustrate:

Before clicking:

image

After clicking:

image

Prior to these upgrades the two top rows of the expanded widget were one, namely the box you type into, the filter, was over the top of the other one. Something has changed.

bernd-wechner commented 2 years ago

Bad news. I rolled back my dev box to django==3.1.7 django-autocomplete-light==3.8.2 which was stable and working fine without this glitch, and it still shows the glitch. That frustrates as an easy diagnosis is now out the door. It means something outside of those two upgrades is causing it.

bernd-wechner commented 2 years ago

I can confirm also that on my end after testing only the ModelSelect2 widget is affected this way and ModelSelect2Multiple is not. I am drilling into the JS a bit to try and work out what's going on, but it's hard.

bernd-wechner commented 2 years ago

As this new "feature" has killed data entry on my site (I have to admit DAL is the flakiest widget I have ever used, regularly going wrong somehow, but still, seems the best in its class and irreplaceable), I stepped through the JS in the debugger with a watchful eye and have narrowed the position of the drop-down to here:

https://github.com/select2/select2/blob/5c38f186c98d793c7d396442986191ca05634d0a/src/js/select2/dropdown/attachBody.js#L148

which is in select2 not DAL, and it attaches CSS that positions the drop-down.

I will drill a little further to diagnose the criteria for placement. It would please me immensely if more talented people with more select2 and DAL expertise did this diagnosis, but for now my goal is:

  1. To understand positioning, as I am fairly convinced the drop down is now a row lower than it was.
  2. Understanding that positioning is not the same as focus whixh is the crux of the problem (if the filter box had focus after dropping down and our old TAB, ENTER, type, ENTER, TAB, ENTER, type, ENTER, TAB, ENTER, type, ENTER ... data entry system worked again I'd be losing less sleep ;-). But that broke because after TAB, and then ENTER to open the dropdown, typing does nothing as the box has lost focus ... Grrrr.
bernd-wechner commented 2 years ago

Well, I've worked nutted out the placement issue, but also installed the DAL test project and checked some references and it's being placed just as expected, below the original placeholder. So 1. is sorted (and was not important at all, rather a bee in my bonnet on account of misremembering expected behaviour).

I have comparisons of the HTML on my site and the test project and the differences are marginal at best. I built a very clean test in my venv a page that has nothing on it but one DAL widget and includes only the bare minimum to make it work.

Alas, the test project is not so clean, nor does it offer such a clean comparison and so I will have to build one quickly and see how that runs. As I do have a working copy to compare against the method of bisection and comparison will hopeful land me on the culprit before too long.

The test project alas does not run with Django 4, so I'm running it with Django 3.2. The docs on using it are also very dated and still referred to syncdb, but that is another story. If need be I will tweak the test project to run under Django 4 too.

bernd-wechner commented 2 years ago

I added two supremely simple clean test pages with nothing but a single DAL widget on them, to the test_project to explore further.

I found most of the examples very difficult to compare with my use case as they are embedded in a lot of distracting context. And it may be, I reasoned, the context of my implementation causing this aberrant behaviour, maybe some include, or other package or something. And so the motivation exists to isolate the widget from everything else, to see it in its naked glory if you will.

I first did this in my project with my models and my database and have such a demo.

My goal was to implement same in the form test_project here and hopefully see a working widget and then be able to compare very closely the result. For better or worse, that was not to be. My implementation in the test_project reproduces the issue.

Not all is lost, that certainly makes it possible now for someone else to step up and look at this example and comment. It maintains formidable utility in its isolation and simplicity.

As my data entry is seriously compromised by this I sincerely hope this empowers someone to take a quick look and suggest a change that produces a working widget, namely identity that it's something I can easily fix in my code, some silly mistake I've made, and not a DAL bug at all! That would be a dream come true if it happened soon! I just want my site working again ;-)

bernd-wechner commented 2 years ago

The test project for DAL can now be played with live at:

https://dal-test.thumbs.place/

And this issue clearly seen at:

https://dal-test.thumbs.place/dal_single/

In a completely minified unadorned context to simplify diagnostics and comparisons (that site implements this PR of course).

So I would like to beg, plead, ask kindly, for any helpful input in fixing this site breaking issue introduced by recent upgrades.

bernd-wechner commented 2 years ago

All quiet on the Western Front?

I admit my trouble in analyzing the cause of this is that even at its stripped down simplest:

https://dal-test.thumbs.place/dal_single/

There are three distinct layers of JS involved:

  1. DAL
  2. Select2
  3. JQuery

What that means is breaking on any event triggers sees us landing in the bowels of JQuery first, trickling up to Select2 and I have never got so far as DAL code in any effort.

And if I had some small inkling as to where and how focus is (and was, prior to this break) shifted from the select tag that was clicked to the search tag that appears in the drop-down, I'd have solved this by now. But working blind, trying to reverse engineer who things hang together, is slow.

My sincere hope is that someone with some DAL experience will pip up, take a look at that and or provide some guidance.

Or is it Select2 experience? You see already in hypothesising the location of the focus transfer code (that isn't doing its job) I am not sure what layer it is in. At some level it has to be in Select2 because Select2 draws the drop-down and I expect an ordinary Select2 widget to do such a transfer. So that if I tab to the widget and hit ENTER, the dropdown appears, and I can immediately type a search term. I don't need to grab my mouse and click the search box. In fact, I am confident that for years now that's what we've been doing on data entry! And then it broke with these recent upgrades.

And I can't even find a working widget to compare against.

This simple example:

https://dal-test.thumbs.place/select2_outside_admin/

only demonstrates the multi select widget, which works. No problem And is precisely why I PR an addition of the simple set of demos/tests.

That leaves us searching through the many non-simply and context embedded admin examples at:

https://dal-test.thumbs.place/admin/

One by one, click Add to get a basic form:

  1. Authentication and Authorisation - no example there
  2. Custom_Select2 - no example there
  3. Forward_Different_Fields - bingo we have an example. In the last field labelled Test there is implemented a Select2 that works.

So here we have a working example:

https://dal-test.thumbs.place/admin/forward_different_fields/tmodel/add/

Albeit it is heavily embeded in context that may distract from an analysis. And still I am stuck finding leverage, dining a way to catch the focus transfer. But I will presently try a little and report back.

bernd-wechner commented 2 years ago

Well, 3. is a broken widget so moved onto:

  1. Linked_Data

it has a working Select2 single select widget under the label Test (actually has 4 of them).

Made a little diagnostic progess. I found that if I put this on the end of select2.full.js:

function log_event() { 
    console.log('focused: ', document.activeElement); 
    console.trace(); 
}

document.addEventListener('focusin', log_event, true);

Something useful emerges. If I load this page:

https://dal-test.thumbs.place/dal_single/

and click the widget all I see is:

21:20:49.942 focused:  
<span class="select2-selection select…ection--single selector" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-disabled="false" aria-labelledby="select2--container" aria-owns="select2--results">
[select2.full.js:6823:13](https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js)
21:20:49.943 console.trace() [select2.full.js:6824:13](https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js)
    log_event https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:6824

and if I load:

https://dal-test.thumbs.place/admin/linked_data/tmodel/add/

and clock the Test widget I see:

21:23:13.518 focused:  
<span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-disabled="false" aria-labelledby="select2-id_test-container" aria-owns="select2-id_test-results">
[select2.full.js:6823:13](https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js)
21:23:13.518 console.trace() [select2.full.js:6824:13](https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js)
    log_event https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:6824
    (Async: EventListener.handleEvent)
    <anonymous> https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:6827
21:23:13.520 focused:  
<input class="select2-search__field" type="search" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" data-com.bitwarden.browser.user-edited="yes" aria-controls="select2-id_test-results">
[select2.full.js:6823:13](https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js)
21:23:13.520 console.trace() [select2.full.js:6824:13](https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js)
    log_event https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:6824
    jQuery 5
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:4130
    (Async: setTimeout handler)
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:4129
    invoke https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:655
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:645
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5827
    _registerEvents https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5666
    invoke https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:655
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:645
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5827
    open https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5851
    toggleDropdown https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5838
    _registerSelectionEvents https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5609
    invoke https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:655
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:645
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:1629
    jQuery 8
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:1623
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:1868
    calledMethod https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:598
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:2228
    calledMethod https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:598
    _bindAdapters https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5534
    Select2 https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5418
    select2 https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:6762
    jQuery 2
    select2 https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:6759
    <anonymous> https://dal-test.thumbs.place/static/collected/autocomplete_light/select2.js:92
    initialize https://dal-test.thumbs.place/static/collected/autocomplete_light/autocomplete_light.js:153
    jQuery 2
    <anonymous> https://dal-test.thumbs.place/static/collected/autocomplete_light/autocomplete_light.js:185
    jQuery 9
    <anonymous> https://dal-test.thumbs.place/static/collected/autocomplete_light/autocomplete_light.js:184
    <anonymous> https://dal-test.thumbs.place/static/collected/autocomplete_light/autocomplete_light.js:238
    (Async: EventListener.handleEvent)
    <anonymous> https://dal-test.thumbs.place/static/collected/autocomplete_light/autocomplete_light.js:30

The whole difference is in fact the missing focus shift, and the focus shift has a wonderful stack trace to analyse.

bernd-wechner commented 2 years ago

And so I walked through both the working and on working code step by step single stepping in two browsers and debuggers looking for the point of divergence. I got as far as this:

21:58:17.769 console.trace() [debugger eval code:1:9](chrome://devtools/content/webconsole/debugger%20eval%20code)
    <anonymous> debugger eval code:1
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:2244
    invoke https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:655
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:649
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5818
    _registerEvents https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5666
    invoke https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:655
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:645
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5827
    open https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5851
    toggleDropdown https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5838
    _registerSelectionEvents https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:5609
    invoke https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:655
    trigger https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:645
    bind https://dal-test.thumbs.place/static/collected/admin/js/vendor/select2/select2.full.js:1629
    jQuery 2

alas it spends some time inside of JQuery at that point and I noticed the line numbers different by a little so I checked with:

console.log(jQuery.fn.jquery);

and it turns out the working one is using 3.5.1 and the not working one is using 3.6.0

So I went back to my own site, and checked, and we are using 3.6.0. I changed it to 3.5.1 to see what happens and voila, this issue disappears. The search box gets focus again.

And so, a long and arduous process, but I nailed a part of the cause, and a fix so our site is functional again. This issue stands of course as DAL should function with the latest JQuery at any given time and we should understand the break the actual reasons and fix DAL. But for now I am content it at least not an urgent crisis any more on my web site.

bernd-wechner commented 2 years ago

So I fixed the test site, and the PR above to use 3.5.1 and now:

https://dal-test.thumbs.place/dal_single/

works beautifully. And serves, as it is intended, as a stripped down bare minimal test of the widget against which you can compare your site if you experience any dysfunction.

bernd-wechner commented 2 years ago

I will go one further and provide a complete diff between JQuery 3.5.1 and 3.6.0. Somewhere in these (surprisingly few) changes, lies the thing that breaks the focus swap to the search box in DAL (or Select2):

2c2
<  * jQuery JavaScript Library v3.5.1
---
>  * jQuery JavaScript Library v3.6.0
8c8
<  * Copyright JS Foundation and other contributors
---
>  * Copyright OpenJS Foundation and other contributors
12c12
<  * Date: 2020-05-04T22:49Z
---
>  * Date: 2021-03-02T17:08Z
79,84c79,88
<       // Support: Chrome <=57, Firefox <=52
<       // In some browsers, typeof returns "function" for HTML <object> elements
<       // (i.e., `typeof document.createElement( "object" ) === "function"`).
<       // We don't want to classify *any* DOM node as a function.
<       return typeof obj === "function" && typeof obj.nodeType !== "number";
<   };
---
>       // Support: Chrome <=57, Firefox <=52
>       // In some browsers, typeof returns "function" for HTML <object> elements
>       // (i.e., `typeof document.createElement( "object" ) === "function"`).
>       // We don't want to classify *any* DOM node as a function.
>       // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
>       // Plus for old WebKit, typeof returns "function" for HTML collections
>       // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
>       return typeof obj === "function" && typeof obj.nodeType !== "number" &&
>           typeof obj.item !== "function";
>   };
150c154
<   version = "3.5.1",
---
>   version = "3.6.0",
404c408
<                   [ arr ] : arr
---
>                       [ arr ] : arr
499,501c503,505
< function( _i, name ) {
<   class2type[ "[object " + name + "]" ] = name.toLowerCase();
< } );
---
>   function( _i, name ) {
>       class2type[ "[object " + name + "]" ] = name.toLowerCase();
>   } );
521c525
<  * Sizzle CSS Selector Engine v2.3.5
---
>  * Sizzle CSS Selector Engine v2.3.6
528c532
<  * Date: 2020-03-14
---
>  * Date: 2021-02-16
1111,1112c1115,1116
<   var namespace = elem.namespaceURI,
<       docElem = ( elem.ownerDocument || elem ).documentElement;
---
>   var namespace = elem && elem.namespaceURI,
>       docElem = elem && ( elem.ownerDocument || elem ).documentElement;
3027c3031
<   return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
---
>   return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
3029c3033
< };
---
> }
4000,4001c4004,4005
<           // the master Deferred
<           master = jQuery.Deferred(),
---
>           // the primary Deferred
>           primary = jQuery.Deferred(),
4009c4013
<                       master.resolveWith( resolveContexts, resolveValues );
---
>                       primary.resolveWith( resolveContexts, resolveValues );
4016c4020
<           adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
---
>           adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
4020c4024
<           if ( master.state() === "pending" ||
---
>           if ( primary.state() === "pending" ||
4023c4027
<               return master.then();
---
>               return primary.then();
4029c4033
<           adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
---
>           adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
4032c4036
<       return master.promise();
---
>       return primary.promise();
4183,4184c4187,4188
<                   value :
<                   value.call( elems[ i ], i, fn( elems[ i ], key ) )
---
>                       value :
>                       value.call( elems[ i ], i, fn( elems[ i ], key ) )
5092,5095c5096
< var
<   rkeyEvent = /^key/,
<   rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
<   rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
---
> var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5390,5391c5391,5392
<                   dataPriv.get( this, "events" ) || Object.create( null )
<               )[ event.type ] || [],
---
>               dataPriv.get( this, "events" ) || Object.create( null )
>           )[ event.type ] || [],
5515c5516
<                           return hook( this.originalEvent );
---
>                       return hook( this.originalEvent );
5520c5521
<                           return this.originalEvent[ name ];
---
>                       return this.originalEvent[ name ];
5659c5660,5666
<                       return result.value;
---
> 
>                       // Support: Chrome 86+
>                       // In Chrome, if an element having a focusout handler is blurred by
>                       // clicking outside of it, it invokes the handler synchronously. If
>                       // that handler calls `.remove()` on the element, the data is cleared,
>                       // leaving `result` undefined. We need to guard against this.
>                       return result && result.value;
5824,5851c5831
< 
<   which: function( event ) {
<       var button = event.button;
< 
<       // Add which for key events
<       if ( event.which == null && rkeyEvent.test( event.type ) ) {
<           return event.charCode != null ? event.charCode : event.keyCode;
<       }
< 
<       // Add which for click: 1 === left; 2 === middle; 3 === right
<       if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
<           if ( button & 1 ) {
<               return 1;
<           }
< 
<           if ( button & 2 ) {
<               return 3;
<           }
< 
<           if ( button & 4 ) {
<               return 2;
<           }
< 
<           return 0;
<       }
< 
<       return event.which;
<   }
---
>   which: true
5876a5857,5862
>       // Suppress native focus or blur as it's already being fired
>       // in leverageNative.
>       _default: function() {
>           return true;
>       },
> 
6543a6530,6533
>       //
>       // Support: Firefox 70+
>       // Only Firefox includes border widths
>       // in computed dimensions. (gh-4529)
6551c6541,6546
<               table.style.cssText = "position:absolute;left:-11111px";
---
>               table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
>               tr.style.cssText = "border:1px solid";
> 
>               // Support: Chrome 86+
>               // Height set through cssText does not get applied.
>               // Computed height then comes back as 0.
6554a6550,6557
>               // Support: Android 8 Chrome 86+
>               // In our bodyBackground.html iframe,
>               // display for all div elements is set to "inline",
>               // which causes a problem only in Android 8 Chrome 86.
>               // Ensuring the div is display: block
>               // gets around this issue.
>               trChild.style.display = "block";
> 
6561c6564,6566
<               reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
---
>               reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
>                   parseInt( trStyle.borderTopWidth, 10 ) +
>                   parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
7025,7028c7030,7033
<                       swap( elem, cssShow, function() {
<                           return getWidthOrHeight( elem, dimension, extra );
<                       } ) :
<                       getWidthOrHeight( elem, dimension, extra );
---
>                   swap( elem, cssShow, function() {
>                       return getWidthOrHeight( elem, dimension, extra );
>                   } ) :
>                   getWidthOrHeight( elem, dimension, extra );
7087c7092
<               ) + "px";
---
>           ) + "px";
7226c7231
<                   jQuery.cssHooks[ tween.prop ] ||
---
>               jQuery.cssHooks[ tween.prop ] ||
7471c7476
<           /* eslint-enable no-loop-func */
---
>               /* eslint-enable no-loop-func */
7591c7596
<                       animation.opts.specialEasing[ prop ] || animation.opts.easing );
---
>                   animation.opts.specialEasing[ prop ] || animation.opts.easing );
7764c7769,7770
<           doAnimation.finish = doAnimation;
---
> 
>       doAnimation.finish = doAnimation;
8404,8405c8410,8411
<                       "" :
<                       dataPriv.get( this, "__className__" ) || ""
---
>                           "" :
>                           dataPriv.get( this, "__className__" ) || ""
8420c8426
<                   return true;
---
>               return true;
8710,8712c8716
<           handle = (
<                   dataPriv.get( cur, "events" ) || Object.create( null )
<               )[ event.type ] &&
---
>           handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
8859c8863
<   var xml;
---
>   var xml, parserErrorElem;
8868,8870c8872
<   } catch ( e ) {
<       xml = undefined;
<   }
---
>   } catch ( e ) {}
8872,8873c8874,8882
<   if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
<       jQuery.error( "Invalid XML: " + data );
---
>   parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
>   if ( !xml || parserErrorElem ) {
>       jQuery.error( "Invalid XML: " + (
>           parserErrorElem ?
>               jQuery.map( parserErrorElem.childNodes, function( el ) {
>                   return el.textContent;
>               } ).join( "\n" ) :
>               data
>       ) );
8974,8975c8983
<       } )
<       .filter( function() {
---
>       } ).filter( function() {
8982,8983c8990
<       } )
<       .map( function( _i, elem ) {
---
>       } ).map( function( _i, elem ) {
9036c9043,9044
<   originAnchor.href = location.href;
---
> 
> originAnchor.href = location.href;
9417,9418c9425,9426
<                   jQuery( callbackContext ) :
<                   jQuery.event,
---
>               jQuery( callbackContext ) :
>               jQuery.event,
9730,9731c9738,9741
<           // Use a noop converter for missing script
<           if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
---
>           // Use a noop converter for missing script but not if jsonp
>           if ( !isSuccess &&
>               jQuery.inArray( "script", s.dataTypes ) > -1 &&
>               jQuery.inArray( "json", s.dataTypes ) < 0 ) {
10469,10474d10478
<           if ( typeof props.top === "number" ) {
<               props.top += "px";
<           }
<           if ( typeof props.left === "number" ) {
<               props.left += "px";
<           }
10643,10644c10647,10651
<   jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
<       function( defaultExtra, funcName ) {
---
>   jQuery.each( {
>       padding: "inner" + name,
>       content: type,
>       "": "outer" + name
>   }, function( defaultExtra, funcName ) {
10729c10736,10737
< jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
---
> jQuery.each(
>   ( "blur focus focusin focusout resize scroll click dblclick " +
10740c10748,10749
<   } );
---
>   }
> );

Kudos to anyone who can spot what the breaking change is ;-)

I'm going to take a punt and suggest this as a prime candidate:

5876a5857,5862
>       // Suppress native focus or blur as it's already being fired
>       // in leverageNative.
>       _default: function() {
>           return true;
>       },
> 

Though it's a feeble guess at present.

medaglia commented 2 years ago

I've had the same issue. Doing some more research (and thanks to the excellent findings of @bernd-wechner), I've learned this is a known bug with select2 and jquery 3.6.

For anyone else having the same issue: while waiting for the fix, you can find some hacks/workarounds in that thread that may work for you. Like this one, for example.

sonarun commented 1 year ago

jQuery 3.7 is now out and replacing jquery fixes the issue for me. https://github.com/select2/select2/issues/5993

https://github.com/jquery/jquery/releases/tag/3.7.0