From ea4f36682405f3f20c0887d38d85edfbbc26dc2a Mon Sep 17 00:00:00 2001 From: Drikus Roor Date: Mon, 2 Dec 2024 15:09:42 +0100 Subject: [PATCH] fix(django-select2): Add re-initialization for django-select2 on form change to handle new inlines (#1409) --- backend/experiment/static/experiment_form.js | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/backend/experiment/static/experiment_form.js b/backend/experiment/static/experiment_form.js index 95c2a4c77..830bf29b6 100644 --- a/backend/experiment/static/experiment_form.js +++ b/backend/experiment/static/experiment_form.js @@ -1,6 +1,10 @@ document.addEventListener("DOMContentLoaded", function () { initCollapsibleInlineForms(); floatingSubmitRow(); + + // TODO: Remove this in the future once the issue is fixed in django-select2 + // re-initialize django-select2 on form change + reinitializeDjangoSelect2OnFormChange(); }); function initCollapsibleInlineForms() { @@ -60,3 +64,43 @@ function floatingSubmitRow() { } }); } +/** + * Re-initialize django-select2 on form change. + * This is needed because django-select2 is not re-initialized on new inlines. + * Let's check again in the future if this issue is fixed in django-select2 + * and remove this function. + * See also: https://github.com/codingjoe/django-select2/pull/300 + * @returns {void} + */ +function reinitializeDjangoSelect2OnFormChange() { + + const $ = django.jQuery; + + return $(function () { + $('.django-select2').djangoSelect2() + + // This part fixes new inlines not having the correct select2 widgets + function handleFormsetAdded(row, formsetName) { + // Converting to the "normal jQuery" + var jqRow = django.jQuery(row) + + // Because select2 was already instantiated on the empty form, we need to remove it, destroy the instance, + // and re-instantiate it. + jqRow.find('.django-select2').parent().find('.select2-container').remove() + jqRow.find('.django-select2').djangoSelect2('destroy'); + jqRow.find('.django-select2').djangoSelect2() + } + + // See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/javascript/#supporting-versions-of-django-older-than-4-1 + django.jQuery(document).on('formset:added', function (event, $row, formsetName) { + if (event.detail && event.detail.formsetName) { + // Django >= 4.1 + handleFormsetAdded(event.target, event.detail.formsetName) + } else { + // Django < 4.1, use $row and formsetName + handleFormsetAdded($row.get(0), formsetName) + } + }) + // End of fix + }) +}