Crie um conversor de moeda com HTML, CSS e Vanilla JavaScript

Vamos criar um aplicativo conversor de moeda totalmente funcional usando HTML, CSS e JavaScript vanilla. Ao final deste tutorial, teremos um aplicativo de moeda responsivo que busca dados em tempo real com a API Exchange Rate e os apresenta em uma interface amigável.

Estrutura HTML

Nosso aplicativo de moeda terá uma interface simples contendo:

  • Um campo de entrada para o valor a ser convertido.
  • Um menu suspenso para selecionar o valor da moeda
  • Um segundo menu suspenso para selecionar o valor da moeda
  • Um botão de conversão
  • A

    tag para mostrar o valor convertido

  • A

    tag para mostrar quaisquer erros que possam ocorrer durante o processo de conversão.

O código HTML ficará assim:

1
 class="container">
2

3
   class="currency-container">
4
    

Currency converter

5
     class="input-box">
6
       for="amount">Enter amount
7
       type="text" id="amount" placeholder="100"  required/>
8
    
9
     class="currency">
10
       class="box">
11
        
12
          class="select-option"
13
          name="from-currency"
14
          id="fromCurrency"
15
        >
16
           value="USD">United States Dollar
17
        
18
      
19
      
20
        TO
21
      
22
       class="box">
23
         class="select-option" name="to-currency" id="toCurrency">
24
           value="USD">United States Dollar
25
        
26
      
27
       class="convert">Convert
28
       class="result">

29
       class="error">

30

31
    
32
  
33

Atualmente, estamos usando o valor da opção como espaço reservado. Substituiremos e adicionaremos mais dados de opções dinamicamente com JavaScript.

Estilo com CSS

Vamos começar com alguns estilos básicos. Também extraímos a excelente fonte Bricolage Grotesque das fontes do Google:

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: bold;
11
        text-align: center;
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
        color: #040203;
22
        display: flex;
23
        flex-direction: column;
24
        align-items: center;
25
        justify-content: center;
26
      }
27

28
      .currency-container {
29
        height: fit-content;
30
        background-color: #7cb889;
31
        padding: 3em;
32
        border-radius: 40px;
33
      }

Para a entrada e o rótulo (incluindo o espaço reservado na entrada) eles terão os seguintes estilos:

1
      .input-box {
2
        display: flex;
3
        flex-direction: column;
4
        align-items: center;
5
        justify-content: center;
6
        text-align: center;
7
      }
8

9
      label {
10
        font-size: 1.5em;
11
        margin-bottom: .4em;
12
      }
13

14
      #amount {
15
        width: 300px;
16
        padding: 20px;
17
        border-radius: 30px;
18
        font-size: 3em;
19
        border: 3px solid black;
20
        background: transparent;
21
        color: black;
22
        
23
      }
24
      #amount:focus {
25
        border: 3px solid white;
26
        outline: none;
27
      }
28

29
      ::placeholder {
30
        color: rgba(0,0,0,0.6);
31
        opacity: 1; /* Firefox */
32
      }

A seguir, aplicaremos estilo aos elementos da caixa que contêm o De e Para menus suspensos de moeda. Os elementos suspensos serão organizados em um layout de coluna usando Flexbox e centralizados vertical e horizontalmente. Também temos um espaço entre os elementos da caixa, algum preenchimento e um raio de borda.

1
      .currency {
2
        margin-top: 50px;
3
        padding: 20px 20px;
4
        display: flex;
5
        align-items: center;
6
        justify-content: center;
7
        flex-direction: column;
8
        gap: 1.5rem;
9
      }
10

11
      .box {
12
        display: flex;
13
        align-items: center;
14
        justify-content: center;
15
      }

A opção de seleção terá os seguintes estilos

1
      .select-option {
2
        font-size: 16px;
3
        color: #333;
4
        padding: 20px;
5
        display: block;
6
        font-weight: 700;
7
        line-height: 1.3;
8
        width: 100%;
9
        max-width: 100%;
10
        margin: 0;
11
        outline: none;
12
        border-radius: 20px;
13
        border: 3px solid black;
14
      }

Por fim, o botão de conversão, o resultado e os elementos da mensagem de erro terão os seguintes estilos:

1
      button {
2
        width: 100%;
3
        height: 100px;
4
        padding: 10px;
5
        border-radius: 30px;
6
        border: none;
7
        font-size: 1.5em;
8
        align-items: center;
9
        background-color: black;
10
        color: #fff;
11
        margin-top: 30px;
12
      }
13
      .result {
14
        color: black;
15
        font-size: 2.5em;
16
      }
17
      .error {
18
        color: #800020;
19
        font-size: 12px;
20
      }

Funcionalidade JavaScript

A funcionalidade JavaScript terá duas partes:

  • Obtendo o código da moeda, o nome da moeda e a bandeira da API de países REST
  • obtendo taxa de conversão da API Exchange Rate

API REST de países

O API de países REST fornece uma API com o endpoint https://restcountries.com/v3.1/all onde você pode filtrar os resultados fornecendo os campos de seu interesse. Em nosso caso, queremos a bandeira do país, o nome da moeda e o código da moeda e o ponto final ficará assim:

1
https://restcountries.com/v3.1/all?fields=currencies,flag

Os dados de amostra resultantes serão assim:

1
{
2
    "name": {
3
      "common": "Eritrea",
4
      "official": "State of Eritrea",
5
      "nativeName": {
6
        "ara": {
7
          "official": "دولة إرتريا",
8
          "common": "إرتريا‎"
9
        },
10
        "eng": {
11
          "official": "State of Eritrea",
12
          "common": "Eritrea"
13
        },
14
        "tir": {
15
          "official": "ሃገረ ኤርትራ",
16
          "common": "ኤርትራ"
17
        }
18
      }
19
    },
20
    "currencies": {
21
      "ERN": {
22
        "name": "Eritrean nakfa",
23
        "symbol": "Nfk"
24
      }
25
    },
26
    "flag": "🇪🇷"
27
  },

Para facilitar a exibição de nossas moedas, buscaremos os dados e os armazenaremos em um arquivo JavaScript. O script para buscar os dados ficará assim:

1
const url =
2
  "https://restcountries.com/v3.1/all?fields=name,currencies,flag";
3
fetch(url)
4
  .then((response) => response.json())
5
  .then((data) => {
6
    
7
    const result = [];
8
    data.forEach((country) => {
9
      if (Object.keys(country.currencies).length >0) {
10
        result.push({
11
          countryname: country.name.common,
12
          name: Object.values(country.currencies)[0].name,
13
          code: Object.keys(country.currencies)[0],
14
          flag: country.flag,
15
        });
16
      }
17
    });
18

19
    result.sort((a, b) => a.code.localeCompare(b.code));
20
    const jsonString = JSON.stringify(result, null);
21
    console.log(jsonString);
22

23
  });

O código acima faz o seguinte:

  • Nós usamos o fetch() método para fazer uma solicitação HTTP para a API de países REST.
  • Em seguida, convertemos a resposta para o formato JSON e iniciamos o processamento dos dados.
  • A partir do JSON de resposta, primeiro verificamos se cada país possui um código de moeda, pois nem todos os países possuem um código de moeda.
  • Se um país tiver uma moeda, criamos um objeto com seu nome, código e nome da moeda e o enviamos para a matriz de resultados vazia.
  • Em seguida, classificamos o código da moeda em ordem alfabética.
  • Finalmente, convertemos o resultado para JSON e imprimimos o estringificado dados para o console.

Ao executar o script em um ambiente de navegador, você poderá copiar os dados para seu arquivo JavaScript. Os dados são assim:

Alternativamente, adicione este link ao seu script usando o src atributo.

A seguir, vamos obter os elementos selecionados.

1
let fromCurrency = document.getElementById("fromCurrency");
2
let toCurrency = document.getElementById("toCurrency");

Como temos os dados em um array, agora é mais fácil anexar as moedas aos elementos de opção dos elementos fromCurrency e toCurrency select.

Crie uma função chamada addCurrency(). Dentro de addCurrency() função, usamos o forEach() função para percorrer a matriz de moedas; para cada iteração, queremos adicionar o código da moeda ao elemento de opção e anexar o elemento de opção a ambos os elementos de seleção.

1
 const result = currencies.forEach((currency) => {
2

3
    const optionFrom = document.createElement("option");
4
    optionFrom.classList.add("select-option");
5
    optionFrom.value = currency.code;
6
    if (currency.code === "USD") {
7
      optionFrom.selected = true;
8
    }
9
    optionFrom.text =`${currency.flag} ${currency.code} - ${currency.name}`;
10

11
    fromCurrency.appendChild(optionFrom);
12

13
    const optionTO = document.createElement("option");
14
    optionTO.classList.add("select-option");
15
    optionTO.value = currency.code;
16
    if (currency.code === "EUR") {
17
      optionTO.selected = true;
18
    }
19
    optionTO.text =`${currency.flag} ${currency.code} - ${currency.name}`;
20
    toCurrency.appendChild(optionTO);
21
  });

No código acima, usamos o ForEach() função para iterar em cada dado da matriz de moedas e fazer o seguinte:

  • Extrai a chave da moeda da matriz de moedas para cada moeda
  • recebe a bandeira
  • obtém o nome da moeda
  • Cria um elemento de opção HTML para o “fromCurrency“selecione o menu suspenso.
  • define o valor da opção para o código da moeda
  • Define o texto da opção como uma combinação do sinalizador, do nome da moeda e do código da moeda
  • Acrescenta o elemento de opção criado ao “fromCurrency” selecione o menu suspenso.
  • Cria outro elemento de opção para o “toCurrency” selecione o menu suspenso com os mesmos dados do fromCurrency
  • Acrescenta o elemento de opção criado ao menu suspenso de seleção “toCurrency”.
  • Finalmente invocamos o addCurrency() função para aplicar a funcionalidade.

O valor da opção será o código da moeda e o texto da opção será a bandeira da moeda, o código da moeda e o nome da moeda separados por um hífen.

Também definimos a moeda padrão no fromCurrency elemento de opção para USD e a moeda padrão para o toCurrency elemento de opção para EUR.

Agora nosso menu suspenso mostra as moedas.

Refatoração de código

De addCurrency() função você pode ver que estamos repetindo o mesmo código para adicionar os valores das opções. Vamos criar outra função para gerar as opções para cada elemento da moeda.

A função ficará assim:

1
function createOption(country, defaultCode, element ){
2
    // console.log(country);

3
    const option = document.createElement("option");
4
    option.classList.add("select-option");
5
    option.value = country.code;
6
    if (country.code === defaultCode) {
7
      option.selected = true;
8
    }
9
    option.text = `${country.flag} ${country.code} - ${country.name}`;
10
    element.appendChild(option);
11

12

13
}

O createOption() A função leva três parâmetros: o objeto do país, o código padrão e o elemento onde as opções serão anexadas.

A seguir, atualize a função addCurrency() da seguinte forma:

1
function addCurrency() {
2
  const result = countries.map((country) => {
3
      createOption(country, "USD", fromCurrency );
4
      createOption(country, "EUR", toCurrency )
5

6
  });
7
}

A função agora é mais fácil de ler, pois não temos nenhum código repetitivo.

conversão de moeda

Usaremos a API ExchangeRate para conversão de moeda. A API ExchangeRate fornece taxas de conversão de moeda para 161 moedas.

A API permite que os desenvolvedores convertam moedas fornecendo um par de códigos de moeda na solicitação. Por exemplo, se você deseja converter USD em EUR, sua chamada de API será semelhante a esta:

1
https://v6.exchangerate-api.com/v6/24faec6b42da4a96ceea41d3/pair/USD/EUR

O endpoint nos dará o seguinte resultado.

1
{
2
  "result": "success",
3
  "documentation": "https://www.exchangerate-api.com/docs",
4
  "terms_of_use": "https://www.exchangerate-api.com/terms",
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
}

Como já temos os códigos em nossas opções de select, passaremos os valores na API e multiplicaremos a taxa de conversão pelo valor para obter o resultado.

Crie uma função chamada convertCurrency() função. Na função:

  • obter o elemento de exibição
  • obtenha os valores das opções selecionadas
  • Armazene o URL em uma variável.
1
const BASE_URL = `https://v6.exchangerate-api.com/v6/${apiKey}`;
2
const fromCurrrencyCode = document.getElementById("fromCurrency").value;
3
const toCurrencyCode = document.getElementById("toCurrency").value;
4
const result = document.querySelector(".result");
5
const error = document.querySelector(".error");

Certifique-se de fornecer sua chave de API da API Exchange Rate. Você pode obter um gratuitamente aqui.

No convertCurrency() função, primeiro verificamos se um valor válido foi inserido e, se for verdade, realizamos uma solicitação GET para a API de taxa de câmbio com os pares de moedas.

A resposta conterá a taxa de conversão. Finalmente, atualizamos o resultado com um valor convertido formatado

1
function convertCurrency() {
2
  const BASE_URL = `https://v6.exchangerate-api.com/v6/${apiKey}`;
3

4
  const fromCurrrencyCode = document.getElementById("fromCurrency").value;
5
  const toCurrencyCode = document.getElementById("toCurrency").value;
6
  const result = document.querySelector(".result");
7
  const error = document.querySelector(".error");
8

9
  console.log(fromCurrrencyCode);
10
  console.log(toCurrencyCode);
11

12
  const amount = input.value;
13

14
  if (amount !== "" && parseFloat(amount) >= 1) {
15
    const url = `${BASE_URL}/pair/${fromCurrrencyCode}/${toCurrencyCode}`;
16
    console.log(url);
17
    fetch(url)
18
      .then((resp) => resp.json())
19
      .then((data) => {
20
        console.log(data.conversion_rate);
21

22
        const conversionResult = (amount * data.conversion_rate).toFixed(
23
          2
24
        );
25
        const formattedResult = conversionResult.replace(
26
          /\B(?=(\d{3})+(?!\d))/g,
27
          ","
28
        );
29

30
        result.innerHTML = `${amount} ${fromCurrrencyCode} = ${formattedResult} ${toCurrencyCode}`;
31
        amount.innerHTML = " ";
32
      })
33
      .catch(() => {
34
        error.textContent = "An error occured, please try again later ";
35
      });
36
  } else {
37
    alert("Please enter an amount");
38
  }
39
}

Se ocorrer um erro, exibimos uma mensagem ao usuário informando que algo deu errado.

Para que a conversão funcione, vamos adicionar um ouvinte de evento ao botão de conversão e invocar o convertCurrency() função, conforme mostrado abaixo.

1
const convertBtn = document.querySelector(".convert");
2
convertBtn.addEventListener("click", () => {
3
  convertCurrency();
4
});

Resultado final

Aqui está o resultado final!

Conclusão

Este tutorial abordou como construir um conversor de moeda que busca dados em tempo real da API Exchange Rate. Certifique-se de obter sua chave de API gratuita do ExchangeRateAPI e divirta-se construindo coisas!

Deixe uma resposta