(() => { const root = document.getElementById('fx-rates-currencies'); if (!root) { return; } const page = JSON.parse(root.dataset.page || '{}'); const currencies = Array.isArray(page.currencies) ? page.currencies : []; const selected = new Set( (Array.isArray(page.preferred_currencies) ? page.preferred_currencies : []) .map((code) => String(code || '').trim().toUpperCase()) .filter(Boolean) ); let displayBase = String(page.display_base_currency || '').trim().toUpperCase(); const nodes = { tokenList: root.querySelector('[data-fx-token-list]'), searchInput: root.querySelector('[data-fx-search-input]'), suggestions: root.querySelector('[data-fx-suggestions]'), displayBaseSelect: root.querySelector('[data-fx-display-base-select]'), displayBaseHidden: root.querySelector('[data-fx-display-base-hidden]'), hiddenPreferred: root.querySelector('[data-fx-hidden-preferred]'), }; const escapeHtml = (value) => String(value || '') .replaceAll('&', '&') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('"', '"') .replaceAll("'", '''); const currencyByCode = new Map( currencies.map((currency) => [String(currency.code || '').toUpperCase(), currency]) ); const sortedSelectedCodes = () => Array.from(selected).sort((left, right) => left.localeCompare(right)); const ensureDisplayBase = () => { const available = sortedSelectedCodes(); if (available.length === 0) { displayBase = ''; return; } if (!displayBase || !selected.has(displayBase)) { displayBase = available[0]; } }; const renderHiddenInputs = () => { if (!nodes.hiddenPreferred) { return; } nodes.hiddenPreferred.innerHTML = sortedSelectedCodes() .map((code) => ``) .join(''); if (nodes.displayBaseHidden) { nodes.displayBaseHidden.value = displayBase; } }; const renderDisplayBase = () => { if (!nodes.displayBaseSelect) { return; } ensureDisplayBase(); const available = sortedSelectedCodes(); nodes.displayBaseSelect.innerHTML = available.length ? available.map((code) => ``).join('') : ''; nodes.displayBaseSelect.disabled = available.length === 0; }; const removeCode = (code) => { selected.delete(code); renderAll(); }; const renderTokens = () => { if (!nodes.tokenList) { return; } const selectedCodes = sortedSelectedCodes(); if (selectedCodes.length === 0) { nodes.tokenList.innerHTML = '
Noch keine bevorzugten Waehrungen ausgewaehlt.
'; return; } nodes.tokenList.innerHTML = selectedCodes.map((code) => { const currency = currencyByCode.get(code) || { code, name: code }; return ` `; }).join(''); nodes.tokenList.querySelectorAll('[data-remove-code]').forEach((button) => { button.addEventListener('click', () => { removeCode(String(button.getAttribute('data-remove-code') || '').toUpperCase()); }); }); }; const renderSuggestions = () => { if (!nodes.suggestions || !nodes.searchInput) { return; } const needle = String(nodes.searchInput.value || '').trim().toLowerCase(); if (!needle) { nodes.suggestions.innerHTML = ''; return; } const matches = currencies .filter((currency) => !selected.has(String(currency.code || '').toUpperCase())) .filter((currency) => { const code = String(currency.code || '').toLowerCase(); const name = String(currency.name || '').toLowerCase(); return code.includes(needle) || name.includes(needle); }) .slice(0, 12); nodes.suggestions.innerHTML = matches.map((currency) => ` `).join(''); nodes.suggestions.querySelectorAll('[data-add-code]').forEach((button) => { button.addEventListener('click', () => { const code = String(button.getAttribute('data-add-code') || '').toUpperCase(); if (code) { selected.add(code); if (nodes.searchInput) { nodes.searchInput.value = ''; } renderAll(); } }); }); }; const renderAll = () => { ensureDisplayBase(); renderTokens(); renderDisplayBase(); renderHiddenInputs(); renderSuggestions(); }; nodes.searchInput?.addEventListener('input', renderSuggestions); nodes.displayBaseSelect?.addEventListener('change', () => { displayBase = String(nodes.displayBaseSelect?.value || '').trim().toUpperCase(); renderHiddenInputs(); }); renderAll(); })();