Merge branch 'feat/modals' into 'master'
refactoring of modals and ajax-support See merge request !21
This commit is contained in:
commit
7f549c3667
@ -399,12 +399,6 @@ defaultMenuLayout menu widget = do
|
||||
asidenav = $(widgetFile "widgets/asidenav")
|
||||
breadcrumbs :: Widget
|
||||
breadcrumbs = $(widgetFile "widgets/breadcrumbs")
|
||||
modal :: [Char] -> [Char] -> Widget
|
||||
modal modalTrigger modalContent = do
|
||||
let
|
||||
modalId :: Int32
|
||||
modalId = 13
|
||||
$(widgetFile "widgets/modal")
|
||||
pageactionprime :: Widget
|
||||
pageactionprime = $(widgetFile "widgets/pageactionprime")
|
||||
-- functions to determine if there are page-actions
|
||||
@ -420,6 +414,7 @@ defaultMenuLayout menu widget = do
|
||||
addStylesheet $ StaticR css_fonts_css
|
||||
addStylesheet $ StaticR css_icons_css
|
||||
$(widgetFile "default-layout")
|
||||
$(widgetFile "standalone/modal")
|
||||
$(widgetFile "standalone/showHide")
|
||||
$(widgetFile "standalone/sortable")
|
||||
$(widgetFile "standalone/inputs")
|
||||
|
||||
@ -6,3 +6,17 @@ import Import.NoFoundation
|
||||
|
||||
lipsum :: WidgetT site IO ()
|
||||
lipsum = $(widgetFile "widgets/lipsum")
|
||||
|
||||
modal :: [Char] -> Maybe [Char] -> WidgetT site IO ()
|
||||
modal modalTrigger (Just modalContent) = do
|
||||
let
|
||||
modalId :: Int32
|
||||
modalId = 13
|
||||
$(widgetFile "widgets/modal")
|
||||
modal modalTrigger Nothing = do
|
||||
let
|
||||
modalId :: Int32
|
||||
modalId = 13
|
||||
modalContent :: [Char]
|
||||
modalContent = "placeholder"
|
||||
$(widgetFile "widgets/modal")
|
||||
|
||||
@ -6,8 +6,6 @@
|
||||
<!-- secondary navigation at the side -->
|
||||
^{asidenav}
|
||||
|
||||
^{modal ".toggler" "<h2>Neue Veranstaltung</h2><br>Erstelle eine neue Veranstaltung! Jetzt und hier. Kostenlos."}
|
||||
|
||||
<div .main__content>
|
||||
|
||||
<!-- alerts -->
|
||||
|
||||
@ -72,11 +72,14 @@
|
||||
Knopf-Test:
|
||||
<form .form-inline method=post action=@{HomeR} enctype=#{btnEnctype}>
|
||||
^{btnWdgt}
|
||||
$if True
|
||||
$# meant to be 'if js-supported'
|
||||
<li><br>
|
||||
Modals:
|
||||
<button type="button" .toggler>Klick mich
|
||||
<li><br>
|
||||
Modals:
|
||||
^{modal ".toggler1" Nothing}
|
||||
<a href="/" .btn.toggler1>Klick mich für Ajax-Test
|
||||
<noscript>(Für Modals bitte JS aktivieren)</noscript>
|
||||
^{modal ".toggler2" (Just "Test wegen Modal")}
|
||||
<div .btn.toggler2>Klick mich für Content-Test
|
||||
<noscript>(Für Modals bitte JS aktivieren)</noscript>
|
||||
|
||||
<li><br>
|
||||
Multi-File-Input für bereits hochgeladene Dateien:
|
||||
|
||||
@ -152,6 +152,9 @@
|
||||
window.utils.reactiveFileCheckbox = function(input, label, parent) {
|
||||
// adds eventlistener(s)
|
||||
function addListener(container) {
|
||||
container.addEventListener('click', function() {
|
||||
input.click();
|
||||
});
|
||||
input.addEventListener('change', function(event) {
|
||||
container.classList.toggle('file-checkbox__container--valid', this.checked);
|
||||
});
|
||||
|
||||
1
templates/standalone/modal.hamlet
Normal file
1
templates/standalone/modal.hamlet
Normal file
@ -0,0 +1 @@
|
||||
<!-- only here to be able to include modal using `toWidget` -->
|
||||
100
templates/standalone/modal.julius
Normal file
100
templates/standalone/modal.julius
Normal file
@ -0,0 +1,100 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.utils = window.utils || {};
|
||||
|
||||
window.utils.modal = function(modal) {
|
||||
var overlay = document.createElement('div');
|
||||
var closer = document.createElement('div');
|
||||
var trigger = document.querySelector(modal.dataset.trigger);
|
||||
var origParent = modal.parentNode;
|
||||
|
||||
function open(event) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
modal.classList.add('modal--open');
|
||||
overlay.classList.add('modal__overlay');
|
||||
document.body.insertBefore(modal, null);
|
||||
document.body.insertBefore(overlay, modal);
|
||||
overlay.classList.add('modal__overlay--open');
|
||||
toggleScroll(false);
|
||||
|
||||
if (modal.dataset.closeable === 'true') {
|
||||
closer.classList.add('modal__closer');
|
||||
modal.insertBefore(closer, null);
|
||||
closer.addEventListener('click', close, false);
|
||||
overlay.addEventListener('click', close, false);
|
||||
}
|
||||
}
|
||||
|
||||
// open this modal with an event:
|
||||
// document.dispatchEvent(new CustomEvent('modal-open', { dateils: {for: 'modal-13'}}))
|
||||
function openOnEvent(event) {
|
||||
if (event.detail.for === modal.getAttribute('id')) {
|
||||
open();
|
||||
}
|
||||
}
|
||||
|
||||
function close(event) {
|
||||
if (typeof event === 'undefined' || event.target === closer || event.target === overlay) {
|
||||
overlay.remove();
|
||||
origParent.insertBefore(modal, null);
|
||||
modal.classList.remove('modal--open');
|
||||
toggleScroll(true);
|
||||
closer.removeEventListener('click', close, false);
|
||||
}
|
||||
};
|
||||
|
||||
function setup() {
|
||||
// every modal can be openend via document-wide event, see openOnEvent
|
||||
document.addEventListener('modal-open', openOnEvent, false);
|
||||
// if modal has trigger assigned to it open modal on click
|
||||
if (trigger) {
|
||||
trigger.classList.add('modal__trigger');
|
||||
trigger.addEventListener('click', open, false);
|
||||
}
|
||||
// if there is no content specified for the modal we assume that
|
||||
// the content is supposed to be the page the trigger links to.
|
||||
// so we check if the trigger has a href-attribute, fetch that page
|
||||
// and replace the modal content with the response
|
||||
var replaceMe = modal.querySelector('.replace-me');
|
||||
var replaceWith = trigger ? trigger.getAttribute('href') : '';
|
||||
if (replaceMe) {
|
||||
replaceMe.classList.remove('replace-me');
|
||||
replaceMe.innerText = '...loading';
|
||||
if (replaceWith.length > 0) {
|
||||
fetch(replaceWith).then(function(response) {
|
||||
return response.text();
|
||||
}).then(function(body) {
|
||||
var modalContent = document.createElement('div');
|
||||
modalContent.innerHTML = body;
|
||||
var main = modalContent.querySelector('.main__content');
|
||||
if (main) {
|
||||
replaceMe.innerText = '';
|
||||
replaceMe.insertBefore(main, null);
|
||||
} else {
|
||||
replaceMe.innerHTML = body;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// tell further modals, that this one already got initialized
|
||||
modal.classList.add('js-modal-initialized');
|
||||
}
|
||||
setup();
|
||||
};
|
||||
|
||||
// make sure document doesn't scroll when modal is active
|
||||
function toggleScroll(scrollable) {
|
||||
document.body.classList.toggle('no-scroll', !scrollable);
|
||||
}
|
||||
})();
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
Array.from(document.querySelectorAll('.js-modal:not(.js-modal-initialized)')).map(function(modal) {
|
||||
new utils.modal(modal);
|
||||
});
|
||||
|
||||
}, false);
|
||||
@ -73,6 +73,7 @@
|
||||
background-color: var(--darkbase);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
z-index: 20;
|
||||
|
||||
&::before {
|
||||
content: '\e014';
|
||||
@ -1,17 +1,18 @@
|
||||
<div .modal.js-modal #modal-#{modalId} data-trigger=#{modalTrigger} data-closeable=true>
|
||||
<h2>Neue Veranstaltung
|
||||
#{modalContent}
|
||||
<form>
|
||||
<div .form-group>
|
||||
<label .reactive-label for="inp1">Name
|
||||
<input type="text" id="inp1">
|
||||
<div .form-group>
|
||||
<label .reactive-label for="inp2">Kürzel
|
||||
<input type="text" id="inp2">
|
||||
<div .form-group>
|
||||
<label .reactive-label for="inp3">Aktiv?
|
||||
<div .checkbox>
|
||||
<input id="inp3" name="f2" type="checkbox">
|
||||
<label for="inp3">
|
||||
<div .form-group>
|
||||
<input type="submit" value="Submit">
|
||||
$if 11 == length modalContent
|
||||
<div .replace-me>
|
||||
$else
|
||||
<h2>Neue Veranstaltung
|
||||
#{modalContent}
|
||||
<form>
|
||||
<div .form-group>
|
||||
<label .reactive-label for="inp1">Name
|
||||
<input type="text" id="inp1">
|
||||
<div .form-group>
|
||||
<label .reactive-label for="inp2">Kürzel
|
||||
<input type="text" id="inp2">
|
||||
<div .form-group>
|
||||
<label .reactive-label for="inp3">Semester
|
||||
<input type="text" id="inp3">
|
||||
<div .form-group>
|
||||
<input type="submit" value="Submit">
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
'use strict';
|
||||
|
||||
window.utils = window.utils || {};
|
||||
|
||||
if (!window.utils.modal) {
|
||||
window.utils.modal = function(modal) {
|
||||
var overlay = document.createElement('div');
|
||||
var closer = document.createElement('div');
|
||||
var trigger = document.querySelector(modal.dataset.trigger);
|
||||
var closeBound;
|
||||
|
||||
this.open = function openFn() {
|
||||
modal.classList.add('modal--open');
|
||||
overlay.classList.add('modal__overlay');
|
||||
modal.parentNode.insertBefore(overlay, modal);
|
||||
overlay.classList.add('modal__overlay--open');
|
||||
toggleScroll(false);
|
||||
|
||||
if (modal.dataset.closeable === 'true') {
|
||||
closer.classList.add('modal__closer');
|
||||
modal.insertBefore(closer, null);
|
||||
closer.addEventListener('click', closeBound, false);
|
||||
overlay.addEventListener('click', closeBound, false);
|
||||
}
|
||||
};
|
||||
|
||||
this.openOnEvent = function openOnEventFn(event) {
|
||||
if (event.detail.for === modal.getAttribute('id')) {
|
||||
this.open();
|
||||
}
|
||||
};
|
||||
this.close = function closeFn(event) {
|
||||
if (typeof event === 'undefined' || event.target === closer || event.target === overlay) {
|
||||
modal.classList.remove('modal--open');
|
||||
overlay.classList.remove('modal__overlay--open');
|
||||
toggleScroll(true);
|
||||
closer.removeEventListener('click', closeBound, false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('modal-open', this.openOnEvent.bind(this), false);
|
||||
closeBound = this.close.bind(this);
|
||||
if (trigger) {
|
||||
trigger.classList.add('modal__trigger');
|
||||
trigger.addEventListener('click', this.open.bind(this), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleScroll(scrollable) {
|
||||
document.body.classList.toggle('no-scroll', !scrollable);
|
||||
}
|
||||
|
||||
new utils.modal(document.querySelector('#modal-13')); // hashtag{modalId} scope-variable
|
||||
|
||||
}, false);
|
||||
Loading…
Reference in New Issue
Block a user