import supportDom from '../decorators/supportDom' import { noop } from '../utils' import domEval from '../utils/domEval'
let globalModalId = 0
@supportDom export default class Modal {
constructor(dom, options = {}) { this.dom = dom this.isVisible = false this.modalId = null this.options = options this.options.cancel = options.cancel || noop this.options.confirm = options.confirm || noop this.init() } init() { this.bindEvents() } bindEvents() { this.setModalDom() this.closeBtn = this.modal.querySelector('[data-close]') this.cancelBtn = this.modal.querySelector('[data-cancel]') this.confirmBtn = this.modal.querySelector('[data-confirm]') this.addEvents() } setModalDom() { const { modalOpener, modal } = this.dom.dataset if (modalOpener) { this.modalId = this.dom.dataset.modalOpener const selector = `[data-modal="${this.modalId}"]` this.modal = document.querySelector(selector) return } if (modal) { this.modalId = modal } else { this.modalId = `modal-${++globalModalId}` this.dom.dataset.modal = this.modalId } this.modal = this.dom } triggerShowEventIfNeeded() { if (typeof $ === 'function') { $(this.dom).trigger('beyond.modal.show') } } show(html) { if (this.isVisible && html) { this.replace(html) this.modal.classList.add('js-active') this.modal.style.display = 'block' return this.triggerShowEventIfNeeded() } if (html) { this.replace(html) } this.isVisible = true this.modal.style.display = 'block' setTimeout(() => { this.modal.classList.add('js-active') this.triggerShowEventIfNeeded() }, 50) } hide() { this.isVisible = false this.modal.classList.remove('js-active') setTimeout(() => { this.modal.style.display = 'none' if (typeof $ === 'function') { $(this.dom).trigger('beyond.modal.hide') } }, 300) } replace(html) { this.destroy() this.modalId = null // replace with new dom const div = document.createElement('div') div.innerHTML = html.trim() const dom = div.firstChild // keep the id that is created by $.uniqModal() const originalDomId = this.dom.id if (originalDomId === 'beyond-uniq-modal') { dom.id = originalDomId } this.dom.parentNode.replaceChild(dom, this.dom) this.dom = dom this.dom._modal = this this.init() Array.from(dom.querySelectorAll('script')) .forEach(script => domEval(script.text)) } visible() { return this.isVisible } addEventIfDomExists(dom, event, cb) { if (dom) { this.addEvent(dom, event, cb) } } addEvents() { if (this.dom.dataset.modalOpener) { this.addEventIfDomExists(this.dom, 'click', () => this.show()) } this.addEventIfDomExists(this.closeBtn, 'click', () => { this.hide() this.options.cancel('close') }) this.addEventIfDomExists(this.cancelBtn, 'click', () => { this.hide() this.options.cancel('cancel') }) this.addEventIfDomExists(this.modal, 'click', event => { // is backdrop if (event.target.dataset.modal === this.modalId) { this.hide() this.options.cancel('backdrop') } }) this.addEventIfDomExists(this.confirmBtn, 'click', () => { if (typeof this.options.confirm === 'function') { this.options.confirm() } else { this.hide() } }) }
}