Fully ajaxified modals
This commit is contained in:
parent
a627b7be72
commit
213f3a39cc
@ -261,27 +261,20 @@ postHelpR = do
|
|||||||
|
|
||||||
((res,formWidget),formEnctype) <- runFormPost $ renderAForm FormStandard $ helpForm mReferer mUid
|
((res,formWidget),formEnctype) <- runFormPost $ renderAForm FormStandard $ helpForm mReferer mUid
|
||||||
|
|
||||||
case res of
|
formResultModal res HelpR $ \HelpForm{..} -> do
|
||||||
FormSuccess HelpForm{..} -> do
|
now <- liftIO getCurrentTime
|
||||||
now <- liftIO getCurrentTime
|
hfReferer' <- traverse toTextUrl hfReferer
|
||||||
hfReferer' <- traverse toTextUrl hfReferer
|
queueJob' JobHelpRequest
|
||||||
queueJob' JobHelpRequest
|
{ jSender = hfUserId
|
||||||
{ jSender = hfUserId
|
, jHelpRequest = hfRequest
|
||||||
, jHelpRequest = hfRequest
|
, jRequestTime = now
|
||||||
, jRequestTime = now
|
, jReferer = hfReferer'
|
||||||
, jReferer = hfReferer'
|
}
|
||||||
}
|
tell . pure =<< messageI Success MsgHelpSent
|
||||||
-- redirect $ HelpR
|
|
||||||
addMessageI Success MsgHelpSent
|
|
||||||
return ()
|
|
||||||
{-selectRep $ do
|
|
||||||
provideJson ()
|
|
||||||
provideRep (redirect $ HelpR :: Handler Html) -}
|
|
||||||
FormMissing -> return ()
|
|
||||||
FormFailure errs -> mapM_ (addMessage Error . toHtml) errs
|
|
||||||
|
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitle "Hilfe" -- TODO: International
|
setTitle "Hilfe" -- TODO: International
|
||||||
|
isModal <- hasCustomHeader HeaderIsModal
|
||||||
$(widgetFile "help")
|
$(widgetFile "help")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
module Handler.Utils.Form
|
module Handler.Utils.Form
|
||||||
( module Handler.Utils.Form
|
( module Handler.Utils.Form
|
||||||
, module Utils.Form
|
, module Utils.Form
|
||||||
|
, MonadWriter(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Utils.Form
|
import Utils.Form
|
||||||
@ -35,6 +36,7 @@ import qualified Data.Set as Set
|
|||||||
import Data.Map (Map, (!))
|
import Data.Map (Map, (!))
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
|
import Control.Monad.Trans.Writer (execWriterT, WriterT)
|
||||||
import Control.Monad.Writer.Class
|
import Control.Monad.Writer.Class
|
||||||
|
|
||||||
import Data.Scientific (Scientific)
|
import Data.Scientific (Scientific)
|
||||||
@ -587,9 +589,16 @@ multiActionA FieldSettings{..} acts defAction = formToAForm $ do
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
formResultModal :: MonadHandler m => FormResult a -> (a -> m ()) -> m ()
|
formResultModal :: (MonadHandler m, RedirectUrl (HandlerSite m) route) => FormResult a -> route -> (a -> WriterT [Message] m ()) -> m ()
|
||||||
formResultModal res handler = do
|
formResultModal res finalDest handler = maybeT_ $ do
|
||||||
formResult res handler
|
messages <- case res of
|
||||||
whenM (hasCustomHeader HeaderIsModal) $ do
|
FormMissing -> mzero
|
||||||
messages <- mapM (\(cl, co) -> maybe (throwM $ UnknownMessageClass cl) (return . flip Message co) $ fromPathPiece cl) =<< getMessages
|
FormFailure errs -> return $ map (Message Error . toHtml) errs
|
||||||
sendResponse $ toJSON messages
|
FormSuccess val -> lift . execWriterT $ handler val
|
||||||
|
|
||||||
|
isModal <- hasCustomHeader HeaderIsModal
|
||||||
|
if
|
||||||
|
| isModal -> sendResponse $ toJSON messages
|
||||||
|
| otherwise -> do
|
||||||
|
forM_ messages $ \Message{..} -> addMessage messageClass messageContent
|
||||||
|
redirect finalDest
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
module Utils.Message
|
module Utils.Message
|
||||||
( MessageClass(..)
|
( MessageClass(..)
|
||||||
, UnknownMessageClass(..)
|
, UnknownMessageClass(..)
|
||||||
, Message(..)
|
|
||||||
, addMessage, addMessageI, addMessageIHamlet, addMessageFile, addMessageWidget
|
, addMessage, addMessageI, addMessageIHamlet, addMessageFile, addMessageWidget
|
||||||
|
, Message(..)
|
||||||
|
, messageI, messageIHamlet, messageFile, messageWidget
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
|
||||||
@ -67,12 +68,17 @@ instance FromJSON Message where
|
|||||||
return Message{..}
|
return Message{..}
|
||||||
|
|
||||||
|
|
||||||
addMessage :: MonadHandler m => MessageClass-> Html -> m ()
|
addMessage :: MonadHandler m => MessageClass -> Html -> m ()
|
||||||
addMessage mc = ClassyPrelude.Yesod.addMessage (toPathPiece mc)
|
addMessage mc = ClassyPrelude.Yesod.addMessage (toPathPiece mc)
|
||||||
|
|
||||||
addMessageI :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => MessageClass -> msg -> m ()
|
addMessageI :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => MessageClass -> msg -> m ()
|
||||||
addMessageI mc = ClassyPrelude.Yesod.addMessageI (toPathPiece mc)
|
addMessageI mc = ClassyPrelude.Yesod.addMessageI (toPathPiece mc)
|
||||||
|
|
||||||
|
messageI :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => MessageClass -> msg -> m Message
|
||||||
|
messageI messageClass msg = do
|
||||||
|
messageContent <- toHtml . ($ msg) <$> getMessageRender
|
||||||
|
return Message{..}
|
||||||
|
|
||||||
addMessageIHamlet :: ( MonadHandler m
|
addMessageIHamlet :: ( MonadHandler m
|
||||||
, RenderMessage (HandlerSite m) msg
|
, RenderMessage (HandlerSite m) msg
|
||||||
, HandlerSite m ~ site
|
, HandlerSite m ~ site
|
||||||
@ -81,9 +87,20 @@ addMessageIHamlet mc iHamlet = do
|
|||||||
mr <- getMessageRender
|
mr <- getMessageRender
|
||||||
ClassyPrelude.Yesod.addMessage (toPathPiece mc) =<< withUrlRenderer (iHamlet $ toHtml . mr)
|
ClassyPrelude.Yesod.addMessage (toPathPiece mc) =<< withUrlRenderer (iHamlet $ toHtml . mr)
|
||||||
|
|
||||||
|
messageIHamlet :: ( MonadHandler m
|
||||||
|
, RenderMessage (HandlerSite m) msg
|
||||||
|
, HandlerSite m ~ site
|
||||||
|
) => MessageClass -> HtmlUrlI18n msg (Route site) -> m Message
|
||||||
|
messageIHamlet mc iHamlet = do
|
||||||
|
mr <- getMessageRender
|
||||||
|
Message mc <$> withUrlRenderer (iHamlet $ toHtml . mr)
|
||||||
|
|
||||||
addMessageFile :: MessageClass -> FilePath -> ExpQ
|
addMessageFile :: MessageClass -> FilePath -> ExpQ
|
||||||
addMessageFile mc tPath = [e|addMessageIHamlet mc $(ihamletFile tPath)|]
|
addMessageFile mc tPath = [e|addMessageIHamlet mc $(ihamletFile tPath)|]
|
||||||
|
|
||||||
|
messageFile :: MessageClass -> FilePath -> ExpQ
|
||||||
|
messageFile mc tPath = [e|messageIHamlet mc $(ihamletFile tPath)|]
|
||||||
|
|
||||||
addMessageWidget :: forall m site.
|
addMessageWidget :: forall m site.
|
||||||
( MonadHandler m
|
( MonadHandler m
|
||||||
, HandlerSite m ~ site
|
, HandlerSite m ~ site
|
||||||
@ -93,3 +110,12 @@ addMessageWidget :: forall m site.
|
|||||||
addMessageWidget mc wgt = do
|
addMessageWidget mc wgt = do
|
||||||
PageContent{pageBody} <- liftHandlerT $ widgetToPageContent wgt
|
PageContent{pageBody} <- liftHandlerT $ widgetToPageContent wgt
|
||||||
addMessageIHamlet mc (const pageBody :: HtmlUrlI18n (SomeMessage site) (Route site))
|
addMessageIHamlet mc (const pageBody :: HtmlUrlI18n (SomeMessage site) (Route site))
|
||||||
|
|
||||||
|
messageWidget :: forall m site.
|
||||||
|
( MonadHandler m
|
||||||
|
, HandlerSite m ~ site
|
||||||
|
, Yesod site
|
||||||
|
) => MessageClass -> WidgetT site IO () -> m Message
|
||||||
|
messageWidget mc wgt = do
|
||||||
|
PageContent{pageBody} <- liftHandlerT $ widgetToPageContent wgt
|
||||||
|
messageIHamlet mc (const pageBody :: HtmlUrlI18n (SomeMessage site) (Route site))
|
||||||
|
|||||||
@ -28,7 +28,7 @@ $if not isModal
|
|||||||
^{pageactionprime}
|
^{pageactionprime}
|
||||||
|
|
||||||
<!-- alerts -->
|
<!-- alerts -->
|
||||||
<div .alerts>
|
<div #alerts .alerts>
|
||||||
$forall (status, msg) <- mmsgs
|
$forall (status, msg) <- mmsgs
|
||||||
$with status2 <- bool status "info" (status == "")
|
$with status2 <- bool status "info" (status == "")
|
||||||
<div class="alert alert-#{status2}">
|
<div class="alert alert-#{status2}">
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
_{MsgHelpIntroduction}
|
_{MsgHelpIntroduction}
|
||||||
|
|
||||||
<form method=post action=@{HelpR} enctype=#{formEnctype}>
|
<form method=post action=@{HelpR} enctype=#{formEnctype} :isModal:data-ajax-submit>
|
||||||
^{formWidget}
|
^{formWidget}
|
||||||
|
|||||||
@ -5,24 +5,24 @@
|
|||||||
|
|
||||||
var ALERT_INVISIBLE_CLASS = 'alert--invisible';
|
var ALERT_INVISIBLE_CLASS = 'alert--invisible';
|
||||||
var TOGGLER_INVISIBLE_CLASS = 'alerts__toggler--visible';
|
var TOGGLER_INVISIBLE_CLASS = 'alerts__toggler--visible';
|
||||||
|
var alertsShowingToggler = false;
|
||||||
|
|
||||||
window.utils.alerts = function(alertsEl) {
|
window.utils.alerts = function(alertsEl) {
|
||||||
|
|
||||||
var alerts = Array.from(alertsEl.querySelectorAll('.alert'));
|
var toggler = alertsEl.querySelector('.alerts__toggler');
|
||||||
var toggler;
|
|
||||||
var showingToggler = false;
|
|
||||||
|
|
||||||
function makeToggler() {
|
function makeToggler() {
|
||||||
toggler = document.createElement('DIV');
|
toggler = document.createElement('DIV');
|
||||||
toggler.classList.add('alerts__toggler');
|
toggler.classList.add('alerts__toggler');
|
||||||
toggler.addEventListener('click', function() {
|
toggler.addEventListener('click', function() {
|
||||||
alerts.forEach(function(alert) {
|
Array.from(alertsEl.querySelectorAll('.alert')).forEach(function(alert) {
|
||||||
alert.classList.remove(ALERT_INVISIBLE_CLASS);
|
alert.classList.remove(ALERT_INVISIBLE_CLASS);
|
||||||
toggler.classList.remove(TOGGLER_INVISIBLE_CLASS);
|
toggler.classList.remove(TOGGLER_INVISIBLE_CLASS);
|
||||||
});
|
});
|
||||||
checkToggler();
|
checkToggler();
|
||||||
});
|
});
|
||||||
alertsEl.appendChild(toggler);
|
alertsEl.appendChild(toggler);
|
||||||
|
alertsEl.classList.add('js-initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeAlert(alertEl) {
|
function makeAlert(alertEl) {
|
||||||
@ -47,6 +47,8 @@
|
|||||||
closeAlert(alertEl);
|
closeAlert(alertEl);
|
||||||
}, autoDecay * 1000);
|
}, autoDecay * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alertEl.classList.add('js-initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeAlert(alertEl) {
|
function closeAlert(alertEl) {
|
||||||
@ -56,22 +58,23 @@
|
|||||||
|
|
||||||
function checkToggler() {
|
function checkToggler() {
|
||||||
var hidden = true;
|
var hidden = true;
|
||||||
alerts.forEach(function(alert) {
|
Array.from(alertsEl.querySelectorAll('.alert')).forEach(function(alert) {
|
||||||
if (hidden && !alert.classList.contains(ALERT_INVISIBLE_CLASS)) {
|
if (hidden && !alert.classList.contains(ALERT_INVISIBLE_CLASS)) {
|
||||||
hidden = false;
|
hidden = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!showingToggler) {
|
if (!alertsShowingToggler) {
|
||||||
showingToggler = true;
|
alertsShowingToggler = true;
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
toggler.classList.toggle(TOGGLER_INVISIBLE_CLASS, hidden);
|
toggler.classList.toggle(TOGGLER_INVISIBLE_CLASS, hidden);
|
||||||
showingToggler = false;
|
alertsShowingToggler = false;
|
||||||
}, 120);
|
}, 120);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeToggler();
|
if (!alertsEl.classList.contains('js-initialized') || !toggler)
|
||||||
alerts.map(makeAlert);
|
makeToggler();
|
||||||
|
Array.from(alertsEl.querySelectorAll('.alert:not(.js-initialized)')).map(makeAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
@ -79,7 +82,11 @@
|
|||||||
document.addEventListener('setup', function(e) {
|
document.addEventListener('setup', function(e) {
|
||||||
|
|
||||||
// setup alerts
|
// setup alerts
|
||||||
var alertsEl = e.detail.scope.querySelector('.alerts');
|
if (e.detail.scope.classList.contains('alerts')) {
|
||||||
if (alertsEl)
|
window.utils.alerts(e.detail.scope);
|
||||||
window.utils.alerts(alertsEl);
|
} else {
|
||||||
|
var alertsEl = e.detail.scope.querySelector('.alerts');
|
||||||
|
if (alertsEl)
|
||||||
|
window.utils.alerts(alertsEl);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -10,6 +10,10 @@
|
|||||||
// var origParent = modal.parentNode;
|
// var origParent = modal.parentNode;
|
||||||
|
|
||||||
function open(event) {
|
function open(event) {
|
||||||
|
if (!modal.classList.contains('js-modal-initialized')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// disable modals for narrow screens
|
// disable modals for narrow screens
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -17,7 +21,7 @@
|
|||||||
modal.classList.add('modal--open');
|
modal.classList.add('modal--open');
|
||||||
overlay.classList.add('modal__overlay');
|
overlay.classList.add('modal__overlay');
|
||||||
// document.body.insertBefore(modal, null);
|
// document.body.insertBefore(modal, null);
|
||||||
document.body.insertBefore(overlay, modal);
|
document.body.insertBefore(overlay, modal);
|
||||||
overlay.classList.add('modal__overlay--open');
|
overlay.classList.add('modal__overlay--open');
|
||||||
|
|
||||||
if ('closeable' in modal.dataset) {
|
if ('closeable' in modal.dataset) {
|
||||||
@ -37,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function close(event) {
|
function close(event) {
|
||||||
if (typeof event === 'undefined' || event.target === closer || event.target === overlay) {
|
if (typeof event === 'undefined' || event.target === closer || event.target === overlay || event.target === modal) {
|
||||||
overlay.remove();
|
overlay.remove();
|
||||||
// origParent.insertBefore(modal, null);
|
// origParent.insertBefore(modal, null);
|
||||||
modal.classList.remove('modal--open');
|
modal.classList.remove('modal--open');
|
||||||
@ -46,7 +50,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
document.body.insertBefore(modal, null);
|
document.body.insertBefore(modal, null);
|
||||||
|
|
||||||
// every modal can be openend via document-wide event, see openOnEvent
|
// every modal can be openend via document-wide event, see openOnEvent
|
||||||
document.addEventListener('modal-open', openOnEvent, false);
|
document.addEventListener('modal-open', openOnEvent, false);
|
||||||
@ -57,21 +61,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ('dynamic' in modal.dataset) {
|
if ('dynamic' in modal.dataset) {
|
||||||
var dynamicContentURL = trigger.getAttribute('href');
|
function fetchModal(url, init) {
|
||||||
|
function responseHtml(body) {
|
||||||
console.log(dynamicContentURL);
|
|
||||||
|
|
||||||
if (dynamicContentURL.length > 0) {
|
|
||||||
fetch(dynamicContentURL, {
|
|
||||||
credentials: 'same-origin',
|
|
||||||
headers: {
|
|
||||||
#{String (toPathPiece HeaderIsModal)}: 'True'
|
|
||||||
}
|
|
||||||
}).then(function(response) {
|
|
||||||
return response.text();
|
|
||||||
}).then(function(body) {
|
|
||||||
var modalContent = document.createElement('div');
|
var modalContent = document.createElement('div');
|
||||||
modalContent.classList.add('modal__content');
|
|
||||||
modalContent.innerHTML = body;
|
modalContent.innerHTML = body;
|
||||||
|
|
||||||
var contentBody = modalContent.querySelector('.main__content-body');
|
var contentBody = modalContent.querySelector('.main__content-body');
|
||||||
@ -122,6 +114,7 @@
|
|||||||
|
|
||||||
modalContent = contentBody;
|
modalContent = contentBody;
|
||||||
}
|
}
|
||||||
|
modalContent.classList.add('modal__content');
|
||||||
|
|
||||||
var nudgeAttr = function(attr, x) {
|
var nudgeAttr = function(attr, x) {
|
||||||
var oldVal = x.getAttribute(attr);
|
var oldVal = x.getAttribute(attr);
|
||||||
@ -136,11 +129,12 @@
|
|||||||
modalContent.querySelectorAll('[' + attr + ']').forEach(function(x) { nudgeAttr(attr, x); });
|
modalContent.querySelectorAll('[' + attr + ']').forEach(function(x) { nudgeAttr(attr, x); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modal.querySelectorAll('.modal__content').forEach(function(prev) { modal.removeChild(prev); });
|
||||||
modal.appendChild(modalContent);
|
modal.appendChild(modalContent);
|
||||||
|
|
||||||
var triggerContentLoad = function() {
|
var triggerContentLoad = function() {
|
||||||
document.dispatchEvent(new CustomEvent('setup', {
|
document.dispatchEvent(new CustomEvent('setup', {
|
||||||
detail: { scope: modalContent },
|
detail: { scope: modal },
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
cancelable: true
|
cancelable: true
|
||||||
}));
|
}));
|
||||||
@ -151,14 +145,110 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
triggerContentLoad();
|
triggerContentLoad();
|
||||||
|
|
||||||
|
return 'html';
|
||||||
|
}
|
||||||
|
|
||||||
|
function responseJson(data) {
|
||||||
|
var alertsEl = document.querySelector('#alerts');
|
||||||
|
if (!alertsEl)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
var alert = document.createElement('div');
|
||||||
|
alert.classList.add('alert', 'alert-' + data[i].class);
|
||||||
|
var alertContent = document.createElement('div');
|
||||||
|
alertContent.classList.add('alert__content');
|
||||||
|
alertContent.innerHTML = data[i].content;
|
||||||
|
alert.appendChild(alertContent);
|
||||||
|
|
||||||
|
alertsEl.insertBefore(alert, alertsEl.querySelector('.alerts__toggler'));
|
||||||
|
}
|
||||||
|
|
||||||
|
document.dispatchEvent(new CustomEvent('setup', { detail: { scope: alertsEl }, bubbles: true, cancelable: true }));
|
||||||
|
|
||||||
|
return 'json';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return fetch(url, init).then(function(response) {
|
||||||
|
var contentType = response.headers.get('Content-Type')
|
||||||
|
if (contentType && contentType.includes('text/html')) {
|
||||||
|
return response.text().then(responseHtml);
|
||||||
|
} else if (contentType && contentType.includes('application/json')) {
|
||||||
|
return response.json().then(responseJson);
|
||||||
|
} else {
|
||||||
|
console.log(response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
modal.addEventListener('modal-fetch', function(event) {
|
||||||
|
var dynamicContentURL = (event.detail && event.detail.url) || trigger.getAttribute('href');
|
||||||
|
console.log(dynamicContentURL);
|
||||||
|
|
||||||
|
var fetchInit = (event.detail && event.detail.init) || {
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
#{String (toPathPiece HeaderIsModal)}: 'True'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dynamicContentURL.length > 0) {
|
||||||
|
fetchModal(dynamicContentURL, fetchInit).then((event.detail && event.detail.then) || (function(){}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
modal.dispatchEvent(new CustomEvent('modal-fetch'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell further modals, that this one already got initialized
|
// tell further modals, that this one already got initialized
|
||||||
modal.classList.add('js-modal-initialized');
|
modal.classList.add('js-modal-initialized');
|
||||||
|
|
||||||
|
modal.addEventListener('modal-close', close);
|
||||||
}
|
}
|
||||||
setup();
|
setup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.utils.ajaxSubmit = function(modal, form) {
|
||||||
|
function doSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
console.log('ajaxSubmit', modal, form);
|
||||||
|
|
||||||
|
var modalContent = modal.querySelector('.modal__content');
|
||||||
|
modalContent.style.pointerEvents = 'none';
|
||||||
|
modalContent.style.opacity = 0.5;
|
||||||
|
|
||||||
|
modal.dispatchEvent(new CustomEvent('modal-fetch', {
|
||||||
|
detail: {
|
||||||
|
url: form.target,
|
||||||
|
init: {
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
#{String (toPathPiece HeaderIsModal)}: 'True'
|
||||||
|
},
|
||||||
|
method: form.method,
|
||||||
|
body: new FormData(form)
|
||||||
|
},
|
||||||
|
then: (function(typ) {
|
||||||
|
modalContent.style.pointerEvents = 'auto';
|
||||||
|
modalContent.style.opacity = 1;
|
||||||
|
|
||||||
|
if (typ === 'json') {
|
||||||
|
modal.dispatchEvent(new CustomEvent('modal-close'));
|
||||||
|
modal.dispatchEvent(new CustomEvent('modal-fetch'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
form.addEventListener('submit', doSubmit);
|
||||||
|
form.classList.add('js-ajax-initialized');
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
document.addEventListener('setup', function(e) {
|
document.addEventListener('setup', function(e) {
|
||||||
@ -167,5 +257,17 @@ document.addEventListener('setup', function(e) {
|
|||||||
new utils.modal(modal);
|
new utils.modal(modal);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (e.detail.scope.classList.contains('js-modal')) {
|
||||||
|
Array.from(e.detail.scope.querySelectorAll('form[data-ajax-submit]:not(.js-ajax-initialized)')).map(function(form) {
|
||||||
|
window.utils.ajaxSubmit(e.detail.scope, form);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Array.from(e.detail.scope.querySelectorAll('.js-modal')).map(function(modal) {
|
||||||
|
Array.from(modal.querySelectorAll('form[data-ajax-submit]:not(.js-ajax-initialized)')).map(function(form) {
|
||||||
|
window.utils.ajaxSubmit(modal, form);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
function setupAsync(wrapper) {
|
function setupAsync(wrapper) {
|
||||||
|
|
||||||
var table = wrapper.querySelector('#' + #{String $ dbtIdent});
|
var table = wrapper.querySelector('#' + #{String $ dbtIdent});
|
||||||
|
if (!table)
|
||||||
|
return;
|
||||||
|
|
||||||
var ths = Array.from(table.querySelectorAll('th.sortable'));
|
var ths = Array.from(table.querySelectorAll('th.sortable'));
|
||||||
var pagination = wrapper.querySelector('#' + #{String $ dbtIdent} + '-pagination');
|
var pagination = wrapper.querySelector('#' + #{String $ dbtIdent} + '-pagination');
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<div .modal.js-modal #modal-#{modalId} data-trigger=#{triggerId} data-closeable :modalDynamic:data-dynamic>
|
<div .modal.js-modal #modal-#{modalId} data-trigger=#{triggerId} data-closeable :modalDynamic:data-dynamic>
|
||||||
$case modalContent
|
$case modalContent
|
||||||
$of Right content
|
$of Right content
|
||||||
^{content}
|
<div .modal__content>
|
||||||
|
^{content}
|
||||||
$of Left _
|
$of Left _
|
||||||
|
|||||||
Reference in New Issue
Block a user