Hello Coders! Welcome to Coding Torque. In this blog, we are going to create a Currency Converter App using HTML, CSS and JavaScript. We are going to use exchangerate-api to fetch currency rates and calculations, and also a flagcdn api to fetch flags of different countries. This is a real-world project so you must create this to upskill yourself in API fetching.
Before we start, here are some more JavaScript projects for you to practice:
1. Filter Cards using JavaScript
2. Dictionary App using JavaScript
3. Rock Paper Scissor Game using JavaScript
4. Tip Calculator using JavaScript
5. QR Code Generator using JavaScript
I would recommend you don't just copy and paste the code, just look at the code and type by understanding it.
Demo
HTML Code
Starter Template
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS -->
<link rel="stylesheet" href="style.css">
<!-- FONT AWESOME CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog=="
crossorigin="anonymous" />
<title>Currency Converter using JavaScript - @code.scientist x @codingtorque</title>
</head>
<body>
<!-- Further Code Here -->
<script src="script.js"></script>
</body>
</html>
Paste the below code in your <body> tag
<div class="wrapper">
<h2>Currency Converter</h2>
<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/in.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>
Output Till Now
CSS Code
/* 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: #1a212d;
}
.wrapper {
width: 30rem;
padding: 30px;
border-radius: 7px;
background: #161922;
color: white;
box-shadow: 7px 7px 20px rgba(0, 0, 0, 0.05);
}
.wrapper h2 {
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;
background: transparent;
color: white;
border: 1px solid #999;
}
form input:focus {
padding: 0 14px;
border: 2px solid #675afe;
}
form .drop-list {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
margin-top: 20px;
}
.from {
width: 100%;
}
.to {
width: 100%;
}
.drop-list .select-box {
display: flex;
width: 100%;
height: 45px;
align-items: center;
border-radius: 5px;
padding: 0 20px;
border: 1px solid #999;
background: #20232c;
}
.select-box img {
max-width: 21px;
}
.select-box select {
width: 100%;
font-size: 16px;
background: none;
margin: 0 -5px 0 5px;
color: white;
background: #20232c;
}
.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: 10px;
font-size: 22px;
transform: rotate(90deg);
}
form .exchange-rate {
font-size: 17px;
margin: 20px 0 30px;
}
form button {
height: 52px;
color: #fff;
font-size: 17px;
cursor: pointer;
background: #20232c;
transition: 0.3s ease;
}
Output Till Now
JavaScript Code
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"
}
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) {
let selected = i == 0 ? currency_code == "USD" ? "selected" : "" : currency_code == "INR" ? "selected" : "";
let optionTag = `<option value="${currency_code}" ${selected}>${currency_code}</option>`;
dropList[i].insertAdjacentHTML("beforeend", optionTag);
}
dropList[i].addEventListener("change", e => {
loadFlag(e.target);
});
}
function loadFlag(element) {
for (let code in country_list) {
if (code == element.value) {
let imgTag = element.parentElement.querySelector("img");
imgTag.src = `https://flagcdn.com/48x36/${country_list[code].toLowerCase()}.png`;
}
}
}
window.addEventListener("load", () => {
getExchangeRate();
});
getButton.addEventListener("click", e => {
e.preventDefault();
getExchangeRate();
});
const exchangeIcon = document.querySelector("form .icon");
exchangeIcon.addEventListener("click", () => {
let tempCode = fromCurrency.value;
fromCurrency.value = toCurrency.value;
toCurrency.value = tempCode;
loadFlag(fromCurrency);
loadFlag(toCurrency);
getExchangeRate();
})
function getExchangeRate() {
const amount = document.querySelector("form input");
const exchangeRateTxt = document.querySelector("form .exchange-rate");
let amountVal = amount.value;
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_HERE/latest/${fromCurrency.value}`;
fetch(url).then(response => response.json()).then(result => {
let exchangeRate = result.conversion_rates[toCurrency.value];
let totalExRate = (amountVal * exchangeRate).toFixed(2);
exchangeRateTxt.innerText = `${amountVal} ${fromCurrency.value} = ${totalExRate} ${toCurrency.value}`;
}).catch(() => {
exchangeRateTxt.innerText = "Something went wrong";
});
}