@@ -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