In this tutorial, I will teach you how to create a currency converter app using HTML5, CSS3, and JavaScript. The complete source code of this JavaScript currency converter app is given below.
JavaScript Currency Converter App Source Code
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Currency Converter App in JavaScript</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- FontAweome CDN Link for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
</head>
<body>
<div class="wrapper">
<header>Currency Converter</header>
<form action="#">
<div class="amount">
<p>Enter Amount</p>
<input type="text" value="1">
</div>
<div class="drop-list">
<div class="from">
<p>From</p>
<div class="select-box">
<img src="https://flagcdn.com/48x36/us.png" alt="flag">
<select> <!-- Options tag are inserted from JavaScript --> </select>
</div>
</div>
<div class="icon"><i class="fas fa-exchange-alt"></i></div>
<div class="to">
<p>To</p>
<div class="select-box">
<img src="https://flagcdn.com/48x36/np.png" alt="flag">
<select> <!-- Options tag are inserted from JavaScript --> </select>
</div>
</div>
</div>
<div class="exchange-rate">Getting exchange rate...</div>
<button>Get Exchange Rate</button>
</form>
</div>
<script src="js/country-list.js"></script>
<script src="js/script.js"></script>
</body>
</html>
style.css
/* Import Google Font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 0 10px;
background: #675AFE;
}
::selection{
color: #fff;
background: #675AFE;
}
.wrapper{
width: 370px;
padding: 30px;
border-radius: 7px;
background: #fff;
box-shadow: 7px 7px 20px rgba(0, 0, 0, 0.05);
}
.wrapper header{
font-size: 28px;
font-weight: 500;
text-align: center;
}
.wrapper form{
margin: 40px 0 20px 0;
}
form :where(input, select, button){
width: 100%;
outline: none;
border-radius: 5px;
border: none;
}
form p{
font-size: 18px;
margin-bottom: 5px;
}
form input{
height: 50px;
font-size: 17px;
padding: 0 15px;
border: 1px solid #999;
}
form input:focus{
padding: 0 14px;
border: 2px solid #675AFE;
}
form .drop-list{
display: flex;
margin-top: 20px;
align-items: center;
justify-content: space-between;
}
.drop-list .select-box{
display: flex;
width: 115px;
height: 45px;
align-items: center;
border-radius: 5px;
justify-content: center;
border: 1px solid #999;
}
.select-box img{
max-width: 21px;
}
.select-box select{
width: auto;
font-size: 16px;
background: none;
margin: 0 -5px 0 5px;
}
.select-box select::-webkit-scrollbar{
width: 8px;
}
.select-box select::-webkit-scrollbar-track{
background: #fff;
}
.select-box select::-webkit-scrollbar-thumb{
background: #888;
border-radius: 8px;
border-right: 2px solid #ffffff;
}
.drop-list .icon{
cursor: pointer;
margin-top: 30px;
font-size: 22px;
}
form .exchange-rate{
font-size: 17px;
margin: 20px 0 30px;
}
form button{
height: 52px;
color: #fff;
font-size: 17px;
cursor: pointer;
background: #675AFE;
transition: 0.3s ease;
}
form button:hover{
background: #4534fe;
}js/country-list.js
let country_list = {
"AED" : "AE",
"AFN" : "AF",
"XCD" : "AG",
"ALL" : "AL",
"AMD" : "AM",
"ANG" : "AN",
"AOA" : "AO",
"AQD" : "AQ",
"ARS" : "AR",
"AUD" : "AU",
"AZN" : "AZ",
"BAM" : "BA",
"BBD" : "BB",
"BDT" : "BD",
"XOF" : "BE",
"BGN" : "BG",
"BHD" : "BH",
"BIF" : "BI",
"BMD" : "BM",
"BND" : "BN",
"BOB" : "BO",
"BRL" : "BR",
"BSD" : "BS",
"NOK" : "BV",
"BWP" : "BW",
"BYR" : "BY",
"BZD" : "BZ",
"CAD" : "CA",
"CDF" : "CD",
"XAF" : "CF",
"CHF" : "CH",
"CLP" : "CL",
"CNY" : "CN",
"COP" : "CO",
"CRC" : "CR",
"CUP" : "CU",
"CVE" : "CV",
"CYP" : "CY",
"CZK" : "CZ",
"DJF" : "DJ",
"DKK" : "DK",
"DOP" : "DO",
"DZD" : "DZ",
"ECS" : "EC",
"EEK" : "EE",
"EGP" : "EG",
"ETB" : "ET",
"EUR" : "FR",
"FJD" : "FJ",
"FKP" : "FK",
"GBP" : "GB",
"GEL" : "GE",
"GGP" : "GG",
"GHS" : "GH",
"GIP" : "GI",
"GMD" : "GM",
"GNF" : "GN",
"GTQ" : "GT",
"GYD" : "GY",
"HKD" : "HK",
"HNL" : "HN",
"HRK" : "HR",
"HTG" : "HT",
"HUF" : "HU",
"IDR" : "ID",
"ILS" : "IL",
"INR" : "IN",
"IQD" : "IQ",
"IRR" : "IR",
"ISK" : "IS",
"JMD" : "JM",
"JOD" : "JO",
"JPY" : "JP",
"KES" : "KE",
"KGS" : "KG",
"KHR" : "KH",
"KMF" : "KM",
"KPW" : "KP",
"KRW" : "KR",
"KWD" : "KW",
"KYD" : "KY",
"KZT" : "KZ",
"LAK" : "LA",
"LBP" : "LB",
"LKR" : "LK",
"LRD" : "LR",
"LSL" : "LS",
"LTL" : "LT",
"LVL" : "LV",
"LYD" : "LY",
"MAD" : "MA",
"MDL" : "MD",
"MGA" : "MG",
"MKD" : "MK",
"MMK" : "MM",
"MNT" : "MN",
"MOP" : "MO",
"MRO" : "MR",
"MTL" : "MT",
"MUR" : "MU",
"MVR" : "MV",
"MWK" : "MW",
"MXN" : "MX",
"MYR" : "MY",
"MZN" : "MZ",
"NAD" : "NA",
"XPF" : "NC",
"NGN" : "NG",
"NIO" : "NI",
"NPR" : "NP",
"NZD" : "NZ",
"OMR" : "OM",
"PAB" : "PA",
"PEN" : "PE",
"PGK" : "PG",
"PHP" : "PH",
"PKR" : "PK",
"PLN" : "PL",
"PYG" : "PY",
"QAR" : "QA",
"RON" : "RO",
"RSD" : "RS",
"RUB" : "RU",
"RWF" : "RW",
"SAR" : "SA",
"SBD" : "SB",
"SCR" : "SC",
"SDG" : "SD",
"SEK" : "SE",
"SGD" : "SG",
"SKK" : "SK",
"SLL" : "SL",
"SOS" : "SO",
"SRD" : "SR",
"STD" : "ST",
"SVC" : "SV",
"SYP" : "SY",
"SZL" : "SZ",
"THB" : "TH",
"TJS" : "TJ",
"TMT" : "TM",
"TND" : "TN",
"TOP" : "TO",
"TRY" : "TR",
"TTD" : "TT",
"TWD" : "TW",
"TZS" : "TZ",
"UAH" : "UA",
"UGX" : "UG",
"USD" : "US",
"UYU" : "UY",
"UZS" : "UZ",
"VEF" : "VE",
"VND" : "VN",
"VUV" : "VU",
"YER" : "YE",
"ZAR" : "ZA",
"ZMK" : "ZM",
"ZWD" : "ZW"
}
js/script.js
const dropList = document.querySelectorAll("form select"),
fromCurrency = document.querySelector(".from select"),
toCurrency = document.querySelector(".to select"),
getButton = document.querySelector("form button");
for (let i = 0; i < dropList.length; i++) {
for(let currency_code in country_list){
// selecting USD by default as FROM currency and NPR as TO currency
let selected = i == 0 ? currency_code == "USD" ? "selected" : "" : currency_code == "NPR" ? "selected" : "";
// creating option tag with passing currency code as a text and value
let optionTag = `<option value="${currency_code}" ${selected}>${currency_code}</option>`;
// inserting options tag inside select tag
dropList[i].insertAdjacentHTML("beforeend", optionTag);
}
dropList[i].addEventListener("change", e =>{
loadFlag(e.target); // calling loadFlag with passing target element as an argument
});
}
function loadFlag(element){
for(let code in country_list){
if(code == element.value){ // if currency code of country list is equal to option value
let imgTag = element.parentElement.querySelector("img"); // selecting img tag of particular drop list
// passing country code of a selected currency code in a img url
imgTag.src = `https://flagcdn.com/48x36/${country_list[code].toLowerCase()}.png`;
}
}
}
window.addEventListener("load", ()=>{
getExchangeRate();
});
getButton.addEventListener("click", e =>{
e.preventDefault(); //preventing form from submitting
getExchangeRate();
});
const exchangeIcon = document.querySelector("form .icon");
exchangeIcon.addEventListener("click", ()=>{
let tempCode = fromCurrency.value; // temporary currency code of FROM drop list
fromCurrency.value = toCurrency.value; // passing TO currency code to FROM currency code
toCurrency.value = tempCode; // passing temporary currency code to TO currency code
loadFlag(fromCurrency); // calling loadFlag with passing select element (fromCurrency) of FROM
loadFlag(toCurrency); // calling loadFlag with passing select element (toCurrency) of TO
getExchangeRate(); // calling getExchangeRate
})
function getExchangeRate(){
const amount = document.querySelector("form input");
const exchangeRateTxt = document.querySelector("form .exchange-rate");
let amountVal = amount.value;
// if user don't enter any value or enter 0 then we'll put 1 value by default in the input field
if(amountVal == "" || amountVal == "0"){
amount.value = "1";
amountVal = 1;
}
exchangeRateTxt.innerText = "Getting exchange rate...";
let url = `https://v6.exchangerate-api.com/v6/YOUR-API-KEY/latest/${fromCurrency.value}`;
// fetching api response and returning it with parsing into js obj and in another then method receiving that obj
fetch(url).then(response => response.json()).then(result =>{
let exchangeRate = result.conversion_rates[toCurrency.value]; // getting user selected TO currency rate
let totalExRate = (amountVal * exchangeRate).toFixed(2); // multiplying user entered value with selected TO currency rate
exchangeRateTxt.innerText = `${amountVal} ${fromCurrency.value} = ${totalExRate} ${toCurrency.value}`;
}).catch(() =>{ // if user is offline or any other error occured while fetching data then catch function will run
exchangeRateTxt.innerText = "Something went wrong";
});
}