/** * Create a control to show or hide values * * Possible options are: * * - froms: an Element, an Array of Element, or a NodeList. A * listener will be attached to **all** input of those elements * and will trigger the check on changes * - test: a function which will test the element and will return true * if the content must be shown, false if it must be hidden. * The function will receive the `froms` as first argument, and the * event as second argument. * - container: an Element, an Array of Element, or a Node List. The * child nodes will be hidden / shown inside this container * - event_name: the name of the event to listen to. `'change'` by default. * * @param object options */ var ShowHide = function(options) { var froms = typeof options.froms[Symbol.iterator] === "function" ? options.froms : [ options.froms ], //options.froms; test = options.test, container = typeof options.container[Symbol.iterator] === "function" ? options.container : [ options.container ], is_shown = true, event_name = 'event_name' in options ? options.event_name : 'change', container_content = [], debug = 'debug' in options ? options.debug : false, load_event = 'load_event' in options ? options.load_event : 'load', id = 'uid' in options ? options.id : Math.random(); var bootstrap = function(event) { if (debug) { console.log('debug is activated on this show-hide', this); } // keep the content in memory for (let c of container.values()) { let contents = []; for (let el of c.childNodes.values()) { contents.push(el); } container_content.push(contents); } // attach the listener on each input for (let f of froms.values()) { let inputs = f.querySelectorAll('input'); for (let input of inputs.values()) { if (debug) { console.log('attaching event to input', input); } input.addEventListener(event_name, function(e) { onChange(e); }); } } // first launch of the show/hide onChange(event); }; var onChange = function (event) { var result = test(froms, event), me; if (result === true) { if (is_shown === false) { forceShow(); me = new CustomEvent('show-hide-show', { detail: { id: id, container: container, froms: froms } }); window.dispatchEvent(me); } } else if (result === false) { if (is_shown) { forceHide(); me = new CustomEvent('show-hide-hide', { detail: { id: id, container: container, froms: froms } }); window.dispatchEvent(me); } } else { throw "the result of test is not a boolean"; } }; var forceHide = function() { if (debug) { console.log('force hide'); } for (let contents of container_content.values()) { for (let el of contents.values()) { el.remove(); } } is_shown = false; }; var forceShow = function() { if (debug) { console.log('show'); } for (let i of container_content.keys()) { var contents = container_content[i]; for (let el of contents.values()) { container[i].appendChild(el); } } is_shown = true; }; var forceCompute = function(event) { onChange(event); }; if (load_event !== null) { window.addEventListener('load', bootstrap); } else { bootstrap(null); } return { forceHide: forceHide, forceShow: forceShow, forceCompute: forceCompute, }; }; export {ShowHide};