aboutsummaryrefslogtreecommitdiff
path: root/scripts/src/overlay.js
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/src/overlay.js')
-rw-r--r--scripts/src/overlay.js253
1 files changed, 253 insertions, 0 deletions
diff --git a/scripts/src/overlay.js b/scripts/src/overlay.js
new file mode 100644
index 0000000..b40d911
--- /dev/null
+++ b/scripts/src/overlay.js
@@ -0,0 +1,253 @@
+'use strict';
+/**
+ * @name Novicell overlay
+ * @desc Simple script that opens an overlay / modal with some content form either a selector or an URL
+ * @author Danni Larsen (DLA), Michael Sølvsteen (MSL), Signe Helbo Poulsen (SHP), Emil Skytte Ankersen (EAN)
+ * @example novicell.overlay.create({ 'selector': SELECTOR, 'url': URL, 'class':'CLASSNAME', 'onCreate': FUNCTIONNAME, 'onLoaded': FUNCTIONNAME, 'onDestroy': FUNCTIONNAME });
+ * @requires none
+ */
+
+var novicell = novicell || {};
+
+novicell.overlay = novicell.overlay || new function () {
+ var self = this;
+ var options = {};
+ var overlayElem;
+ var overlayContainer;
+ var overlayContent;
+ var backdrop;
+ var content;
+ var onCreate;
+ var onLoaded;
+ var onDestroy;
+ var isVideo = false;
+
+ this.create = function (opts) {
+ var self = this;
+ // Set global options
+ options = opts;
+
+ // Call onCreate callback
+ if (typeof options.onCreate === 'function') {
+ options.onCreate();
+ }
+
+ // Remove existing overlays
+ self.destroy();
+
+ // Check if content comes from a DOM selector
+ if (options.hasOwnProperty('selector') && options.selector !== null) {
+ var element = document.querySelector(options.selector);
+
+ if (element) {
+ content = element.innerHTML;
+ constructOverlay();
+ } else {
+ console.warn('novicell.overlay: element does not exist. Please provide a valid selector for use in document.querySelector.');
+ return;
+ }
+ }
+
+ // Check if content comes from a HTML element
+ else if (options.hasOwnProperty('element') && options.element !== null) {
+ var element = options.element;
+
+ if (element) {
+ content = element.innerHTML;
+ constructOverlay();
+ } else {
+ console.warn('novicell.overlay: element does not exist. Please provide a valid DOM element.');
+ return;
+ }
+ }
+
+ // Or if content comes from an ID
+ else if (options.hasOwnProperty('videoId')) {
+ if (options.videoId !== null) {
+ var src = '';
+ isVideo = true;
+
+ if(options.type == 'vimeo') {
+ src = 'https://player.vimeo.com/video/' + options.videoId + '?autoplay=' + options.autoplay;
+ }
+ else if(options.type == 'youtube') {
+ src = 'https://www.youtube.com/embed/' + options.videoId + '?autoplay=' + options.autoplay + '&rel=0';
+ }
+ else {
+ return;
+ }
+
+ var iframe = document.createElement('iframe');
+ iframe.setAttribute('src', src);
+ iframe.setAttribute('frameborder', 0);
+ iframe.setAttribute('allowfullscreen', '');
+ iframe.setAttribute('width', '100%');
+ iframe.setAttribute('height', '100%');
+
+ content = iframe.outerHTML;
+
+ constructOverlay();
+ } else {
+ console.warn('novicell.overlay: video-id is empty. Please provide a video-id for use in video embed code (we support only Vimeo and YouTube).');
+ return;
+ }
+ }
+ // If nothing is working, send error to los consolé
+ else {
+ console.error('novicell.overlay: no content to display! Please set a selector or a url to load.')
+ return;
+ }
+ };
+
+ this.destroy = function () {
+ if(document.querySelector('#js-novi-overlay')) {
+ // Remove elements
+ overlayElem.parentElement.removeChild(overlayElem);
+ backdrop.parentElement.removeChild(backdrop);
+
+ // Stop listening for close overlay events
+ document.removeEventListener('keyup', self.destroy);
+
+ // Remove class on body
+ document.documentElement.classList.remove('no-scroll', 'novi-overlay--open');
+
+ // Reset video variable
+ isVideo = false;
+
+ // Call onDestroy callback
+ if (typeof options.onDestroy === 'function') {
+ options.onDestroy();
+ }
+ }
+ };
+
+ function constructOverlay() {
+ // Create backdrop
+ setupBackdrop();
+
+ // Create the overlay
+ setupOverlay();
+
+ // Create content for overlay
+ setupOverlayContainer();
+
+ // Create close button
+ setupCloseButton();
+
+ // Add class to body-element
+ document.documentElement.classList.add('no-scroll');
+
+ // Call onLoaded callback
+ if (typeof options.onLoaded === 'function') {
+ options.onLoaded();
+ }
+ };
+
+ function setupBackdrop() {
+ // Create the backdrop
+ backdrop = document.createElement('div');
+ backdrop.classList.add('novi-backdrop');
+ backdrop.id = 'js-novi-backdrop';
+
+ backdrop.addEventListener('click', function(e){
+ if(e.target.classList.contains('novi-overlay') || e.target.classList.contains('novi-overlay__container')) {
+ self.destroy();
+ }
+ });
+
+ // Add backdrop to overlay element
+ document.querySelector('body').appendChild(backdrop);
+ };
+
+ /*
+ * Helper functions for HTML elements
+ */
+ function setupOverlay() {
+ // Create the overlay
+ overlayElem = document.createElement('div');
+ overlayElem.classList.add('novi-overlay');
+ overlayElem.id = 'js-novi-overlay';
+
+ // Set class for the overlay, if set in options
+ if (options.hasOwnProperty('class')) {
+ overlayElem.classList.add(options.class);
+ }
+
+ // Add overlay to overlay element
+ // document.querySelector('body').appendChild(overlayElem);
+ backdrop.appendChild(overlayElem);
+ };
+
+ function setupOverlayContainer() {
+ // Create content for overlay
+ overlayContainer = document.createElement('div');
+ overlayContainer.classList.add('novi-overlay__container');
+
+ // Create scroll element
+ overlayContent = document.createElement('div');
+ overlayContent.classList.add('novi-overlay__content');
+
+ if(isVideo) {
+ overlayContent.classList.add('novi-overlay__content--video')
+ }
+
+ // Set content
+ overlayContent.innerHTML = content;
+ overlayContainer.appendChild(overlayContent);
+
+ // Add overlayContainer to overlay element
+ overlayElem.appendChild(overlayContainer);
+ };
+
+ function setupCloseButton() {
+ // Create the button
+ var btnClose = document.createElement('button');
+ btnClose.classList.add('novi-overlay-close', 'button--close');
+ btnClose.type = 'button';
+ btnClose.id = 'js-novi-overlay-close';
+
+ // Add eventlistener for button click
+ btnClose.addEventListener('click', self.destroy);
+
+ // Add eventlistener for esc key
+ document.addEventListener('keydown', function (e) {
+ if (e.keyCode === 27) {
+ self.destroy();
+ }
+ });
+
+ // Add close button to overlay element
+ overlayContent.appendChild(btnClose);
+ };
+
+ /*
+ * Helper functions for getting content
+ */
+ function get(url) {
+ // Return a new promise.
+ return new Promise(function (resolve, reject) {
+ // Do the usual XHR stuff
+ var req = new XMLHttpRequest();
+ req.open('GET', url);
+
+ req.onload = function () {
+ if (req.status >= 200 && req.status < 400) {
+ // Success!!
+ resolve(req.response);
+ } else {
+ // Error!!
+ reject(Error(req.statusText));
+ }
+ };
+
+ // Handle network errors
+ req.onerror = function () {
+ reject(Error("Network Error"));
+ };
+
+ // Make the request
+ req.send();
+ });
+ };
+
+}();