UNPKG

popin

Version:
234 lines (198 loc) 7.54 kB
/** * Popin class. * @class Popin */ class Popin { /** * Represents an Popin instance. * @constructs Popin * @param {Object} options - Options to configure the plugin * @param {string} options.input - Selector of the input to bind * @param {Array} [options.data] - Data to use */ constructor( params ) { var defaultParams = { overlay : true } if(params) { for (var key in params) { if (defaultParams.hasOwnProperty(key)) { defaultParams[key] = params[key]; } } } this.popins = document.querySelectorAll(defaultParams && defaultParams.popin ? defaultParams.popin : '.js-popin'); this.isDevice = 'ontouchstart' in document.documentElement; this.instanciedPopins = []; this.instanciedPopinsOptions = []; this.openedPopins = []; /** create overlay when params.overlay is true */ if(defaultParams.overlay){ var overlay = document.createElement('div'); overlay.id = 'popin-overlay'; overlay.className = 'popin-overlay'; document.body.appendChild(overlay); this.overlay = document.getElementById('popin-overlay'); this.overlay.addEventListener('click', (e) => { var popinOptions = this.instanciedPopinsOptions[this.openedPopins[this.openedPopins.length-1]]; this.close(popinOptions); }, false); } } /** init generic popins ans specifique if selector is past in arg */ init(options) { var defaultOptions = { overlayVisible : true, closeButton : true, buttonSticky:false, beforeOpen:null, afterOpen:null, beforeClose:null, afterClose:null, disableAfterClose:null } if(options) { for (var key in options) { if (options.hasOwnProperty(key)) { defaultOptions[key] = options[key]; } } } var _this = this; if(defaultOptions.className) { this[defaultOptions.className] = document.querySelectorAll('.'+defaultOptions.className); } [].forEach.call((this[defaultOptions.className]) ? this[defaultOptions.className] : this.popins, (popin, i) => { var elements = { overlayVisible : defaultOptions.overlayVisible, closeButton : defaultOptions.closeButton, buttonSticky : defaultOptions.buttonSticky, popinId : (defaultOptions.content) ? 'popin-'+this.instanciedPopins.length : popin.getAttribute('data-target'), beforeOpen : defaultOptions.beforeOpen, afterOpen : defaultOptions.afterOpen, beforeClose : defaultOptions.beforeClose, afterClose : defaultOptions.afterClose, disableAfterClose : defaultOptions.disableAfterClose, link : popin, firstOpen : true }; /** if content is past in params add content to body */ if(defaultOptions.content){ var div = document.createElement('div'); div.id = 'popin-'+this.instanciedPopins.length; div.className = "popin"; div.innerHTML = defaultOptions.content document.body.appendChild(div); } popin.setAttribute('data-popin-id',this.instanciedPopins.length); popin.setAttribute('data-className',defaultOptions.className ? defaultOptions.className :'js-popin' ); this.instanciedPopins.push(elements.popinId); this.instanciedPopinsOptions.push(elements); popin.addEventListener('click',event => { event.preventDefault(); event.stopPropagation(); var el = popin; this.open(event,el ,this.instanciedPopinsOptions[ el.getAttribute('data-popin-id')]); } ,false); }); } click(){ } /** METHODE */ open(e, currentPopin, options) { //if the popin is disable break; if(currentPopin.getAttribute('data-disable')) { return false; } //if there is a opened popin close it temporary if(this.openedPopins.length > 0){ document.getElementById(this.instanciedPopins[this.openedPopins.length-1]).classList.add('popin--closeJs'); } //execute callback before openning popin if(options.beforeOpen && typeof options.beforeOpen == "function") { options.beforeOpen(currentPopin); } //popin Div var popinDiv = document.getElementById(options.popinId); //show overlay when options.overlay true => default : true if(options.overlayVisible && this.openedPopins.length == 0){ this.overlay.classList.add('popin-overlay--visible'); } //add popin to table memory of opened popin this.openedPopins.push(currentPopin.getAttribute('data-popin-id')); //show the popin var windowHeight = document.documentElement.clientHeight, popinHeight = popinDiv.clientHeight, popinOffset = this.getOffset(currentPopin), popinTop = (options.buttonSticky) ? popinOffset.top + 'px' : document.body.scrollTop + 20 + 'px'; if(options.buttonSticky || popinHeight > windowHeight) { //Popin is bigenouth screen height popinDiv.style.top = popinTop; popinDiv.classList.add('popin--openJs'); } else { //popin fit in screen popinDiv.classList.add('popin--open'); } //bind closing event if(options.closeButton && options.firstOpen){ options.firstOpen = false; var closeBtn = popinDiv.querySelectorAll('.js-popin-linkClose'); [].forEach.call(closeBtn, (button, i) => { button.addEventListener('click', (event) => { event.preventDefault(); event.stopPropagation(); //open the popin this.close(options); }); }); } //execute callback after openning popin if(options.afterOpen && typeof options.afterOpen == "function") { options.afterOpen(); } } getOffset(el) { var rect = el.getBoundingClientRect(); return { top: rect.top + document.body.scrollTop, left: rect.left + document.body.scrollLeft }; } close(options) { if(!options) { var options = {} } //execute callback before closing popin if(options.beforeClose && typeof options.beforeClose == "function") { options.beforeClose(); } //close the current popin var currentPopin = this.openedPopins[this.openedPopins.length-1]; var popinDiv = document.getElementById(this.instanciedPopins[currentPopin]); popinDiv.classList.remove('popin--open','popin--openJs'); popinDiv.style.top = ''; this.openedPopins.splice(this.openedPopins.length-1,1); //open last opened popin if(this.openedPopins.length > 0){ document.getElementById(this.instanciedPopins[this.openedPopins.length-1]).classList.remove('popin--closeJs'); } //hide overlay if(this.openedPopins.length == 0) { this.overlay.classList.remove('popin-overlay--visible'); } //execute callback after closing popin if(options.afterClose && typeof options.afterClose == "function") { options.afterClose(); } //disable the popin this.disable(currentPopin); } disable(currentPopin) { var popinOptions = this.instanciedPopinsOptions[currentPopin]; var link = document.querySelector('[data-popin-id="'+currentPopin+'"]'); if(popinOptions.disableAfterClose){ link.setAttribute('data-disable', true) } } }; export default Popin;