diff --git a/public/css/select2-overrides.css b/public/css/select2-overrides.css index 4f87450ef..8fe4c77d8 100644 --- a/public/css/select2-overrides.css +++ b/public/css/select2-overrides.css @@ -193,12 +193,15 @@ span.select2.select2-container .select2-selection__choice__remove:hover { /* Custom class to support styling to show clickable choice options */ .select2_choice_clickable+span.select2-container .select2-selection__choice__display { cursor: pointer; +} +.select2_choice_clickable_buttonstyle+span.select2-container .select2-selection__choice__display { + cursor: pointer; transition: background-color 0.3s; color: var(--SmartThemeBodyColor); background-color: var(--black50a); } -.select2_choice_clickable+span.select2-container .select2-selection__choice__display:hover { +.select2_choice_clickable_buttonstyle+span.select2-container .select2-selection__choice__display:hover { background-color: var(--white30a); } @@ -240,4 +243,4 @@ span.select2.select2-container .select2-selection__choice__remove:hover { .select2_multi_sameline+span.select2-container.select2-container--focus .select2-selection--multiple .select2-search--inline { height: unset; -} \ No newline at end of file +} diff --git a/public/scripts/utils.js b/public/scripts/utils.js index aef6d33f5..0ab518f5d 100644 --- a/public/scripts/utils.js +++ b/public/scripts/utils.js @@ -1531,16 +1531,20 @@ export function dynamicSelect2DataViaAjax(dataProvider) { * @param {JQuery} control The original control the select2 was applied to * @param {function(EventTarget):void} action - The action to execute when a choice element is clicked * @param {object} options - Optional parameters + * @param {boolean} [options.buttonStyle=false] - Whether the choices should be styles as a clickable button with color and hover transition, instead of just changed cursor * @param {boolean} [options.closeDrawer=false] - Whether the drawer should be closed and focus removed after the choice item was clicked + * @param {boolean} [options.openDrawer=false] - Whether the drawer should be opened, even if this click would normally close it */ -export function select2ChoiceClickSubscribe(control, action, { closeDrawer = false } = {}) { +export function select2ChoiceClickSubscribe(control, action, { buttonStyle = false, closeDrawer = false, openDrawer = false } = {}) { // Add class for styling (hover color, changed cursor, etc) control.addClass('select2_choice_clickable'); + if (buttonStyle) control.addClass('select2_choice_clickable_buttonstyle'); // Get the real container below and create a click handler on that one const select2Container = control.next('span.select2-container'); select2Container.on('click', function (event) { - if ($(event.target).hasClass('select2-selection__choice__display')) { + const $target = $(event.target); + if ($target.hasClass('select2-selection__choice__display') || $target.parents('.select2-selection__choice__display')) { event.preventDefault(); // select2 still bubbles the event to open the dropdown. So we close it here and remove focus if we want that @@ -1548,6 +1552,9 @@ export function select2ChoiceClickSubscribe(control, action, { closeDrawer = fal control.select2('close'); setTimeout(() => select2Container.find('textarea').trigger('blur'), debounce_timeout.quick); } + if (openDrawer) { + control.select2('open'); + } // Now execute the actual action that was subscribed action(event.target); diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index 23224bffa..0e1cd89cd 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -1338,7 +1338,7 @@ function getWorldEntry(name, data, entry) { }); function templateStyling(/** @type {Select2Option} */ item, { searchStyle = false } = {}) { - const content = $('').addClass('item').text(item.text); + const content = $('').addClass('item').text(item.text).attr('title', `${item.text}\n\nClick to edit`); const isRegex = isValidRegex(item.text); if (isRegex) { content.html(highlightRegex(item.text)); @@ -1381,6 +1381,24 @@ function getWorldEntry(name, data, entry) { input.on('select2:select', /** @type {function(*):void} */ event => updateWorldEntryKeyOptionsCache([event.params.data])); input.on('select2:unselect', /** @type {function(*):void} */ event => updateWorldEntryKeyOptionsCache([event.params.data], { remove: true })); + select2ChoiceClickSubscribe(input, target => { + const key = $(target).text(); + console.debug('Editing WI key', key); + + // Remove the current key from the actual selection + const selected = input.val(); + if (!Array.isArray(selected)) return; + var index = selected.indexOf(getSelect2OptionId(key)); + if (index > -1) selected.splice(index, 1); + input.val(selected).trigger('change'); + // Manually update the cache, that change event is not gonna trigger it + updateWorldEntryKeyOptionsCache([key], { remove: true }) + + // We need to "hack" the actual text input into the currently open textarea + input.next('span.select2-container').find('textarea') + .val(key).trigger('input'); + }, { openDrawer: true }); + select2ModifyOptions(input, entry[entryPropName], { select: true, changeEventArgs: { skipReset: true, noSave: true } }); } else { @@ -3525,14 +3543,14 @@ jQuery(() => { }); // Subscribe world loading to the select2 multiselect items (We need to target the specific select2 control) - select2ChoiceClickSubscribe($('#world_info'), (target) => { + select2ChoiceClickSubscribe($('#world_info'), target => { const name = $(target).text(); const selectedIndex = world_names.indexOf(name); if (selectedIndex !== -1) { $('#world_editor_select').val(selectedIndex).trigger('change'); console.log('Quick selection of world', name); } - }, { closeDrawer: true }); + }, { buttonStyle: true, closeDrawer: true }); } $('#WorldInfo').on('scroll', () => {