/** * 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'; export class CollectionEventPayload { collection: HTMLUListElement; entry: HTMLLIElement; constructor(collection: HTMLUListElement, entry: HTMLLIElement) { this.collection = collection; this.entry = entry; } } export const handleAdd = (button: any): void => { let form_name = button.dataset.collectionAddTarget, prototype = button.dataset.formPrototype, collection: HTMLUListElement | null = document.querySelector('ul[data-collection-name="' + form_name + '"]'); if (collection === null) { return; } let empty_explain: HTMLLIElement | null = collection.querySelector('li[data-collection-empty-explain]'), entry = document.createElement('li'), counter = collection.childNodes.length + 1, content = prototype.replace(new RegExp('__name__', 'g'), counter.toString()), event = new CustomEvent('collection-add-entry', {detail: new CollectionEventPayload(collection, entry)}); entry.innerHTML = content; entry.classList.add('entry'); if ("dataCollectionRegular" 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 => { let 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; } window.addEventListener('load', () => { let 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++) { let addButton = addButtons[i]; addButton.addEventListener('click', (e: Event) => { e.preventDefault(); handleAdd(e.target); }); } for (let i = 0; i < collections.length; i++) { let entries: NodeListOf = collections[i].querySelectorAll(':scope > li'); for (let j = 0; j < entries.length; j++) { if (entries[j].dataset.collectionEmptyExplain === "1") { continue; } initializeRemove(collections[i], entries[j]); } } });