refactor alerts js utility
This commit is contained in:
parent
1c99b36be0
commit
7d7c0d15c9
@ -1068,8 +1068,8 @@ siteLayout' headingOverride widget = do
|
|||||||
addScript $ StaticR js_services_utilRegistry_js
|
addScript $ StaticR js_services_utilRegistry_js
|
||||||
addScript $ StaticR js_services_httpClient_js
|
addScript $ StaticR js_services_httpClient_js
|
||||||
addScript $ StaticR js_services_i18n_js
|
addScript $ StaticR js_services_i18n_js
|
||||||
-- addScript $ StaticR js_utils_alerts_js
|
|
||||||
-- JavaScript utils
|
-- JavaScript utils
|
||||||
|
addScript $ StaticR js_utils_alerts_js
|
||||||
addScript $ StaticR js_utils_asidenav_js
|
addScript $ StaticR js_utils_asidenav_js
|
||||||
addScript $ StaticR js_utils_asyncForm_js
|
addScript $ StaticR js_utils_asyncForm_js
|
||||||
addScript $ StaticR js_utils_asyncTable_js
|
addScript $ StaticR js_utils_asyncTable_js
|
||||||
|
|||||||
@ -1,23 +1,3 @@
|
|||||||
/* ALERTS */
|
|
||||||
/**
|
|
||||||
.alert
|
|
||||||
Regular Info Alert
|
|
||||||
Disappears automatically after 30 seconds
|
|
||||||
Disappears after x seconds if explicitly specified via data-decay='x'
|
|
||||||
Can be told not to disappear with data-decay='0'
|
|
||||||
|
|
||||||
.alert-success
|
|
||||||
Disappears automatically after 30 seconds
|
|
||||||
|
|
||||||
.alert-warning
|
|
||||||
Does not disappear
|
|
||||||
Orange regardless of user's selected theme
|
|
||||||
|
|
||||||
.alert-error
|
|
||||||
Does not disappear
|
|
||||||
Red regardless of user's selected theme
|
|
||||||
|
|
||||||
*/
|
|
||||||
.alerts {
|
.alerts {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|||||||
@ -1,68 +1,126 @@
|
|||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
window.utils = window.utils || {};
|
/**
|
||||||
|
*
|
||||||
|
* Alerts Utility
|
||||||
|
* makes alerts interactive
|
||||||
|
*
|
||||||
|
* Attribute: uw-alerts
|
||||||
|
*
|
||||||
|
* Types of alerts:
|
||||||
|
* [default]
|
||||||
|
* Regular Info Alert
|
||||||
|
* Disappears automatically after 30 seconds
|
||||||
|
* Disappears after x seconds if explicitly specified via data-decay='x'
|
||||||
|
* Can be told not to disappear with data-decay='0'
|
||||||
|
*
|
||||||
|
* [success]
|
||||||
|
* Currently no special visual appearance
|
||||||
|
* Disappears automatically after 30 seconds
|
||||||
|
*
|
||||||
|
* [warning]
|
||||||
|
* Will be coloured warning-orange regardless of user's selected theme
|
||||||
|
* Does not disappear
|
||||||
|
*
|
||||||
|
* [error]
|
||||||
|
* Will be coloured error-red regardless of user's selected theme
|
||||||
|
* Does not disappear
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* <div .alerts uw-alerts>
|
||||||
|
* <div .alerts__toggler>
|
||||||
|
* <div .alert.alert-info>
|
||||||
|
* <div .alert__closer>
|
||||||
|
* <div .alert__icon>
|
||||||
|
* <div .alert__content>
|
||||||
|
* This is some information
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
var ALERTS_CLASS = 'alerts';
|
var ALERTS_UTIL_NAME = 'alerts';
|
||||||
|
var ALERTS_UTIL_SELECTOR = '[uw-alerts]';
|
||||||
|
|
||||||
|
var ALERTS_INITIALIZED_CLASS = 'alerts--initialized';
|
||||||
var ALERTS_TOGGLER_CLASS = 'alerts__toggler';
|
var ALERTS_TOGGLER_CLASS = 'alerts__toggler';
|
||||||
var ALERTS_TOGGLER_VISIBLE_CLASS = 'alerts__toggler--visible';
|
var ALERTS_TOGGLER_VISIBLE_CLASS = 'alerts__toggler--visible';
|
||||||
var ALERTS_TOGGLER_APPEAR_DELAY = 120;
|
var ALERTS_TOGGLER_APPEAR_DELAY = 120;
|
||||||
|
|
||||||
var ALERT_CLASS = 'alert';
|
var ALERT_CLASS = 'alert';
|
||||||
|
var ALERT_INITIALIZED_CLASS = 'alert--initialized';
|
||||||
var ALERT_CLOSER_CLASS = 'alert__closer';
|
var ALERT_CLOSER_CLASS = 'alert__closer';
|
||||||
var ALERT_INVISIBLE_CLASS = 'alert--invisible';
|
var ALERT_INVISIBLE_CLASS = 'alert--invisible';
|
||||||
var ALERT_AUTO_HIDE_DELAY = 10;
|
var ALERT_AUTO_HIDE_DELAY = 10;
|
||||||
var ALERT_AUTOCLOSING_MATCHER = '.alert-info, .alert-success';
|
var ALERT_AUTOCLOSING_MATCHER = '.alert-info, .alert-success';
|
||||||
|
|
||||||
var JS_INITIALIZED_CLASS = 'js-initialized';
|
var alertsUtil = function(element) {
|
||||||
|
|
||||||
window.utils.alerts = function(alertsEl) {
|
|
||||||
|
|
||||||
if (alertsEl.classList.contains(JS_INITIALIZED_CLASS)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!alertsEl || !alertsEl.classList.contains(ALERTS_CLASS)) {
|
|
||||||
throw new Error('utils.alerts has to be called with alerts element');
|
|
||||||
}
|
|
||||||
|
|
||||||
var togglerCheckRequested = false;
|
var togglerCheckRequested = false;
|
||||||
|
var togglerElement;
|
||||||
|
var alertElements;
|
||||||
|
|
||||||
var togglerEl = alertsEl.querySelector('.' + ALERTS_TOGGLER_CLASS);
|
function init() {
|
||||||
|
if (!element) {
|
||||||
|
throw new Error('Alerts util has to be called with an element!');
|
||||||
|
}
|
||||||
|
|
||||||
var alertElements = Array.from(alertsEl.querySelectorAll('.' + ALERT_CLASS))
|
if (element.classList.contains(ALERTS_INITIALIZED_CLASS)) {
|
||||||
.filter(function(alert) {
|
return false;
|
||||||
return !alert.classList.contains(JS_INITIALIZED_CLASS);
|
}
|
||||||
|
|
||||||
|
togglerElement = element.querySelector('.' + ALERTS_TOGGLER_CLASS);
|
||||||
|
alertElements = gatherAlertElements();
|
||||||
|
|
||||||
|
initToggler();
|
||||||
|
initAlerts();
|
||||||
|
|
||||||
|
// mark initialized
|
||||||
|
element.classList.add(ALERTS_INITIALIZED_CLASS);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: ALERTS_UTIL_NAME,
|
||||||
|
element: element,
|
||||||
|
destroy: function() {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function gatherAlertElements() {
|
||||||
|
return Array.from(element.querySelectorAll('.' + ALERT_CLASS)).filter(function(alert) {
|
||||||
|
return !alert.classList.contains(ALERT_INITIALIZED_CLASS);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function initToggler() {
|
function initToggler() {
|
||||||
togglerEl.addEventListener('click', function() {
|
togglerElement.addEventListener('click', function() {
|
||||||
alertElements.forEach(function(alertEl) {
|
alertElements.forEach(function(alertEl) {
|
||||||
toggleAlert(alertEl, true);
|
toggleAlert(alertEl, true);
|
||||||
});
|
});
|
||||||
togglerEl.classList.remove(ALERTS_TOGGLER_VISIBLE_CLASS);
|
togglerElement.classList.remove(ALERTS_TOGGLER_VISIBLE_CLASS);
|
||||||
});
|
});
|
||||||
alertsEl.classList.add(JS_INITIALIZED_CLASS);
|
element.classList.add(ALERTS_INITIALIZED_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initAlert(alertEl) {
|
function initAlerts() {
|
||||||
|
alertElements.forEach(initAlert);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initAlert(alertElement) {
|
||||||
var autoHideDelay = ALERT_AUTO_HIDE_DELAY;
|
var autoHideDelay = ALERT_AUTO_HIDE_DELAY;
|
||||||
if (alertEl.dataset.decay) {
|
if (alertElement.dataset.decay) {
|
||||||
autoHideDelay = parseInt(alertEl.dataset.decay, 10);
|
autoHideDelay = parseInt(alertElement.dataset.decay, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
var closeEl = alertEl.querySelector('.' + ALERT_CLOSER_CLASS);
|
var closeEl = alertElement.querySelector('.' + ALERT_CLOSER_CLASS);
|
||||||
closeEl.addEventListener('click', function() {
|
closeEl.addEventListener('click', function() {
|
||||||
toggleAlert(alertEl);
|
toggleAlert(alertElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (autoHideDelay > 0 && alertEl.matches(ALERT_AUTOCLOSING_MATCHER)) {
|
if (autoHideDelay > 0 && alertElement.matches(ALERT_AUTOCLOSING_MATCHER)) {
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
toggleAlert(alertEl);
|
toggleAlert(alertElement);
|
||||||
}, autoHideDelay * 1000);
|
}, autoHideDelay * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
alertEl.classList.add(JS_INITIALIZED_CLASS);
|
alertElement.classList.add(ALERTS_INITIALIZED_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAlert(alertEl, visible) {
|
function toggleAlert(alertEl, visible) {
|
||||||
@ -80,17 +138,19 @@
|
|||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
togglerEl.classList.toggle(ALERTS_TOGGLER_VISIBLE_CLASS, alertsHidden);
|
togglerElement.classList.toggle(ALERTS_TOGGLER_VISIBLE_CLASS, alertsHidden);
|
||||||
togglerCheckRequested = false;
|
togglerCheckRequested = false;
|
||||||
}, ALERTS_TOGGLER_APPEAR_DELAY);
|
}, ALERTS_TOGGLER_APPEAR_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
initToggler();
|
return init();
|
||||||
alertElements.forEach(initAlert);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scope: alertsEl,
|
|
||||||
destroy: function() {},
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (UtilRegistry) {
|
||||||
|
UtilRegistry.register({
|
||||||
|
name: ALERTS_UTIL_NAME,
|
||||||
|
selector: ALERTS_UTIL_SELECTOR,
|
||||||
|
setup: alertsUtil,
|
||||||
|
});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<div #alerts-1 .alerts> <!-- make wIdent work here instead of '#alerts-1' -->
|
<div #alerts-1 .alerts uw-alerts>
|
||||||
<div .alerts__toggler>
|
<div .alerts__toggler>
|
||||||
$forall (status, msg) <- mmsgs
|
$forall (status, msg) <- mmsgs
|
||||||
$with status2 <- bool status "info" (status == "")
|
$with status2 <- bool status "info" (status == "")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user