132 lines
4.2 KiB
TypeScript

/**
* 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.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 => {
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<HTMLButtonElement> = document.querySelectorAll("button[data-collection-add-target]"),
collections: NodeListOf<HTMLUListElement> = 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<HTMLLIElement> = 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]);
}
}
});