diff options
Diffstat (limited to 'web_src/js/modules/fomantic')
-rw-r--r-- | web_src/js/modules/fomantic/dropdown.ts | 8 | ||||
-rw-r--r-- | web_src/js/modules/fomantic/modal.ts | 34 |
2 files changed, 38 insertions, 4 deletions
diff --git a/web_src/js/modules/fomantic/dropdown.ts b/web_src/js/modules/fomantic/dropdown.ts index 0360b8ef95..ccc22073d7 100644 --- a/web_src/js/modules/fomantic/dropdown.ts +++ b/web_src/js/modules/fomantic/dropdown.ts @@ -9,9 +9,9 @@ const fomanticDropdownFn = $.fn.dropdown; // use our own `$().dropdown` function to patch Fomantic's dropdown module export function initAriaDropdownPatch() { if ($.fn.dropdown === ariaDropdownFn) throw new Error('initAriaDropdownPatch could only be called once'); - $.fn.dropdown.settings.onAfterFiltered = onAfterFiltered; $.fn.dropdown = ariaDropdownFn; $.fn.fomanticExt.onResponseKeepSelectedItem = onResponseKeepSelectedItem; + $.fn.fomanticExt.onDropdownAfterFiltered = onDropdownAfterFiltered; (ariaDropdownFn as FomanticInitFunction).settings = fomanticDropdownFn.settings; } @@ -71,11 +71,11 @@ function updateSelectionLabel(label: HTMLElement) { } } -function onAfterFiltered(this: any) { - const $dropdown = $(this); +function onDropdownAfterFiltered(this: any) { + const $dropdown = $(this).closest('.ui.dropdown'); // "this" can be the "ui dropdown" or "<select>" const hideEmptyDividers = $dropdown.dropdown('setting', 'hideDividers') === 'empty'; const itemsMenu = $dropdown[0].querySelector('.scrolling.menu') || $dropdown[0].querySelector('.menu'); - if (hideEmptyDividers) hideScopedEmptyDividers(itemsMenu); + if (hideEmptyDividers && itemsMenu) hideScopedEmptyDividers(itemsMenu); } // delegate the dropdown's template functions and callback functions to add aria attributes. diff --git a/web_src/js/modules/fomantic/modal.ts b/web_src/js/modules/fomantic/modal.ts index 6a2c558890..a96c7785e1 100644 --- a/web_src/js/modules/fomantic/modal.ts +++ b/web_src/js/modules/fomantic/modal.ts @@ -1,5 +1,7 @@ import $ from 'jquery'; import type {FomanticInitFunction} from '../../types.ts'; +import {queryElems} from '../../utils/dom.ts'; +import {hideToastsFrom} from '../toast.ts'; const fomanticModalFn = $.fn.modal; @@ -8,6 +10,8 @@ export function initAriaModalPatch() { if ($.fn.modal === ariaModalFn) throw new Error('initAriaModalPatch could only be called once'); $.fn.modal = ariaModalFn; (ariaModalFn as FomanticInitFunction).settings = fomanticModalFn.settings; + $.fn.fomanticExt.onModalBeforeHidden = onModalBeforeHidden; + $.fn.modal.settings.onApprove = onModalApproveDefault; } // the patched `$.fn.modal` modal function @@ -27,3 +31,33 @@ function ariaModalFn(this: any, ...args: Parameters<FomanticInitFunction>) { } return ret; } + +function onModalBeforeHidden(this: any) { + const $modal = $(this); + const elModal = $modal[0]; + hideToastsFrom(elModal.closest('.ui.dimmer') ?? document.body); + + // reset the form after the modal is hidden, after other modal events and handlers (e.g. "onApprove", form submit) + setTimeout(() => { + queryElems(elModal, 'form', (form: HTMLFormElement) => form.reset()); + }, 0); +} + +function onModalApproveDefault(this: any) { + const $modal = $(this); + const selectors = $modal.modal('setting', 'selector'); + const elModal = $modal[0]; + const elApprove = elModal.querySelector(selectors.approve); + const elForm = elApprove?.closest('form'); + if (!elForm) return true; // no form, just allow closing the modal + + // "form-fetch-action" can handle network errors gracefully, + // so keep the modal dialog to make users can re-submit the form if anything wrong happens. + if (elForm.matches('.form-fetch-action')) return false; + + // There is an abuse for the "modal" + "form" combination, the "Approve" button is a traditional form submit button in the form. + // Then "approve" and "submit" occur at the same time, the modal will be closed immediately before the form is submitted. + // So here we prevent the modal from closing automatically by returning false, add the "is-loading" class to the form element. + elForm.classList.add('is-loading'); + return false; +} |