aboutsummaryrefslogtreecommitdiffstats
path: root/web_src/js/modules/fomantic
diff options
context:
space:
mode:
Diffstat (limited to 'web_src/js/modules/fomantic')
-rw-r--r--web_src/js/modules/fomantic/dropdown.ts8
-rw-r--r--web_src/js/modules/fomantic/modal.ts34
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;
+}