<section class="overlay-modal" data-step="1">
<div class="overlay-modal__overlay">
<span class="overlay-modal__bg overlay-modal__trigger--close"></span>
<div class="overlay-modal__inner">
<span class="overlay-modal__close overlay-modal__trigger--close"></span>
<div class="overlay-modal__content">
<h3 class="heading heading--4">
<span data-step="1"></span>
<span data-step="2">Thank you!</span>
</h3>
<div class="overlay-modal__description">
</div>
<form data-step="1" class="form form--modal form--modal" novalidate>
<div class="overlay-modal__form">
<div class="parent-class input-field is-required">
<div class="input-field__inner">
<input type="email" name="email" id="" value="" class="test" required>
<span class="input-field__placeholder">Email address</span>
</div>
<div class="input-field__error">
<p>This field is not filled in correctly or cannot be empty.</p>
</div>
</div>
<div class="overlay-modal__action">
<button type="submit" class="action action--normal action--on-light">
<span class="action__label">Sign me up</span>
<span class="action__bg"></span>
</button>
</div>
</div>
<div class="overlay-modal__note">
We respect your privacy and don't share you email with anybody.
</div>
</form>
</div>
</div>
</div>
</section>
{{#if visible}}<div class="overlay-modal-is-visible">{{/if}}
<section class="overlay-modal" data-step="1"{{#if modal}} data-modal="{{modal}}"{{/if}}>
<div class="overlay-modal__overlay">
<span class="overlay-modal__bg overlay-modal__trigger--close"></span>
<div class="overlay-modal__inner">
<span class="overlay-modal__close overlay-modal__trigger--close">{{ @icon-cross }}</span>
<div class="overlay-modal__content">
<h3 class="heading heading--4">
<span data-step="1">{{ heading }}</span>
<span data-step="2">{{ thanks }}</span>
</h3>
<div class="overlay-modal__description">
{{ description }}
</div>
<form data-step="1" class="form form--modal{{#if formModifier }} form--{{ formModifier }}{{/if}}" novalidate>
<div class="overlay-modal__form">
{{render '@input-field' input merge=true }}
<div class="overlay-modal__action">
{{render '@action' action merge=true }}
</div>
</div>
<div class="overlay-modal__note">
{{ note }}
</div>
</form>
</div>
</div>
</div>
</section>
{{#if visible}}</div>{{/if}}
visible: false
heading: ''
description: ''
thanks: Thank you!
note: We respect your privacy and don't share you email with anybody.
formModifier: modal
input:
placeholder: Email address
name: email
required: true
type: email
action:
label: Sign me up
buttonType: submit
const MODALFORM = ((window, undefined) => {
const SETTINGS = {
debug: true,
};
const SELECTORS = {
form: '.form--modal',
inputWrapper: '.input-field',
select: 'select',
modal: '.overlay-modal'
};
const CLASSES = {
formError: 'form--error',
error: 'has-error',
};
function resetField(element) {
if (SETTINGS.debug) { console.log('MODALFORM reset field', element); }
element.closest(SELECTORS.inputWrapper).classList.remove(CLASSES.error);
}
function isHidden(el) {
return (!el || el.offsetParent === null);
}
function onFieldChange (e) {
resetField(e.target);
}
function validate(form) {
if (!form) { return; }
let valid = true;
if (SETTINGS.debug) { console.log('MODALFORM validate', form); }
[...form.elements].forEach(element => {
if (isHidden(element)) {
resetField(element);
return;
}
element.classList.remove(CLASSES.error);
try {
if (!element.checkValidity()) {
valid = false;
if (SETTINGS.debug) { console.warn('MODALFORM validate element error', element, element.checkValidity()); }
element.closest(SELECTORS.inputWrapper).classList.add(CLASSES.error);
element.removeEventListener('input', onFieldChange);
element.addEventListener('input', onFieldChange);
}
} catch(e) {
if (SETTINGS.debug) { console.error(e); }
}
});
return valid;
}
function submit(e) {
const form = e.target;
form.classList.remove(CLASSES.formError);
if (!validate(form)) {
e.preventDefault();
form.classList.add(CLASSES.formError);
return;
}
if (SETTINGS.debug) {
const modal = form.closest(SELECTORS.modal);
if (!modal) { return; }
if (modal.dataset.step) {
e.preventDefault();
modal.setAttribute('data-step', 2);
return;
}
}
}
function init() {
const forms = document.querySelectorAll(SELECTORS.form);
if (!forms || forms.length <= 0) { return; }
if (SETTINGS.debug) { console.log('MODALFORM init', forms); }
forms.forEach(form => form.addEventListener('submit', submit));
}
document.addEventListener('DOMContentLoaded', init);
})(window);
const OVERLAYModal = ((w, d, undefined) => {
'use strict';
const selectors = {
theWrap: '.overlay-modal',
theTrigger: '.overlay-modal__trigger,.action[data-modal], .action--modal',
theCloser: '.overlay-modal__trigger--close',
};
const classes = {
isVisible: 'is-visible',
overlayModalIsVisible: 'overlay-modal-is-visible',
};
const els = {};
const init = () => {
els.theWraps = d.querySelectorAll(selectors.theWrap);
els.theTriggers = d.querySelectorAll(selectors.theTrigger);
els.theClosers = d.querySelectorAll(selectors.theCloser);
// [...els.theWraps].forEach((theWrap) => {
// const theClose = theWrap.querySelector(selectors.theClose);
// });
[...els.theClosers].forEach((theClose) => {
theClose && theClose.addEventListener('click', (e) => {
e.preventDefault();
d.body.classList.remove(classes.overlayModalIsVisible);
d.removeEventListener('keyup', keyTabbed);
});
});
[...els.theTriggers].forEach((theTrigger) => {
theTrigger && theTrigger.addEventListener('click', (e) => {
e.preventDefault();
const trigger = e.currentTarget;
// if (trigger.getAttribute('href') && trigger.dataset.modal) {
// e.preventDefault();
// }
d.body.classList.add(classes.overlayModalIsVisible);
d.addEventListener('keyup', keyTabbed);
const modal = trigger.dataset['modal'];
if (modal) {
const wrongWrappers = document.querySelectorAll(`${selectors.theWrap}:not([data-modal="${trigger.dataset['modal']}"])`);
[...wrongWrappers].forEach(wrapper => wrapper.classList.add('hidden'));
const wrapper = document.querySelector(`${selectors.theWrap}[data-modal="${trigger.dataset['modal']}"]`);
if (wrapper) {
wrapper.classList.remove('hidden');
}
} else {
const wrongWrappers = document.querySelectorAll(`${selectors.theWrap}[data-modal]`);
[...wrongWrappers].forEach(wrapper => wrapper.classList.add('hidden'));
const wrapper = document.querySelector(`${selectors.theWrap}:not([data-modal])`);
if (wrapper) {
wrapper.classList.remove('hidden');
}
}
MAIN.resize(true);
return false;
});
});
};
const keyTabbed = (event) => {
if(!event || event.key !== 'Escape') { return; }
[...els.theWraps].forEach((theWrap) => {
theWrap.classList.contains(classes.isVisible) && theWrap.classList.remove(classes.isVisible);
d.body.classList.contains(classes.overlayModalIsVisible) && d.body.classList.remove(classes.overlayModalIsVisible);
});
};
d.addEventListener('DOMContentLoaded', init);
})(window, window.document);
.overlay-modal-is-visible {
overflow: hidden;
}
.overlay-modal {
overflow: hidden;
.overlay-modal-is-visible & {
overflow: visible;
}
}
.overlay-modal__overlay {
transition: opacity 500ms, left 0s 500ms;
position: fixed;
top: 0;
left: 100%;
z-index: 99999;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
padding: var(--gutter--bucket);
opacity: 0;
pointer-events: none;
background-color: rgba(#161616, .4);
.overlay-modal-is-visible & {
transition: opacity 500ms;
left: 0;
opacity: 1;
pointer-events: all;
}
}
.overlay-modal .g-recaptcha {
position: relative;
display: block;
width: 100%;
height: 0;
padding-top: (78 / 304) * 100%;
& > div {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
}
iframe {
@media (max-width: 360px) {
transform-origin: 0 0;
transform: scale(.844);
}
}
}
.overlay-modal__bg {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
background-color: var(--color--neutrals-9);
opacity: 0.4;
}
.overlay-modal__inner {
position: relative;
display: block;
flex: 1 1 auto;
max-width: var(--section--3);
padding: var(--gap--10) var(--gap--3);
background-color: var(--color--neutrals-0);
max-height: 90vh;
overflow: auto;
@media (min-width: 750px) {
padding: var(--gap--10) var(--gap--16);
}
}
.overlay-modal__close {
transition: transform 250ms;
position: absolute;
top: var(--gap--3);
right: var(--gap--3);
display: block;
width: 14px;
color: inherit;
text-decoration: none;
cursor: pointer;
@media (min-width: 750px) {
top: var(--gap--5);
right: var(--gap--5);
}
&:hover,
&:focus,
&:active {
transform: rotate(90deg);
color: inherit;
text-decoration: none;
}
&:after {
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 30px;
height: 30px;
border-radius: 50%;
content: '';
}
}
.overlay-modal__description {
margin-top: var(--gap--2);
}
.overlay-modal__form {
margin-top: var(--gap--4);
}
.overlay-modal__action {
margin-top: var(--gap--4);
}
.overlay-modal__note {
margin-top: var(--gap--4);
font-size: var(--p--2);
}
[data-step="1"] {
[data-step]:not([data-step="1"]) & {
display: none;
}
}
[data-step="2"] {
[data-step]:not([data-step="2"]) & {
display: none;
}
}
No notes defined.