UNPKG

@cocreate/conditional-logic

Version:

Simple JS component show & hide elements conditionally with inputs,checkbox,radio,btn etc.Great for creating tabs, accordions, dynamic forms, etc. Easy Configuration using HTML5 data attributes and/or JavaScript API.

142 lines (119 loc) 4.57 kB
/* * https://cocreate.app * https://github.com/CoCreate-app/CoCreate-conditional-logic * Released under the MIT license * https://github.com/CoCreate-app/CoCreate-conditional-logic/blob/master/LICENSE */ /*globals CustomEvent, CoCreate*/ import observer from '@cocreate/observer'; import action from '@cocreate/actions'; import { queryElements } from '@cocreate/utils'; // TODO: update to listen to document events, find closest action return function init() { let elements = document.querySelectorAll(`[show],[hide]`); initElements(elements); } function initElements(elements) { for (let el of elements) initElement(el); } function initElement(el) { if (el.tagName.toLowerCase() == "option") el = el.closest('select'); let actions = el.getAttribute('actions'); if (actions && actions.includes('validate')) { el.removeEventListener('change', selectShowHideEle); el.addEventListener("change", selectShowHideEle); } else { el.removeEventListener('change', selectShowHideEle); el.removeEventListener("click", clickShowHideEle); el.addEventListener("change", selectShowHideEle); el.addEventListener("click", clickShowHideEle); } } function selectShowHideEle(e) { e.preventDefault(); var select = this; if (typeof select.options != 'undefined') for (var i = 0, len = select.options.length; i < len; i++) { var opt = select.options[i]; var value = opt.value; if (value != '') { var show = opt.getAttribute('show'); if (typeof show != 'undefined') { for (let el of queryElements({ element: document, selector: show, type: 'selector' })) el.setAttribute('hidden', ''); if (opt.selected === true) { for (let el of queryElements({ element: document, selector: show, type: 'selector' })) el.removeAttribute('hidden'); } } } } } function clickShowHideEle(e) { let element = e.currentTarget; if (!element) element = e; var show = element.getAttribute('show'); var hide = element.getAttribute('hide'); let tagName = element.tagName.toLowerCase(); if (tagName == 'input' && element.getAttribute("type").toLowerCase() == 'radio') { let key = element.getAttribute("key"); let radios = document.querySelectorAll(tagName + '[key="' + key + '"]'); for (let radio of radios) { show = radio.getAttribute('show'); for (let el of queryElements({ element: document, selector: show, type: 'selector' })) el.setAttribute('hidden', ''); if (radio.checked) { for (let el of queryElements({ element: document, selector: show, type: 'selector' })) el.removeAttribute('hidden'); } } } else { let updated_els = []; if (show) for (let el of queryElements({ element: document, selector: show, type: 'selector' })) { if (el.hasAttribute('hidden')) { el.removeAttribute('hidden'); updated_els.push(el); } } if (hide) for (let el of queryElements({ element: document, selector: hide, type: 'selector' })) { let existEqual = false; for (let uel of updated_els) { if (el.isEqualNode(uel)) { existEqual = true; break; } } if (!existEqual) el.setAttribute('hidden', '') } } document.dispatchEvent(new CustomEvent('showHide', { detail: {} })); } document.addEventListener('fetchedData', () => { init(); }); observer.init({ name: 'CoCreateConditionalLogic', observe: ['addedNodes'], selector: '[show], [hide]', callback: function (mutation) { initElement(mutation.target); } }); action.init({ name: "showHide", endEvent: "showHide", callback: (data) => { clickShowHideEle(data.element); } }); init(); const CoCreateConditionalLogic = { initElements, selectShowHideEle, clickShowHideEle }; export default CoCreateConditionalLogic;