/** * Javascript file which handle ChillCollectionType * * Two events are emitted by this module, both on window and on collection / ul. * * Collection (an UL element) and entry (a li element) are associated with those * events. * * ``` * window.addEventListener('collection-add-entry', function(e) { * console.log(e.detail.collection); * console.log(e.detail.entry); * }); * * window.addEventListener('collection-remove-entry', function(e) { * console.log(e.detail.collection); * console.log(e.detail.entry); * }); * * collection.addEventListener('collection-add-entry', function(e) { * console.log(e.detail.collection); * console.log(e.detail.entry); * }); * * collection.addEventListener('collection-remove-entry', function(e) { * console.log(e.detail.collection); * console.log(e.detail.entry); * }); * ``` */ import "./collection.scss"; declare global { interface GlobalEventHandlersEventMap { "show-hide-show": CustomEvent<{ id: number; froms: HTMLElement[]; container: HTMLElement; }>; } } export class CollectionEventPayload { collection: HTMLUListElement; entry: HTMLLIElement; constructor(collection: HTMLUListElement, entry: HTMLLIElement) { this.collection = collection; this.entry = entry; } } export const handleAdd = (button: any): void => { const form_name = button.dataset.collectionAddTarget, prototype = button.dataset.formPrototype, collection: HTMLUListElement | null = document.querySelector( 'ul[data-collection-name="' + form_name + '"]', ); if (collection === null) { return; } const empty_explain: HTMLLIElement | null = collection.querySelector( "li[data-collection-empty-explain]", ), entry = document.createElement("li"), counter = collection.querySelectorAll("li.entry").length, // Updated counter logic content = prototype.replace(/__name__/g, counter.toString()), event = new CustomEvent("collection-add-entry", { detail: new CollectionEventPayload(collection, entry), }); console.log(counter); console.log(content); entry.innerHTML = content; entry.classList.add("entry"); if ("collectionRegular" in collection.dataset) { initializeRemove(collection, entry); if (empty_explain !== null) { empty_explain.remove(); } } collection.appendChild(entry); collection.dispatchEvent(event); window.dispatchEvent(event); }; const initializeRemove = ( collection: HTMLUListElement, entry: HTMLLIElement, ): void => { const button = buildRemoveButton(collection, entry); if (null === button) { return; } entry.appendChild(button); }; export const buildRemoveButton = ( collection: HTMLUListElement, entry: HTMLLIElement, ): HTMLButtonElement | null => { const button = document.createElement("button"), isPersisted = entry.dataset.collectionIsPersisted || "", content = collection.dataset.collectionButtonRemoveLabel || "", allowDelete = collection.dataset.collectionAllowDelete || "", event = new CustomEvent("collection-remove-entry", { detail: new CollectionEventPayload(collection, entry), }); if (allowDelete === "0" && isPersisted === "1") { return null; } button.classList.add("btn", "btn-delete", "remove-entry"); button.textContent = content; button.addEventListener("click", (e: Event) => { e.preventDefault(); entry.remove(); collection.dispatchEvent(event); window.dispatchEvent(event); }); return button; }; const collectionsInit = new Set(); const buttonsInit = new Set(); const initialize = function (target: Document | Element): void { const addButtons: NodeListOf = document.querySelectorAll( "button[data-collection-add-target]", ), collections: NodeListOf = document.querySelectorAll( "ul[data-collection-regular]", ); for (let i = 0; i < addButtons.length; i++) { const addButton = addButtons[i]; const uniqid = addButton.dataset.uniqid as string; if (buttonsInit.has(uniqid)) { continue; } buttonsInit.add(uniqid); addButton.addEventListener("click", (e: Event) => { e.preventDefault(); handleAdd(e.target); }); } for (let i = 0; i < collections.length; i++) { const collection = collections[i]; const uniqid = collection.dataset.uniqid as string; if (collectionsInit.has(uniqid)) { continue; } collectionsInit.add(uniqid); const entries: NodeListOf = collection.querySelectorAll(":scope > li"); for (let j = 0; j < entries.length; j++) { if (entries[j].dataset.collectionEmptyExplain === "1") { continue; } initializeRemove(collections[i], entries[j]); } } }; window.addEventListener("DOMContentLoaded", () => { initialize(document); }); window.addEventListener( "show-hide-show", ( event: CustomEvent<{ id: number; container: HTMLElement; froms: HTMLElement[]; }>, ) => { const container = event.detail.container as HTMLElement; initialize(container); }, );