Let’s create a completely purposeful foreign money converter utility utilizing HTML, CSS, and vanilla JavaScript. By the top of this tutorial, we can have a responsive foreign money app that fetches real-time information with the Change Price API and presents it in a user-friendly interface.
HTML Construction
Our foreign money utility can have a easy interface containing :
- An enter discipline for the quantity to be transformed.
- A drop-down to pick out the from Forex worth
- A second drop-down to pick out the to foreign money worth
- A convert button
- A
tag to indicate the transformed quantity
- A
tag to indicate any errors that may happen throughout the conversion course of.
The HTML code will appear like this:
1 |
|
2 |
|
3 |
|
4 |
Forex converter |
5 |
|
6 |
|
7 |
kind="textual content" id="quantity" placeholder="100" required/>
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
class="select-option" |
13 |
title="from-currency" |
14 |
id="fromCurrency" |
15 |
>
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
TO
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
At present, we’re utilizing the choice worth as a placeholder. We’ll exchange and add extra possibility information dynamically with JavaScript.
Styling With CSS
Let’s begin with some primary types. We’ve pulled within the relatively glorious Bricolage Grotesque font from Google fonts too:
1 |
* { |
2 |
margin: 0; |
3 |
padding: 0; |
4 |
box-sizing: border-box; |
5 |
font-family: 'Bricolage Grotesque', sans-serif; |
6 |
}
|
7 |
|
8 |
h1 { |
9 |
font-size: 5em; |
10 |
font-weight: daring; |
11 |
text-align: middle; |
12 |
margin: .5em 0; |
13 |
line-height: .8; |
14 |
}
|
15 |
|
16 |
.container { |
17 |
margin: auto; |
18 |
min-height: 100vh; |
19 |
background-color: #202020; |
20 |
padding: 2em 0; |
21 |
coloration: #040203; |
22 |
show: flex; |
23 |
flex-direction: column; |
24 |
align-items: middle; |
25 |
justify-content: middle; |
26 |
}
|
27 |
|
28 |
.currency-container { |
29 |
top: fit-content; |
30 |
background-color: #7cb889; |
31 |
padding: 3em; |
32 |
border-radius: 40px; |
33 |
}
|
For the enter and label (together with the placeholder within the enter) they’ll have the next types:
1 |
.input-box { |
2 |
show: flex; |
3 |
flex-direction: column; |
4 |
align-items: middle; |
5 |
justify-content: middle; |
6 |
text-align: middle; |
7 |
}
|
8 |
|
9 |
label { |
10 |
font-size: 1.5em; |
11 |
margin-bottom: .4em; |
12 |
}
|
13 |
|
14 |
#quantity { |
15 |
width: 300px; |
16 |
padding: 20px; |
17 |
border-radius: 30px; |
18 |
font-size: 3em; |
19 |
border: 3px stable black; |
20 |
background: clear; |
21 |
coloration: black; |
22 |
|
23 |
}
|
24 |
#quantity:focus { |
25 |
border: 3px stable white; |
26 |
define: none; |
27 |
}
|
28 |
|
29 |
::placeholder { |
30 |
coloration: rgba(0,0,0,0.6); |
31 |
opacity: 1; /* Firefox */ |
32 |
}
|
Subsequent, we’ll apply styling to the field components containing the From and To foreign money drop-downs. The drop-down components shall be organized in a column format utilizing Flexbox and centered vertically and horizontally. We even have a spot between the field components, some padding, and a border radius.
1 |
.foreign money { |
2 |
margin-top: 50px; |
3 |
padding: 20px 20px; |
4 |
show: flex; |
5 |
align-items: middle; |
6 |
justify-content: middle; |
7 |
flex-direction: column; |
8 |
hole: 1.5rem; |
9 |
}
|
10 |
|
11 |
.field { |
12 |
show: flex; |
13 |
align-items: middle; |
14 |
justify-content: middle; |
15 |
}
|
The select-option can have the next types
1 |
.select-option { |
2 |
font-size: 16px; |
3 |
coloration: #333; |
4 |
padding: 20px; |
5 |
show: block; |
6 |
font-weight: 700; |
7 |
line-height: 1.3; |
8 |
width: 100%; |
9 |
max-width: 100%; |
10 |
margin: 0; |
11 |
define: none; |
12 |
border-radius: 20px; |
13 |
border: 3px stable black; |
14 |
}
|
Lastly, the convert button, the outcome, and the error message components can have the next types:
1 |
button { |
2 |
width: 100%; |
3 |
top: 100px; |
4 |
padding: 10px; |
5 |
border-radius: 30px; |
6 |
border: none; |
7 |
font-size: 1.5em; |
8 |
align-items: middle; |
9 |
background-color: black; |
10 |
coloration: #fff; |
11 |
margin-top: 30px; |
12 |
}
|
13 |
.outcome { |
14 |
coloration: black; |
15 |
font-size: 2.5em; |
16 |
}
|
17 |
.error { |
18 |
coloration: #800020; |
19 |
font-size: 12px; |
20 |
}
|
JavaScript Performance
The JavaScript performance can have two elements:
- Getting the foreign money code, foreign money title, and flag from the REST international locations API
- getting conversion price from the Change Price API
REST Nations API
The REST countries API supplies an API with the endpoint https://restcountries.com/v3.1/all the place you’ll be able to filter outcomes by offering the fields you have an interest in. In our case, we wish the nation flag, foreign money title, and foreign money code and the endpoint will appear like this:
1 |
https://restcountries.com/v3.1/all?fields=currencies,flag |
The ensuing pattern information will appear like this:
1 |
{ |
2 |
"title": { |
3 |
"frequent": "Eritrea", |
4 |
"official": "State of Eritrea", |
5 |
"nativeName": { |
6 |
"ara": { |
7 |
"official": "دولة إرتريا", |
8 |
"frequent": "إرتريا" |
9 |
}, |
10 |
"eng": { |
11 |
"official": "State of Eritrea", |
12 |
"frequent": "Eritrea" |
13 |
}, |
14 |
"tir": { |
15 |
"official": "ሃገረ ኤርትራ", |
16 |
"frequent": "ኤርትራ" |
17 |
} |
18 |
} |
19 |
}, |
20 |
"currencies": { |
21 |
"ERN": { |
22 |
"title": "Eritrean nakfa", |
23 |
"image": "Nfk" |
24 |
} |
25 |
}, |
26 |
"flag": "🇪🇷" |
27 |
}, |
To make it simpler to show our currencies, we’ll fetch the info and retailer it in a JavaScript file. The script for fetching the info will appear like this:
1 |
const url = |
2 |
"https://restcountries.com/v3.1/all?fields=title,currencies,flag"; |
3 |
fetch(url) |
4 |
.then((response) => response.json()) |
5 |
.then((information) => { |
6 |
|
7 |
const outcome = []; |
8 |
information.forEach((nation) => { |
9 |
if (Object.keys(nation.currencies).size >0) { |
10 |
outcome.push({ |
11 |
countryname: nation.title.frequent, |
12 |
title: Object.values(nation.currencies)[0].title, |
13 |
code: Object.keys(nation.currencies)[0], |
14 |
flag: nation.flag, |
15 |
});
|
16 |
}
|
17 |
});
|
18 |
|
19 |
outcome.type((a, b) => a.code.localeCompare(b.code)); |
20 |
const jsonString = JSON.stringify(outcome, null); |
21 |
console.log(jsonString); |
22 |
|
23 |
});
|
The code above does the next:
- We use the
fetch()
methodology to make an HTTP request to the REST international locations API. - Then, we convert the response to JSON format and begin processing the info.
- From the response JSON, we first examine if every nation has a foreign money code since not all international locations have a foreign money code.
- If a rustic has a foreign money, we create an object with its title, code, and foreign money title and push it to the empty outcome array.
- Then we type the foreign money code alphabetically.
- Lastly, we convert the outcome to JSON and print the stringified information to the console.
If you run the script in a browser surroundings, it is best to have the ability to copy the info to your JavaScript file. The information appears like this:



Alternatively, add this link to your script utilizing the src
attribute.
Subsequent, let’s get the choose components.
1 |
let fromCurrency = doc.getElementById("fromCurrency"); |
2 |
let toCurrency = doc.getElementById("toCurrency"); |
Since we have now the info in an array, it’s now simpler to append the currencies to the choice components of the fromCurrency and toCurrency choose components.
Create a perform referred to as addCurrency()
. Contained in the addCurrency()
perform, we use the forEach()
perform to loop by means of the currencies array; for every iteration, we wish to add the foreign money code to the choice component and append the choice component to each the choose components.
1 |
const outcome = currencies.forEach((foreign money) => { |
2 |
|
3 |
const optionFrom = doc.createElement("possibility"); |
4 |
optionFrom.classList.add("select-option"); |
5 |
optionFrom.worth = foreign money.code; |
6 |
if (foreign money.code === "USD") { |
7 |
optionFrom.chosen = true; |
8 |
}
|
9 |
optionFrom.textual content =`${foreign money.flag} ${foreign money.code} - ${foreign money.title}`; |
10 |
|
11 |
fromCurrency.appendChild(optionFrom); |
12 |
|
13 |
const optionTO = doc.createElement("possibility"); |
14 |
optionTO.classList.add("select-option"); |
15 |
optionTO.worth = foreign money.code; |
16 |
if (foreign money.code === "EUR") { |
17 |
optionTO.chosen = true; |
18 |
}
|
19 |
optionTO.textual content =`${foreign money.flag} ${foreign money.code} - ${foreign money.title}`; |
20 |
toCurrency.appendChild(optionTO); |
21 |
});
|
Within the code above, we use the ForEach()
perform to iterate on every the currencies array information and do the next:
- Extracts the foreign money key from the currencies array for every foreign money
- will get the flag
- will get the foreign money title
- Creates an HTML possibility component for the “
fromCurrency
” choose dropdown . - units the choice worth to the foreign money code
- Units the choice textual content to a mixture of the flag, the foreign money title, and the foreign money code
- Appends the created possibility component to the “
fromCurrency
” choose dropdown. - Creates an alternative choice component for the “
toCurrency
” choose dropdown with the identical information because thefromCurrency
- Appends the created possibility component to the “toCurrency” choose dropdown.
- Lastly we invoke the
addCurrency()
perform to use the performance.
The choice worth would be the foreign money code, and the choice textual content would be the foreign money flag, foreign money code, and foreign money title separated by a hyphen.
We additionally set the default foreign money within the fromCurrency
possibility component to USD and the default foreign money for the toCurrency
possibility component to EUR.
Now our drop down are displaying the currencies.



Code Refactoring
From the addCurrency()
perform you’ll be able to see that we’re repeating the identical code so as to add the choice values. Let’s create one other perform for producing the choices for every foreign money component.
The perform will appear like this:
1 |
perform createOption(nation, defaultCode, component ){ |
2 |
// console.log(nation);
|
3 |
const possibility = doc.createElement("possibility"); |
4 |
possibility.classList.add("select-option"); |
5 |
possibility.worth = nation.code; |
6 |
if (nation.code === defaultCode) { |
7 |
possibility.chosen = true; |
8 |
}
|
9 |
possibility.textual content = `${nation.flag} ${nation.code} - ${nation.title}`; |
10 |
component.appendChild(possibility); |
11 |
|
12 |
|
13 |
}
|
The createOption()
perform takes three parameters: the nation object, the default code, and the component the place the choices shall be appended.
Subsequent, replace the addCurrency() perform as follows:
1 |
perform addCurrency() { |
2 |
const outcome = international locations.map((nation) => { |
3 |
createOption(nation, "USD", fromCurrency ); |
4 |
createOption(nation, "EUR", toCurrency ) |
5 |
|
6 |
});
|
7 |
}
|
The perform is now simpler to learn since we don’t have any repetitive code.
Forex Conversion
We’ll use the ExchangeRate API for foreign money conversion. The ExchangeRate API supplies foreign money conversion charges for 161 currencies.
The API permits builders to transform currencies by offering a pair of foreign money codes within the request. For instance, if you wish to convert USD to EUR, your API name will appear like this:
1 |
https://v6.exchangerate-api.com/v6/24faec6b42da4a96ceea41d3/pair/USD/EUR |
The endpoint will give us the next outcome.
1 |
{
|
2 |
"outcome": "success", |
3 |
"documentation": "https://www.exchangerate-api.com/docs", |
4 |
"terms_of_use": "https://www.exchangerate-api.com/phrases", |
5 |
"time_last_update_unix": 1703721602,
|
6 |
"time_last_update_utc": "Thu, 28 Dec 2023 00:00:02 +0000", |
7 |
"time_next_update_unix": 1703808002,
|
8 |
"time_next_update_utc": "Fri, 29 Dec 2023 00:00:02 +0000", |
9 |
"base_code": "USD", |
10 |
"target_code": "EUR", |
11 |
"conversion_rate": 0.9015
|
12 |
}
|
Since we have already got the codes in our choose choices, we’ll move the values within the API and multiply the conversion price by the quantity to get the outcome.
Create a perform referred to as convertCurrency()
perform. Within the perform:
- get the show component
- get the values from the chosen choices
- Retailer the url in a variable.
1 |
const BASE_URL = `https://v6.exchangerate-api.com/v6/${apiKey}`; |
2 |
const fromCurrrencyCode = doc.getElementById("fromCurrency").worth; |
3 |
const toCurrencyCode = doc.getElementById("toCurrency").worth; |
4 |
const outcome = doc.querySelector(".outcome"); |
5 |
const error = doc.querySelector(".error"); |
Make sure you provide your API key from the Change Price API. You may acquire one free of charge here.
Within the convertCurrency()
perform, we first examine if a sound quantity has been entered, and if true, we carry out a GET request to the alternate price API with the foreign money pairs.
The response will comprise the conversion price. Lastly we replace the outcome with a formatted transformed quantity
1 |
perform convertCurrency() { |
2 |
const BASE_URL = `https://v6.exchangerate-api.com/v6/${apiKey}`; |
3 |
|
4 |
const fromCurrrencyCode = doc.getElementById("fromCurrency").worth; |
5 |
const toCurrencyCode = doc.getElementById("toCurrency").worth; |
6 |
const outcome = doc.querySelector(".outcome"); |
7 |
const error = doc.querySelector(".error"); |
8 |
|
9 |
console.log(fromCurrrencyCode); |
10 |
console.log(toCurrencyCode); |
11 |
|
12 |
const quantity = enter.worth; |
13 |
|
14 |
if (quantity !== "" && parseFloat(quantity) >= 1) { |
15 |
const url = `${BASE_URL}/pair/${fromCurrrencyCode}/${toCurrencyCode}`; |
16 |
console.log(url); |
17 |
fetch(url) |
18 |
.then((resp) => resp.json()) |
19 |
.then((information) => { |
20 |
console.log(information.conversion_rate); |
21 |
|
22 |
const conversionResult = (quantity * information.conversion_rate).toFixed( |
23 |
2
|
24 |
);
|
25 |
const formattedResult = conversionResult.exchange( |
26 |
/B(?=(d{3})+(?!d))/g, |
27 |
"," |
28 |
);
|
29 |
|
30 |
outcome.innerHTML = `${quantity} ${fromCurrrencyCode} = ${formattedResult} ${toCurrencyCode}`; |
31 |
quantity.innerHTML = " "; |
32 |
})
|
33 |
.catch(() => { |
34 |
error.textContent = "An error occured, please attempt once more later "; |
35 |
});
|
36 |
} else { |
37 |
alert("Please enter an quantity"); |
38 |
}
|
39 |
}
|
If an error happens, we show a message to the person, letting them know one thing went fallacious.
For the conversion to work, let’s add an occasion listener to the convert button and invoke the convertCurrency()
perform, as proven beneath.
1 |
const convertBtn = doc.querySelector(".convert"); |
2 |
convertBtn.addEventListener("click on", () => { |
3 |
convertCurrency(); |
4 |
});
|
Ultimate Outcome
Right here is the ultimate outcome!
Conclusion
This tutorial has coated how one can construct a foreign money converter that fetches real-time information from the Change Price API. Make sure you get your free API key from the ExchangeRateAPI, and have enjoyable constructing issues!