Thumbnail

Currency Converter Using HTML, CSS and JavaScript

Introduction :

This project is a simple currency converter built using HTML, CSS, and JavaScript. It allows users to convert amounts from one currency to another based on predefined exchange rates. Users can also add custom currencies with their own exchange rates.

In today’s interconnected world, where global transactions are commonplace, the ability to swiftly and accurately convert currencies is essential. The Currency Converter project offers a solution to this need, providing a user-friendly interface for converting monetary values between different currencies.

Through a combination of HTML, CSS, and JavaScript, this project creates an intuitive platform where users can seamlessly perform currency conversions. Its primary goal is to empower users with the ability to quickly ascertain the equivalent value of a given amount in their desired currency, thereby facilitating informed financial decisions and transactions across borders.

By leveraging the latest exchange rates, the Currency Converter ensures accuracy and reliability in its calculations. It maintains an up-to-date repository of currency exchange rates, allowing users to access real-time conversion data and stay informed about fluctuations in international currency markets.

Moreover, the Currency Converter project is designed with flexibility in mind. In addition to supporting major currencies out of the box, it offers users the freedom to add custom currencies with their own exchange rates. This feature caters to diverse needs and scenarios, accommodating users who may require conversions involving less common or regional currencies.

With its sleek and responsive interface, the Currency Converter prioritizes user experience, striving to make currency conversion a seamless and hassle-free process. Whether it’s for personal finance management, international travel planning, or business transactions, this tool empowers users with the confidence to navigate the complexities of global finance with ease.

In essence, the Currency Converter project stands as a testament to the power of technology in simplifying and democratizing access to financial services. It embodies the spirit of innovation and inclusivity, serving as a valuable resource for individuals and businesses alike in an increasingly interconnected and dynamic world economy.

Explanation :

HTML Structure:

The HTML markup provides the skeleton of the Currency Converter interface. It’s divided into logical sections, such as the input fields, dropdown menus, and buttons, enclosed within appropriate container elements. Each element is assigned an ID or class for easy identification and manipulation via JavaScript and CSS.

CSS Styling:

CSS stylesheets are responsible for the visual presentation of the Currency Converter. Through carefully crafted rules, elements are styled to achieve a cohesive and aesthetically pleasing design. Properties like font styles, colors, padding, and margins are meticulously defined to enhance readability and usability. Additionally, CSS transitions and animations are employed to create smooth interactions and feedback, ensuring a delightful user experience.

JavaScript Functionality:

The core functionality of the Currency Converter is implemented using JavaScript. This includes handling user interactions, updating currency options, performing conversions, and managing custom currencies.

  • Currency Rates Object: The currencyRates object serves as a central repository for storing exchange rates between different currencies. Each currency is represented by a key-value pair, where the key is the currency code (e.g., USD, EUR) and the value is the exchange rate relative to the base currency (USD).

  • Update Currency Options Function: The updateCurrencyOptions() function dynamically populates the dropdown menus with available currency options based on the currencyRates object. It clears existing options and creates new <option> elements for each currency, ensuring that users can select from a comprehensive list of supported currencies.

  • Add Custom Currency Functionality: The addCurrencyButton event listener enables users to add custom currencies with their own exchange rates. When triggered, it prompts the user to enter the exchange rate for a custom currency. If a valid rate is provided, the custom currency is added to the currencyRates object, and the currency options are updated accordingly.

  • Convert Currency Functionality: The convertCurrency() function handles the conversion of currency amounts based on user input. It retrieves the amount to convert, the source currency, and the target currency selected by the user. Using the exchange rates from the currencyRates object, it performs the necessary calculations to determine the converted amount and displays the result in the designated output field.

Purpose of Functions:

  • updateCurrencyOptions(): Ensures that the dropdown menus are always up to date with the latest currency options available, providing users with a comprehensive selection to choose from.

  • addCurrencyButton: Enhances the flexibility of the Currency Converter by allowing users to add custom currencies, catering to diverse currency needs and scenarios.

  • convertCurrency(): Facilitates seamless currency conversions, empowering users to effortlessly obtain equivalent values in their desired currencies, thereby enabling informed financial decisions and transactions.

By combining HTML for structure, CSS for styling, and JavaScript for functionality, the Currency Converter project delivers a robust and user-friendly solution for currency conversion needs, epitomizing the power of web technologies in simplifying complex tasks and enhancing user experiences.

SOURCE CODE :

HTML (index.html)

				
					<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" href="style.css" /> <script src="script.js" type="module"></script> <title>Currency Converter</title>
</head>

<body>
  <h2>Currency Converter</h2>
  <div class="container converter">
    <div class="input-container">
      <input type="number" id="amount" placeholder="Enter amount" />
      <select id="fromCurrency">
        
        <option value="custom">Custom</option>
      </select>
    </div>
    <div class="input-container">
      <input type="number" id="result" placeholder="Result" disabled />
      <select id="toCurrency">
        
        <option value="custom">Custom</option>
      </select>
    </div>
    <button id="convertButton">Convert</button>
    <div class="input-container">
      <input type="text" id="customCurrency" placeholder="Custom Currency (e.g., CAD)" />
      <button id="addCurrencyButton">Add Currency</button>
    </div>
  </div> <script data-no-optimize="1">!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-no-optimize="1">var litespeed_vary=document.cookie.replace(/(?:(?:^|.*;\s*)_lscache_vary\s*\=\s*([^;]*).*$)|^.*$/,"");litespeed_vary||fetch("/wp-content/plugins/litespeed-cache/guest.vary.php",{method:"POST",cache:"no-cache",redirect:"follow"}).then(e=>e.json()).then(e=>{console.log(e),e.hasOwnProperty("reload")&&"yes"==e.reload&&(sessionStorage.setItem("litespeed_docref",document.referrer),window.location.reload(!0))});</script><script data-optimized="1" type="litespeed/javascript" data-src="https://foolishdeveloper.com/wp-content/litespeed/js/f21cbb88936c42dc19773a8407b9c20a.js?ver=519e0"></script><script>const litespeed_ui_events=["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script></body>

</html>
				
			

CSS (style.css)

				
					body {

  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.converter {
  max-width: 500px;
  padding: 60px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
  text-align: center;
  transition: transform 0.2s ease-in-out;
}

.converter:hover {
  transform: scale(1.02);
}

h1 {
  color: #333;
  margin-bottom: 20px;
  font-size: 24px;
}

.input-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 10px 0;
}

input[type='number'],
select {
  width: 100%;
  padding: 12px;
  border: 1px solid #ccc;
  border-radius: 5px;
  font-size: 16px;
  margin: 5px 0;
  outline: none;
  transition: border-color 0.2s;
}

input[type='number']:focus,
select:focus {
  border-color: #007bff;
}

button {
  background-color: #007bff;
  color: #fff;
  border: none;
  padding: 12px 20px;
  border-radius: 5px;
  font-size: 16px;
  cursor: pointer;
  transition: background-color 0.2s;
}

button:hover {
  background-color: #0056b3;
}
				
			

JavaScript (index.js)

				
					const currencyRates = {
  USD: 1, // USD to USD (1:1)
  EUR: 0.85, // USD to EUR (1 USD = 0.85 EUR)
  GBP: 0.74, // USD to GBP (1 USD = 0.74 GBP)
  INR: 83.52, // USD to INR (1 USD = 74.63 INR)
  // Add more currency rates here
};

document.getElementById('addCurrencyButton').addEventListener('click', function () {
  const customCurrencyCode = document.getElementById('customCurrency').value.toUpperCase();
  if (customCurrencyCode && !currencyRates[customCurrencyCode]) {
    const exchangeRate = parseFloat(
      prompt(`Enter exchange rate for 1 USD to ${customCurrencyCode}`)
    );
    if (!isNaN(exchangeRate)) {
      currencyRates[customCurrencyCode] = exchangeRate;
      updateCurrencyOptions();
    } else {
      alert('Invalid exchange rate. Please enter a valid number.');
    }
  } else if (currencyRates[customCurrencyCode]) {
    alert(`Currency ${customCurrencyCode} already exists.`);
  } else {
    alert('Invalid currency code. Please enter a valid code (e.g., CAD).');
  }
});

function updateCurrencyOptions() {
  const fromCurrencySelect = document.getElementById('fromCurrency');
  const toCurrencySelect = document.getElementById('toCurrency');

  // Clear existing options
  fromCurrencySelect.innerHTML = '';
  toCurrencySelect.innerHTML = '';

  for (const currency in currencyRates) {
    const option = document.createElement('option');
    option.value = currency;
    option.innerText = currency;
    fromCurrencySelect.appendChild(option);

    const toOption = option.cloneNode(true);
    toCurrencySelect.appendChild(toOption);
  }
  toCurrencySelect.innerHTML += '<option value="custom">Custom</option>';
}

document.getElementById('convertButton').addEventListener('click', convertCurrency);

function convertCurrency() {
  const amount = parseFloat(document.getElementById('amount').value);
  const fromCurrency = document.getElementById('fromCurrency').value;
  const toCurrency = document.getElementById('toCurrency').value;
  const resultElement = document.getElementById('result');

  if (isNaN(amount)) {
    alert('Please enter a valid amount.');
    return;
  }

  const convertedAmount = (amount / currencyRates[fromCurrency]) * currencyRates[toCurrency];
  resultElement.value = convertedAmount.toFixed(2);
}

// Initialize currency options
updateCurrencyOptions();

				
			

OUTPUT :

OUTPUT