MULTI CURRENCY CONVERTER

Multi Currency Converter

MULTI CURRENCY CONVERTER

Updated: Loading…

00:00:00
0
${currencyCode}
${currency.name}
`; currencyContainer.appendChild(row); }); // Add drag and drop event listeners setupDragAndDrop(); // Add event listeners to action icons document.querySelectorAll('.search-currency').forEach(icon => { icon.addEventListener('click', () => openCurrencyModal(icon.dataset.currency)); }); document.querySelectorAll('.swap-currency').forEach(icon => { icon.addEventListener('click', () => swapWithBaseCurrency(icon.dataset.currency)); }); document.querySelectorAll('.remove-currency').forEach(icon => { icon.addEventListener('click', () => removeCurrency(icon.dataset.currency)); }); document.querySelectorAll('.currency-value').forEach(input => { input.addEventListener('click', () => { // When a currency value is clicked, set it as the base for calculations setBaseFromCurrency(input.dataset.currency, input.value); }); input.addEventListener('input', (e) => { // Update base amount when user types in a currency value const value = parseFloat(e.target.value.replace(/[^0-9.-]+/g, "")); if (!isNaN(value)) { updateBaseFromCurrency(input.dataset.currency, value); } }); }); } // Set up drag and drop for currency reordering function setupDragAndDrop() { const rows = document.querySelectorAll('.currency-row'); rows.forEach(row => { row.addEventListener('dragstart', (e) => { e.dataTransfer.setData('text/plain', row.dataset.currency); row.classList.add('dragging'); }); row.addEventListener('dragend', () => { rows.forEach(r => r.classList.remove('dragging', 'drag-over')); }); row.addEventListener('dragover', (e) => { e.preventDefault(); rows.forEach(r => r.classList.remove('drag-over')); row.classList.add('drag-over'); }); row.addEventListener('drop', (e) => { e.preventDefault(); const draggedCurrency = e.dataTransfer.getData('text/plain'); const targetCurrency = row.dataset.currency; if (draggedCurrency !== targetCurrency) { // Reorder currencies const draggedIndex = selectedCurrencies.indexOf(draggedCurrency); const targetIndex = selectedCurrencies.indexOf(targetCurrency); selectedCurrencies.splice(draggedIndex, 1); selectedCurrencies.splice(targetIndex, 0, draggedCurrency); // Save to localStorage localStorage.setItem('selectedCurrencies', JSON.stringify(selectedCurrencies)); // Re-render rows renderCurrencyRows(); updateAllCurrencyValues(); } }); }); } // Calculate value for a specific currency function calculateCurrencyValue(currencyCode, amount) { if (!exchangeRates[currencyCode]) return 0; return amount * exchangeRates[currencyCode]; } // Format currency value with proper formatting function formatCurrencyValue(value) { if (value === 0) return '0'; // For very large values, use exponential notation if (Math.abs(value) >= 1e9) { return value.toExponential(2); } // Format with commas for thousands let formatted = new Intl.NumberFormat('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 6 }).format(value); // Remove trailing zeros after decimal if not needed if (formatted.includes('.')) { formatted = formatted.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, ''); } return formatted; } // Update all currency values based on base amount function updateAllCurrencyValues() { selectedCurrencies.forEach(currencyCode => { const valueElement = document.querySelector(`.currency-value[data-currency="${currencyCode}"]`); if (valueElement) { const calculatedValue = calculateCurrencyValue(currencyCode, baseAmount); valueElement.value = formatCurrencyValue(calculatedValue); } }); } // Set base amount from a currency value function setBaseFromCurrency(currencyCode, valueString) { const value = parseFloat(valueString.replace(/[^0-9.-]+/g, "")); if (!isNaN(value) && exchangeRates[currencyCode]) { baseAmount = value / exchangeRates[currencyCode]; updateCalculationDisplay(baseAmount.toString()); updateAllCurrencyValues(); } } // Update base amount from a currency value function updateBaseFromCurrency(currencyCode, value) { if (!isNaN(value) && exchangeRates[currencyCode]) { baseAmount = value / exchangeRates[currencyCode]; updateAllCurrencyValues(); } } // Swap a currency with the base currency (USD) function swapWithBaseCurrency(currencyCode) { if (currencyCode === 'USD') return; // Find the rate for this currency const rate = exchangeRates[currencyCode]; if (!rate) return; // Swap all rates const newBaseRate = 1 / rate; const usdRate = exchangeRates['USD'] || 1; // Update all rates relative to the new base Object.keys(exchangeRates).forEach(code => { if (code === currencyCode) { exchangeRates[code] = 1; } else { exchangeRates[code] = exchangeRates[code] * newBaseRate; } }); // Update base amount baseAmount = baseAmount * rate; // Update display updateAllCurrencyValues(); // Visual feedback const button = document.querySelector(`.swap-currency[data-currency="${currencyCode}"]`); button.classList.add('button-pressed'); setTimeout(() => button.classList.remove('button-pressed'), 100); } // Remove a currency from the list function removeCurrency(currencyCode) { if (selectedCurrencies.length <= 1) return; // Don't remove the last currency const index = selectedCurrencies.indexOf(currencyCode); if (index !== -1) { selectedCurrencies.splice(index, 1); localStorage.setItem('selectedCurrencies', JSON.stringify(selectedCurrencies)); renderCurrencyRows(); updateAllCurrencyValues(); } } // Open currency selection modal function openCurrencyModal(currentCurrency = null) { currencyModal.style.display = 'flex'; populateCurrencyList(currentCurrency); // Focus on search input setTimeout(() => currencySearch.focus(), 100); } // Populate currency list in modal with all world currencies function populateCurrencyList(currentCurrency = null) { currencyList.innerHTML = ''; const searchTerm = currencySearch.value.toLowerCase(); // Sort currencies by code for easier navigation const sortedCurrencyCodes = Object.keys(allCurrencies).sort(); let foundCurrencies = 0; sortedCurrencyCodes.forEach(currencyCode => { const currency = allCurrencies[currencyCode]; // Skip if already selected (unless it's the current one being changed) if (selectedCurrencies.includes(currencyCode) && currencyCode !== currentCurrency) { return; } // Filter by search term if (searchTerm && !currencyCode.toLowerCase().includes(searchTerm) && !currency.name.toLowerCase().includes(searchTerm)) { return; } foundCurrencies++; const option = document.createElement('div'); option.className = 'currency-option'; if (currencyCode === currentCurrency) { option.classList.add('selected'); } option.dataset.currency = currencyCode; option.innerHTML = `
${currencyCode}
${currency.name}
`; option.addEventListener('click', () => { if (currentCurrency) { // Replace existing currency const index = selectedCurrencies.indexOf(currentCurrency); if (index !== -1) { selectedCurrencies[index] = currencyCode; } } else { // Add new currency selectedCurrencies.push(currencyCode); } localStorage.setItem('selectedCurrencies', JSON.stringify(selectedCurrencies)); renderCurrencyRows(); updateAllCurrencyValues(); closeCurrencyModal(); }); currencyList.appendChild(option); }); // If no currencies found, show message if (foundCurrencies === 0) { const noResults = document.createElement('div'); noResults.className = 'currency-option'; noResults.innerHTML = `
No currencies found matching "${searchTerm}"
`; currencyList.appendChild(noResults); } } // Close currency modal function closeCurrencyModal() { currencyModal.style.display = 'none'; currencySearch.value = ''; } // Calculator functions function updateCalculationDisplay(value) { calcDisplay.textContent = value; currentCalculation = value; } function handleNumberInput(number) { if (currentCalculation === '0' || lastCalculationResult !== null) { updateCalculationDisplay(number); lastCalculationResult = null; } else { updateCalculationDisplay(currentCalculation + number); } // Update base amount and currency values const newValue = parseFloat(currentCalculation + number); if (!isNaN(newValue)) { baseAmount = newValue; updateAllCurrencyValues(); } } function handleOperatorInput(operator) { if (lastCalculationResult !== null) { updateCalculationDisplay(lastCalculationResult + operator); lastCalculationResult = null; } else { updateCalculationDisplay(currentCalculation + operator); } } function handleEquals() { try { // Replace × and ÷ with * and / for evaluation let expression = currentCalculation .replace(/×/g, '*') .replace(/÷/g, '/') .replace(/−/g, '-'); // Handle percentage calculations expression = expression.replace(/(\d+(\.\d+)?)%/g, '($1/100)'); // Evaluate the expression const result = eval(expression); // Update display with result updateCalculationDisplay(formatCurrencyValue(result)); // Update base amount and currency values baseAmount = result; updateAllCurrencyValues(); // Store result for next operation lastCalculationResult = result.toString(); } catch (error) { updateCalculationDisplay('Error'); setTimeout(() => updateCalculationDisplay('0'), 1000); } } function handleClear() { updateCalculationDisplay('0'); baseAmount = 0; updateAllCurrencyValues(); lastCalculationResult = null; } function handleDelete() { if (currentCalculation.length > 1) { const newValue = currentCalculation.slice(0, -1); updateCalculationDisplay(newValue); const newBase = parseFloat(newValue); if (!isNaN(newBase)) { baseAmount = newBase; updateAllCurrencyValues(); } } else { updateCalculationDisplay('0'); baseAmount = 0; updateAllCurrencyValues(); } } function handleDecimal() { if (!currentCalculation.includes('.')) { updateCalculationDisplay(currentCalculation + '.'); } } function handlePlusMinus() { if (currentCalculation.startsWith('-')) { updateCalculationDisplay(currentCalculation.substring(1)); } else { updateCalculationDisplay('-' + currentCalculation); } // Update base amount baseAmount = -baseAmount; updateAllCurrencyValues(); } function handlePercent() { const currentValue = parseFloat(currentCalculation); if (!isNaN(currentValue)) { const percentValue = currentValue / 100; updateCalculationDisplay(percentValue.toString()); baseAmount = percentValue; updateAllCurrencyValues(); lastCalculationResult = percentValue.toString(); } } function handleCopy() { navigator.clipboard.writeText(currentCalculation) .then(() => { // Visual feedback const button = document.querySelector('[data-action="copy"]'); button.innerHTML = ''; setTimeout(() => { button.textContent = 'COPY'; }, 1000); }) .catch(err => { console.error('Failed to copy: ', err); }); } function handleSend() { // In a real app, this would send the calculation to a service alert(`Calculation sent: ${currentCalculation}`); // Visual feedback const button = document.querySelector('[data-action="send"]'); button.classList.add('button-pressed'); setTimeout(() => button.classList.remove('button-pressed'), 100); } // Set up event listeners function setupEventListeners() { // Menu toggle menuBtn.addEventListener('click', toggleMenu); menuOverlay.addEventListener('click', closeMenu); // Menu item clicks menuItems.forEach(item => { item.addEventListener('click', (e) => { const feature = e.currentTarget.dataset.feature; handleMenuItemClick(feature); }); }); // Add currency button addCurrencyBtn.addEventListener('click', () => openCurrencyModal()); // Modal close buttons closeModal.addEventListener('click', closeCurrencyModal); window.addEventListener('click', (e) => { if (e.target === currencyModal) { closeCurrencyModal(); } }); // Currency search input currencySearch.addEventListener('input', () => { populateCurrencyList(); }); // Calculator buttons calculatorButtons.forEach(button => { button.addEventListener('click', () => { // Add button press animation button.classList.add('button-pressed'); setTimeout(() => button.classList.remove('button-pressed'), 100); // Handle different button types if (button.dataset.number) { handleNumberInput(button.dataset.number); } else if (button.dataset.operator) { handleOperatorInput(button.dataset.operator); } else if (button.dataset.action) { const action = button.dataset.action; switch(action) { case 'equals': handleEquals(); break; case 'clear': handleClear(); break; case 'delete': handleDelete(); break; case 'decimal': handleDecimal(); break; case 'plusminus': handlePlusMinus(); break; case 'percent': handlePercent(); break; case 'copy': handleCopy(); break; case 'send': handleSend(); break; } } }); }); // Keyboard support document.addEventListener('keydown', (e) => { // Don't trigger keyboard shortcuts when typing in search if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') { return; } const key = e.key; // Number keys if (/[0-9]/.test(key)) { handleNumberInput(key); e.preventDefault(); } // Operators else if (key === '+') { handleOperatorInput('+'); e.preventDefault(); } else if (key === '-') { handleOperatorInput('−'); e.preventDefault(); } else if (key === '*') { handleOperatorInput('×'); e.preventDefault(); } else if (key === '/') { e.preventDefault(); handleOperatorInput('÷'); } // Other keys else if (key === 'Enter' || key === '=') { handleEquals(); e.preventDefault(); } else if (key === 'Escape') { handleClear(); e.preventDefault(); } else if (key === 'Backspace') { handleDelete(); e.preventDefault(); } else if (key === '.') { handleDecimal(); e.preventDefault(); } else if (key === '%') { handlePercent(); e.preventDefault(); } }); } // Initialize the app when DOM is loaded document.addEventListener('DOMContentLoaded', initApp);