How to catch all `select2:open` events in the Django 4 admin site?
I just can't seem to catch the select2:open
events that should be triggered by Select2 dropdowns used by Django ForeignKey
fields with the autocomplete feature enabled.
Here is the code I'm currently running to catch those events (I am trying to automatically set the focus to the child search bar whenever a Select2 is open):
-- autofocus_select2_searchbars.js
/**
* Add an event listener to all the select2 widgets on the page so that
* when they are opened, the search input is automatically focused.
*/
function setFocusOnSearchBarsWhenSelect2WidgetsAreOpen() {
console.log('setFocusOnSearchBarsWhenSelect2WidgetsAreOpen');
$(document).on('select2:open', () => {
console.log('select2:open');
document.querySelector('.select2-container--open .select2-search__field').focus();
});
}
$(document).ready(function () {
setFocusOnSearchBarsWhenSelect2WidgetsAreOpen();
});
and I am calling this in change_form.html
so it gets applied to every change view in the admin:
-- myproject/templates/admin/change_form.html
{% extends "admin/change_form.html" %}
{% load i18n admin_urls static %}
{% block admin_change_form_document_ready %}
{{ block.super }}
<script src="https://code.jquery.com/jquery-3.6.3.slim.min.js" integrity="sha256-ZwqZIVdD3iXNyGHbSYdsmWP//UBokj2FHAxKuSBKDSo=" crossorigin="anonymous"></script>
<script>
{% include "./shared/autofocus_select2_searchbars.js" %}
</script>
{% endblock admin_change_form_document_ready %}
The problem is that the select2:open
event never gets fired.
The problem lied in the inclusion of jQuery on my own with the CDN import in change_form.html
:
<script src="https://code.jquery.com/jquery-3.6.3.slim.min.js" integrity="sha256-ZwqZIVdD3iXNyGHbSYdsmWP//UBokj2FHAxKuSBKDSo=" crossorigin="anonymous"></script>
The Select2 widgets used by Django are initialised using a bundled version of jQuery within Django and the jQuery events fired by those initialised Select2 widgets are processed by that very same jQuery instance.
So the solution is simply to remove the CDN import of jQuery and use the django bundled instance instead. After removing the CDN import, I just added the following declaration at the top of autofocus_select2_searchbars.js
:
const $ = django.jQuery;
the django
variable being available because we extend admin/change_form.html
.