import { documentReady } from '../function/document-ready.function'; declare var beslist_tracking_admin_config: { advertiserIDsFieldID: string, urlInputPlaceholder: string, advertiserIDInputPlaceholder: string, removeButtonLabel: string, }; declare var document: Document; export class BeslistAdvertiserIDListItem { public isPrimary: boolean; public element: HTMLLIElement; public urlInputLabel: HTMLLabelElement; public urlInput: HTMLInputElement; public advertiserIDInputLabel: HTMLLabelElement; public advertiserIDInput: HTMLInputElement; public removeButton?: HTMLInputElement; constructor(listItemElement: HTMLLIElement) { this.element = listItemElement; this.isPrimary = this.element.classList.contains('beslist-tracking__advertiser-id-list-item-primary'); this.urlInputLabel = this.element.querySelector('label[data-beslist-tracking-url-input-label]') as HTMLLabelElement; this.urlInput = this.element.querySelector('input[data-beslist-tracking-url-input]') as HTMLInputElement; this.advertiserIDInputLabel = this.element.querySelector('label[data-beslist-tracking-advertiser-id-input-label]') as HTMLLabelElement; this.advertiserIDInput = this.element.querySelector('input[data-beslist-tracking-advertiser-id-input]') as HTMLInputElement; this.removeButton = this.element.querySelector('input[data-beslist-tracking-remove-advertiser-id]') as HTMLInputElement || undefined; } public static createInstance(index: number): BeslistAdvertiserIDListItem { const itemElement = document.createElement('li'); itemElement.classList.add('beslist-tracking__advertiser-id-list-item'); itemElement.classList.add('row'); itemElement.classList.add('align-items-center'); itemElement.classList.add('mb-5'); itemElement.classList.add('mb-md-2'); const urlInputLabel = document.createElement('label'); urlInputLabel.htmlFor = BeslistAdvertiserIDListItem.generateUrlInputID(index); urlInputLabel.innerText = beslist_tracking_admin_config.urlInputPlaceholder; urlInputLabel.dataset.beslistTrackingUrlInputLabel = ''; urlInputLabel.classList.add('beslist-tracking__url-label'); urlInputLabel.classList.add('col-auto'); itemElement.append(urlInputLabel); const urlInputContainer = document.createElement('div'); urlInputContainer.classList.add('col-md-3'); urlInputContainer.classList.add('mb-3'); urlInputContainer.classList.add('mb-md-0'); const urlInput = document.createElement('input'); urlInput.type = 'text'; urlInput.value = ''; urlInput.required = true; urlInput.dataset.beslistTrackingUrlInput = ''; urlInput.name = this.generateUrlInputName(index); urlInput.id = this.generateUrlInputID(index); urlInput.classList.add('beslist-tracking__url-input'); urlInputContainer.append(urlInput); itemElement.append(urlInputContainer); const advertiserIDInputLabel = document.createElement('label'); advertiserIDInputLabel.htmlFor = this.generateAdvertiserIDInputID(index); advertiserIDInputLabel.innerText = beslist_tracking_admin_config.advertiserIDInputPlaceholder; advertiserIDInputLabel.dataset.beslistTrackingAdvertiserIdInputLabel = ''; advertiserIDInputLabel.classList.add('beslist-tracking__advertiser-id-label'); advertiserIDInputLabel.classList.add('col-12'); advertiserIDInputLabel.classList.add('col-md-auto'); itemElement.append(advertiserIDInputLabel); const advertiserIDInputContainer = document.createElement('div'); advertiserIDInputContainer.classList.add('col-6'); advertiserIDInputContainer.classList.add('col-md-3'); const advertiserIDInput = document.createElement('input'); advertiserIDInput.type = 'text'; advertiserIDInput.value = ''; advertiserIDInput.required = true; advertiserIDInput.dataset.beslistTrackingAdvertiserIdInput = ''; advertiserIDInput.name = this.generateAdvertiserIDInputName(index); advertiserIDInput.id = this.generateAdvertiserIDInputID(index); advertiserIDInput.classList.add('beslist-tracking__advertiser-id-input'); advertiserIDInputContainer.append(advertiserIDInput); itemElement.append(advertiserIDInputContainer); const removeButtonContainer = document.createElement('div'); removeButtonContainer.classList.add('col'); const removeButton = document.createElement('input'); removeButton.type = 'button'; removeButton.classList.add('beslist-tracking__button'); removeButton.classList.add('beslist-tracking__button_warn'); removeButton.value = beslist_tracking_admin_config.removeButtonLabel; removeButton.dataset.beslistTrackingRemoveAdvertiserId = JSON.stringify(index); removeButtonContainer.append(removeButton); itemElement.append(removeButtonContainer); return new BeslistAdvertiserIDListItem(itemElement); } public static generateUrlInputID(index: number): string { return 'beslist-tracking__url-input-' + index; } public static generateUrlInputName(index: number): string { return beslist_tracking_admin_config.advertiserIDsFieldID + '[' + index + '][url]'; } public static generateAdvertiserIDInputID(index: number): string { return 'beslist-tracking__advertiser-id-input-' + index; } public static generateAdvertiserIDInputName(index: number): string { return beslist_tracking_admin_config.advertiserIDsFieldID + '[' + index + '][advertiser_id]'; } } export class BeslistAdvertiserIdInputList { public element: HTMLUListElement; public enableToggle?: HTMLInputElement; public isEnabled: boolean; public addButtons: HTMLElement[]; public listItems: BeslistAdvertiserIDListItem[]; public testFormElements: HTMLElement[]; public infoContainerElements: HTMLElement[]; constructor(listElement: HTMLUListElement) { this.element = listElement; this.enableToggle = document.querySelector('input[type="checkbox"][data-beslist-tracking-enable-advertiser-id-list="' + this.element.id + '"]') as HTMLInputElement || undefined; this.isEnabled = this.enableToggle ? this.enableToggle.checked : true; this.addButtons = Array.from(document.querySelectorAll('[data-beslist-tracking-add-advertiser-id="' + this.element.id + '"]') as NodeListOf); this.listItems = Array.from(this.element.querySelectorAll('li') as NodeListOf).map(itemElement => new BeslistAdvertiserIDListItem(itemElement)); this.testFormElements = Array.from(document.querySelectorAll('[data-beslist-tracking-advertiser-id-test-form="' + this.element.id + '"]') as NodeListOf); this.infoContainerElements = Array.from(document.querySelectorAll('[data-beslist-tracking-advertiser-id-list-info="' + this.element.id + '"]') as NodeListOf); this.initializeEnableToggleListeners(); this.initializeAddButtonListeners(); this.initializeRemoveButtonListeners(); this.initializeTestFormListeners(); } private enableList(): void { this.isEnabled = true; this.element.classList.remove('beslist-tracking__advertiser-id-list-disabled'); this.addButtons.forEach((addButton) => { addButton.classList.remove('beslist-tracking_display-none'); }); this.infoContainerElements.forEach((infoContainer) => { infoContainer.classList.remove('beslist-tracking_display-none'); }); } private disableList(): void { this.isEnabled = false; this.element.classList.add('beslist-tracking__advertiser-id-list-disabled'); this.listItems = this.listItems.filter((listItem) => { if (!listItem.isPrimary) { listItem.element.remove(); return false; } return true; }); this.addButtons.forEach((addButton) => { addButton.classList.add('beslist-tracking_display-none'); }); this.infoContainerElements.forEach((infoContainer) => { infoContainer.classList.add('beslist-tracking_display-none'); }); } private initializeEnableToggleListeners(): void { if (!this.enableToggle) { return; } const toggleElement = this.enableToggle; toggleElement.addEventListener('change', () => { this.isEnabled = toggleElement.checked; if (this.isEnabled) { this.enableList(); } else { this.disableList(); } }); } private initializeAddButtonListeners(): void { this.addButtons.forEach((addButton) => { addButton.addEventListener('click', () => { this.addListItem(); }); }); } private initializeRemoveButtonListeners(): void { this.listItems.forEach((listItem) => { this.initializeRemoveButtonListener(listItem); }); } private initializeRemoveButtonListener(listItem: BeslistAdvertiserIDListItem): void { listItem.removeButton?.addEventListener('click', () => this.removeListItem(listItem.element)); } private initializeTestFormListeners(): void { this.testFormElements.forEach((testFormElement) => { const testButton = testFormElement.querySelector('input[type="button"]') as HTMLInputElement || undefined; if (!testButton) { return; } testButton.addEventListener('click', () => { this.listItems.forEach((listItem) => { listItem.element.classList.remove('url-tested-positive'); }); const url = testFormElement.querySelector('[type="url"]'); if (!(url instanceof HTMLInputElement)) { throw new Error('Url input not found in advertiserID test form.'); } let positiveListItem: BeslistAdvertiserIDListItem | null = null; for (let listItem of this.listItems) { const regex = new RegExp(listItem.urlInput.value); if (regex.test(url.value)) { positiveListItem = listItem; } } if (positiveListItem) { positiveListItem.element.classList.add('url-tested-positive'); } }); }); } private addListItem(): void { if (this.listItems.length > 20) { return; } const listItem = BeslistAdvertiserIDListItem.createInstance(this.listItems.length); this.initializeRemoveButtonListener(listItem); this.element.append(listItem.element); this.listItems.push(listItem); } private removeListItem(itemElement: HTMLLIElement): void { this.listItems = this.listItems.filter((listItem) => { return listItem.element !== itemElement; }); this.element.removeChild(itemElement); this.resetNameIndices(); } private resetNameIndices(): void { this.listItems.forEach((listItem, index) => { listItem.urlInput.name = BeslistAdvertiserIDListItem.generateUrlInputName(index); listItem.advertiserIDInput.name = BeslistAdvertiserIDListItem.generateAdvertiserIDInputName(index); }); } } export class BeslistAdvertiserIdInputHandler { constructor() { document.querySelectorAll('ul[data-beslist-tracking-advertiser-id-list]').forEach(listElement => new BeslistAdvertiserIdInputList(listElement as HTMLUListElement)); } } documentReady(() => { new BeslistAdvertiserIdInputHandler(); });