From 4b734ebacacf73e075c4e80e95e770d12113401f Mon Sep 17 00:00:00 2001 From: Paul Derscheid Date: Tue, 23 Sep 2025 08:22:53 +0000 Subject: [PATCH] Bug 40857: add context parameter for modal overlay - The combobox dropdown in modals scrolled with the modal body instead of overlaying, due to Bootstrap's overflow: hidden on modals clipping extending content. - Added context parameter to combobox config; setting context: 'modal' uses Popper's fixed positioning strategy for proper overlay. - For reference: https://popper.js.org/docs/v2/constructors/#strategy To test: 1. Make an item bookable 1.1. Go to a record (e.g. http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=285) 1.2. Go to the Items tab on the left side of the screen 1.3. Under Bookable, choose Yes and click 'Update' 2. Place a booking 2.1. Click 'Place booking' at the top of the detailed record screen 2.2. Fill out the form 2.3. Click 'Submit' 3. Try to cancel the booking 3.1. Go to the 'Bookings' tab on the left side of the screen 3.2. Click 'Cancel' next to the booking --> A modal appears with a text field for the cancellation reason 3.3. Click 'No, do not cancel' 4. Add one authorised value in BOOKING_CANCELLATION 4.1. Go to Administration > Authorized values 4.2. Search for BOOKING_CANCELLATION 4.3. Click 'Add' 4.4. Fill out the form 4.5. Click 'Save' 5. Redo step 3 --> The option appears as a dropdown below the text field -- OK 6. Add one or two more authorised values 7. Redo step 3 --> The options appear as a dropdown below the text field -- OK Signed-off-by: Caroline Cyr La Rose Signed-off-by: Martin Renvoize Signed-off-by: Lucas Gass (cherry picked from commit f6df86c170fca95b75af056beae0f3872ce23371) Signed-off-by: Paul Derscheid --- .../prog/en/modules/bookings/list.tt | 1 + .../prog/en/modules/circ/circulation.tt | 1 + .../prog/en/modules/members/moremember.tt | 1 + koha-tmpl/intranet-tmpl/prog/js/combobox.js | 16 +++++++++++++--- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt index 509c80e491..3a583d03be 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt @@ -432,6 +432,7 @@ $("#cancellation-reason").comboBox({ displayProperty: 'name', placeholder: _("Select or type a reason"), + context: 'modal', }); }); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 29aa6532b9..388d30d7eb 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -1247,6 +1247,7 @@ $("#cancellation-reason").comboBox({ displayProperty: 'name', placeholder: _("Select or type a reason"), + context: 'modal', }); }); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt index cdb10f8e48..4c0b7f7392 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -855,6 +855,7 @@ $("#cancellation-reason").comboBox({ displayProperty: 'name', placeholder: _("Select or type a reason"), + context: 'modal', }); }); diff --git a/koha-tmpl/intranet-tmpl/prog/js/combobox.js b/koha-tmpl/intranet-tmpl/prog/js/combobox.js index 813b649849..c7ad9d2efe 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/combobox.js +++ b/koha-tmpl/intranet-tmpl/prog/js/combobox.js @@ -11,6 +11,7 @@ * @param {boolean} [config.useKeyAsValue=false] - Whether to use the option's key (either HTML data-* or JavaScript `valueProperty`) as the value of the input (default: false). * @param {string} [config.placeholder='Select or type a value'] - Placeholder text for the input element. * @param {string} [config.labelId=''] - Optional ID of the associated label element. + * @param {string} [config.context='default'] - Positioning context ('default' or 'modal'). * * @example * ```html @@ -35,9 +36,10 @@ * displayProperty: 'name', * valueProperty: 'id', * useKeyAsValue: true, + * context: 'modal', * }); * // or using jQuery - * $("#generic-combobox").comboBox({ ... }); + * $("#generic-combobox").comboBox({ displayProperty: 'name', context: 'modal' }); * * ``` */ @@ -51,6 +53,7 @@ placeholder = "Select or type a value", labelId = "", useKeyAsValue = false, + context = "default", } = config; const input = document.getElementById(inputId); @@ -60,9 +63,16 @@ return; } - const bootstrapDropdown = new bootstrap.Dropdown(input, { + const dropdownOptions = { autoClose: false, - }); + popperConfig: { + strategy: { default: "absolute", modal: "fixed" }[context], + }, + }; + const bootstrapDropdown = new bootstrap.Dropdown( + input, + dropdownOptions + ); // Existing options from HTML const existingOptions = Array.from(dropdownMenu.querySelectorAll("li"))