From 4c30cab7c1500cadb15f71f212f53b4b7fd2ba93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 19 Oct 2025 00:34:31 +0200 Subject: [PATCH] Do not change the dropdownParent of tomselect if it is inside a modal This ensures that it is properly displayed. Fixes issue #1073 --- .../elements/attachment_autocomplete_controller.js | 7 ++++++- assets/controllers/elements/part_select_controller.js | 8 +++++++- assets/controllers/elements/select_controller.js | 6 +++++- assets/controllers/elements/select_multiple_controller.js | 7 ++++++- .../elements/static_file_autocomplete_controller.js | 7 ++++++- .../elements/structural_entity_select_controller.js | 7 +++++-- assets/controllers/elements/tagsinput_controller.js | 7 ++++++- 7 files changed, 41 insertions(+), 8 deletions(-) diff --git a/assets/controllers/elements/attachment_autocomplete_controller.js b/assets/controllers/elements/attachment_autocomplete_controller.js index 0175b284..94b01136 100644 --- a/assets/controllers/elements/attachment_autocomplete_controller.js +++ b/assets/controllers/elements/attachment_autocomplete_controller.js @@ -34,6 +34,11 @@ export default class extends Controller { connect() { + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } + let settings = { persistent: false, create: true, @@ -42,7 +47,7 @@ export default class extends Controller { selectOnTab: true, //This a an ugly solution to disable the delimiter parsing of the TomSelect plugin delimiter: 'VERY_L0NG_D€LIMITER_WHICH_WILL_NEVER_BE_ENCOUNTERED_IN_A_STRING', - dropdownParent: 'body', + dropdownParent: dropdownParent, render: { item: (data, escape) => { return '' + escape(data.label) + ''; diff --git a/assets/controllers/elements/part_select_controller.js b/assets/controllers/elements/part_select_controller.js index 0658f4b4..8a4e19b8 100644 --- a/assets/controllers/elements/part_select_controller.js +++ b/assets/controllers/elements/part_select_controller.js @@ -10,13 +10,19 @@ export default class extends Controller { connect() { + //Check if tomselect is inside an modal and do not attach the dropdown to body in that case (as it breaks the modal) + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } + let settings = { allowEmptyOption: true, plugins: ['dropdown_input'], searchField: ["name", "description", "category", "footprint"], valueField: "id", labelField: "name", - dropdownParent: 'body', + dropdownParent: dropdownParent, preload: "focus", render: { item: (data, escape) => { diff --git a/assets/controllers/elements/select_controller.js b/assets/controllers/elements/select_controller.js index f933731a..d70e588c 100644 --- a/assets/controllers/elements/select_controller.js +++ b/assets/controllers/elements/select_controller.js @@ -38,13 +38,17 @@ export default class extends Controller { this._emptyMessage = this.element.getAttribute('title'); } + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } let settings = { plugins: ["clear_button"], allowEmptyOption: true, selectOnTab: true, maxOptions: null, - dropdownParent: 'body', + dropdownParent: dropdownParent, render: { item: this.renderItem.bind(this), diff --git a/assets/controllers/elements/select_multiple_controller.js b/assets/controllers/elements/select_multiple_controller.js index daa6b0a1..17e85fae 100644 --- a/assets/controllers/elements/select_multiple_controller.js +++ b/assets/controllers/elements/select_multiple_controller.js @@ -26,10 +26,15 @@ export default class extends Controller { _tomSelect; connect() { + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } + this._tomSelect = new TomSelect(this.element, { maxItems: 1000, allowEmptyOption: true, - dropdownParent: 'body', + dropdownParent: dropdownParent, plugins: ['remove_button'], }); } diff --git a/assets/controllers/elements/static_file_autocomplete_controller.js b/assets/controllers/elements/static_file_autocomplete_controller.js index 0421a26d..9703c618 100644 --- a/assets/controllers/elements/static_file_autocomplete_controller.js +++ b/assets/controllers/elements/static_file_autocomplete_controller.js @@ -40,6 +40,11 @@ export default class extends Controller { connect() { + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } + let settings = { persistent: false, create: true, @@ -50,7 +55,7 @@ export default class extends Controller { valueField: 'text', searchField: 'text', orderField: 'text', - dropdownParent: 'body', + dropdownParent: dropdownParent, //This a an ugly solution to disable the delimiter parsing of the TomSelect plugin delimiter: 'VERY_L0NG_D€LIMITER_WHICH_WILL_NEVER_BE_ENCOUNTERED_IN_A_STRING', diff --git a/assets/controllers/elements/structural_entity_select_controller.js b/assets/controllers/elements/structural_entity_select_controller.js index 5c6f9490..4b220d5b 100644 --- a/assets/controllers/elements/structural_entity_select_controller.js +++ b/assets/controllers/elements/structural_entity_select_controller.js @@ -40,7 +40,10 @@ export default class extends Controller { const allowAdd = this.element.getAttribute("data-allow-add") === "true"; const addHint = this.element.getAttribute("data-add-hint") ?? ""; - + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } let settings = { @@ -54,7 +57,7 @@ export default class extends Controller { maxItems: 1, delimiter: "$$VERY_LONG_DELIMITER_THAT_SHOULD_NEVER_APPEAR$$", splitOn: null, - dropdownParent: 'body', + dropdownParent: dropdownParent, searchField: [ {field: "text", weight : 2}, diff --git a/assets/controllers/elements/tagsinput_controller.js b/assets/controllers/elements/tagsinput_controller.js index 53bf7608..14725227 100644 --- a/assets/controllers/elements/tagsinput_controller.js +++ b/assets/controllers/elements/tagsinput_controller.js @@ -33,6 +33,11 @@ export default class extends Controller { _tomSelect; connect() { + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } + let settings = { plugins: { remove_button:{}, @@ -43,7 +48,7 @@ export default class extends Controller { selectOnTab: true, createOnBlur: true, create: true, - dropdownParent: 'body', + dropdownParent: dropdownParent, }; if(this.element.dataset.autocomplete) {