Skip to content

Commit e269521

Browse files
committed
Restore long-lost form-handling ability to modal.js interactivity in modal dialog
1 parent 8c1d0e1 commit e269521

File tree

1 file changed

+40
-1
lines changed
  • app/javascript/blacklight-frontend

1 file changed

+40
-1
lines changed

app/javascript/blacklight-frontend/modal.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const Modal = (() => {
6262
// Trigger selectors identify forms or hyperlinks that should open
6363
// inside a modal dialog.
6464
modal.triggerLinkSelector = 'a[data-blacklight-modal~=trigger]';
65+
modal.triggerformSelector = 'form[data-blacklight-modal~=trigger]';
6566

6667
// preserve selectors identify forms or hyperlinks that, if activated already
6768
// inside a modal dialog, should have destinations remain inside the modal -- but
@@ -71,6 +72,7 @@ const Modal = (() => {
7172
// be preserved. MUST be manually prefixed with the modal selector,
7273
// so they only apply to things inside a modal.
7374
modal.preserveLinkSelector = modal.modalSelector + ' a[data-blacklight-modal~=preserve]';
75+
modal.preserveFormSelector = modal.modalSelector + ' form[data-blacklight-modal~=preserve]';
7476

7577
modal.containerSelector = '[data-blacklight-modal~=container]';
7678

@@ -145,6 +147,35 @@ const Modal = (() => {
145147
.catch(error => modal.onFailure(error))
146148
};
147149

150+
modal.modalAjaxFormSubmit = function(e) {
151+
e.preventDefault();
152+
153+
const closest = e.target.closest(`${modal.triggerFormSelector}, ${modal.preserveFormSelector}`);
154+
155+
const method = (closest.getAttribute("method") || "GET").toUpperCase();
156+
const formData = new FormData(closest);
157+
const formAction = closest.getAttribute('action');
158+
159+
const href = (method == "GET") ? `${ formAction }?${ new URLSearchParams(formData).toString() }` : formAction;
160+
const fetchArgs = {
161+
headers: { 'X-Requested-With': 'XMLHttpRequest' }
162+
}
163+
if (method != "GET") {
164+
fetchArgs.body = formData;
165+
fetchArgs.method = method;
166+
}
167+
168+
fetch(href, fetchArgs)
169+
.then(response => {
170+
if (!response.ok) {
171+
throw new TypeError("Request failed");
172+
}
173+
return response.text();
174+
})
175+
.then(data => modal.receiveAjax(data))
176+
.catch(error => modal.onFailure(error));
177+
}
178+
148179
modal.setupModal = function() {
149180
// Register several click handlers in ONE event handler for efficiency
150181
//
@@ -154,8 +185,16 @@ const Modal = (() => {
154185
document.addEventListener('click', (e) => {
155186
if (e.target.closest(`${modal.triggerLinkSelector}, ${modal.preserveLinkSelector}`))
156187
modal.modalAjaxLinkClick(e)
157-
else if (e.target.matches(`${modal.modalSelector}`) || e.target.closest('[data-bl-dismiss="modal"]'))
188+
else if (e.target.matches(`${modal.modalSelector}`) || e.target.closest('[data-bl-dismiss="modal"]')) {
189+
e.preventDefault()
158190
modal.hide()
191+
}
192+
})
193+
194+
document.addEventListener('submit', (e) => {
195+
if (e.target.closest(`${modal.triggerFormSelector}, ${modal.preserveFormSelector}`)) {
196+
modal.modalAjaxFormSubmit(e)
197+
}
159198
})
160199

161200
// Make sure user-agent dismissal of html 'dialog', etc `esc` key, triggers

0 commit comments

Comments
 (0)