Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <body>
  <div class="container">
    <h1 class="title">Amazing Currency 💸 Converter</h1>
    <div class="slider-wrapper">
      <div class="slider">
        <div class="sliding active flex-center">
          <div id="get_curr" class="grid">
            <p id="msg1" class="msg">Use the suggestion from the list while typing or use all caps to fetch exchange rate from internet</p>
            <label for="source-currency-unit">Convert :</label>
            <label for="target-currency-unit">To :</label>

            <input list="currency" type="text" id="source-currency-unit" placeholder="Ex.: USD" required="True" autocomplete="False" autofocus="True"></input>
            <input list="currency" type="text" id="target-currency-unit" placeholder="Ex.: EUR" required="True" autocomplete="False"></input>

            <button type="button" class="btn exchange_button">
              <svg role="presentation" class="icon exchange__icon" width=24 height=24>
                <use xlink:href="#exchange__icon" />
              </svg>
            </button>

            <datalist id="currency"></datalist>
            <button type="button" id="next" class="btn next"><span class="arrow"><span></button>
          </div>
        </div>
        <div class="sliding flex-center">
          <div id="get_conv" class="grid">
            <p id="msg2">Converting $1 to $2 </p>
            <button type="button" class="change btn">Change</button>
            <div class="grid">
              <label for="original-currency-amount"> Ammount :</label>
              <input type="number" id="original-currency-amount" placeholder="1"></input>

              <label for="exchange-rate">Exchange Rate:</label>
              <input type="number" id="exchange-rate"></input>
            </div>
            <button id="convert" class="btn convert">Exchange my money now!</button>

            <p id="output-text">Converted 💰 will appear here.</p>
          </div>
        </div>
      </div>
    </div>
    <div id="source" class="source">
      <p>In the backend <a href="https://exchangeratesapi.io/" target="blank">exchangeratesapi</a> is used for getting supported currencies and the exchange rate</p>
    </div>

  </div>
  <svg display="none">
    <symbol id="exchange__icon" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
      <path d="M215.793 181.362L275 120.814M274.377 120.814L215.169 60.267M84.2074 118.905L25 179.453M25.6232 179.453L84.8307 240M84.7771 207.368H155.288M85.2178 239.366V207.819M84.3364 150.133V118.587M143.83 91.9974H214.341M215.663 180.779V149.232M214.782 91.5467V60M83.8957 149.683H216.104" stroke="currentColor" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" />
  </svg>
  </symbol>
  <script src="index.pack.js"></script>
  <!-- <script src="index.js"></script> -->
</body>
              
            
!

CSS

              
                @import url("https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&display=swap");

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Removing arrow from number type input */
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Firefox */
input[type="number"] {
  -moz-appearance: textfield;
}

input {
  padding: 5px;
  max-width: 15ch;
  border-radius: 3px;
  border: 1px solid white;
}

body {
  font-family: "Raleway", sans-serif;
  background-color: #08aeea;
  background-image: linear-gradient(0deg, #08aeea 0%, #2af598 100%);
}

.container {
  min-height: 100vh;
  margin: 0 auto;
  display: grid;
  grid-template:
    "title title title" minmax(min-content, 5rem)
    ". content ." minmax(100px, auto)
    "footer footer footer" minmax(2.5rem, max-content)
    / minmax(20px, 1fr) 5fr minmax(20px, 1fr);
}
/*  minmax(1fr, 20px)*/
.title {
  grid-area: title;
  color: black;
  font-weight: bolder;
  text-align: center;
  max-height: rem;
  padding: 10px;
  border-bottom: 0.45rem solid royalblue;
}

.slider-wrapper {
  grid-area: content;
  overflow: hidden;
  width: 100%;
  min-width: 340px;
  display: flex;
  align-items: cennter;
  justify-content: center;
  /*   background-color:#ffffff65; */
}

.source {
  grid-area: footer;
  padding: 10px;
  font-size: 0.75rem;
  text-align: right;
}

.slider {
  width: 100%;
  transform-style: preserve-3d;
  display: grid;
  grid-template-columns: repeat(2, 100%);
  transform: translateX(0);
  transition: transform 450ms;
}
.sliding {
  min-height: 100%;
  padding: 10px;
  align-self: center;
  background-color: #ffffff65;
  /*   border:1px solid red; */
}

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
.flex_row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1ch;
}

.grid {
  /* 	max-width: 600px; */
  display: grid;
  grid-template-columns: repeat(2, auto);
  align-items: center;
  justify-content: center;
  grid-gap: 1ch;
}

.btn {
  color: darkblue;
  cursor: pointer;
  padding: 0.35rem;
  border-radius: 3px;
  border: 1px solid;
  background: transparent;
  transition: 300ms color ease-in-out;
}

.btn:hover {
  color: black;
}

.convert {
  min-height: 100%;
}

#output-text {
  margin: 1rem;
  grid-column: span 2;
}

.msg {
  grid-column: span 2;
  width: 24ch;
  margin-bottom: 1.5rem;
}

.sliding {
  position: relative;
}
.exchange_button {
  grid-column: span 2;
  align-self: center;
  /* width: min-content; */
}
.next {
  position: absolute;
  bottom: 50%;
  left: 88%;
  transform: translate(20%, 50%);
  border-radius: 25px;
  background-color: #d0d0d065;
  border-color: transparent;
  transition: 300ms border-color ease-in-out;
}
.next:hover {
  border-color: royalblue;
}
.arrow {
  width: 20px;
  height: 20px;
  border: solid black;
  border-width: 0 3px 3px 0;
  display: inline-block;
  padding: 3px;
  transform: translateX(-25%) rotate(-45deg);
}

.curr_input {
  position: relative;
}

              
            
!

JS

              
                let source_currency = "";
let target_currency = "";
let curr_list = [];

const msg1 = document.getElementById("msg1");
const msg2 = document.getElementById("msg2");
const sliding = document.querySelector(".sliding");
const slider = document.querySelector(".slider");
const nxt_btn = document.getElementById("next");
const convert_btn = document.getElementById("convert");
const datalist = document.getElementById("currency");
const output = document.getElementById("output-text");
const ex_rate_box = document.getElementById("exchange-rate");
const target_currency_box = document.getElementById("target-currency-unit");
const source_currency_box = document.getElementById("source-currency-unit");
const source_amount_box = document.getElementById("original-currency-amount");

// Break the list adding code into a function for easier re-use
const addListEntry = (value, text) => {
  // Create a new option element.
  var optionNode = document.createElement("option");
  // Set the value
  optionNode.value = value;
  // create a text node and append it to the option element
  optionNode.appendChild(document.createTextNode(text));
  // Add the optionNode to the datalist
  datalist.appendChild(optionNode);
};

// this func will load all supported currencies into a datalist
// and in an array for some logical operation later
const loadSupporedCurrencies = async () => {
  //   reseting all the inputbox values
  ex_rate_box.value = "";
  source_amount_box.value = "";
  source_amount_box.value = "";
  target_currency_box.value = "";

  //   getting all the supported currencies from `exchangeratesapi`
  let response = await fetch("https://api.exchangeratesapi.io/latest");
  let data = await response.json();

  //   adding the base currency to the list
  addListEntry(data.base, data.base);
  curr_list.push(data.base);

  // Read currencies as key from the json obj and pushing into the list
  for (let key in data.rates) {
    addListEntry(key, key);
    curr_list.push(key);
  }
};

// gets exchange rate for specific currencies
const getExRate = async (frm, to) => {
  let req_url = `https://api.exchangeratesapi.io/latest?base=${frm}&symbols=${to}`;
  let res = await fetch(req_url);
  let data = await res.json();

  return data.rates[to];
};

// loading the rates in the inputbox
const loadExRate = async (frm, to) => {
  // let ex_rate = document.getElementById("exchange-rate")
  let rate = await getExRate(frm, to);

  ex_rate_box.value = rate;
  //   disabling the exchange rate inputbox as the value is
  // loaded beforehand
  ex_rate_box.disabled = "true";
};

// animating between two divs
// `true` for backward animation
// `false` for forward animation
const animateSlider = (isPositive) => {
  // dynamically getting the length to translate
  let to_translate = sliding.offsetWidth;

  if (isPositive) {
    slider.style.transform = `translate(0px)`;
  } else {
    slider.style.transform = `translate(${-to_translate}px)`;
  }
};

// it will handel all the logics related to gettng currencies
// and the exchange rate from the internet if exists
const fetchCurrency = async () => {
  source_currency = source_currency_box.value.toString();
  target_currency = target_currency_box.value.toString();

  //   basic validations
  if (source_currency === target_currency) {
    source_currency_box.focus();
    alert("source and target currency can't be same or empty !");
    return;
  } else if (source_currency === "") {
    source_currency_box.focus();
    alert("source currency can't be empty !");
    return;
  } else if (target_currency === "") {
    target_currency_box.focus();
    alert("target currency can't be empty !");
    return;
  } else {
    let s_found = curr_list.find((crr) => crr == source_currency);
    let t_found = curr_list.find((crr) => crr == target_currency);

    // if source currency is not supported
    if (s_found == undefined) {
      msg2.innerHTML = `target currency <b>not found</b> for Converting <b>${source_currency}</b> to <b>${target_currency}</b>.\n Enter Exchage rate yourself !`;
      animateSlider(false);
      // to get a smooth animation without jumping arround
      setTimeout(() => ex_rate_box.focus(), 300);
      // if target currency is not supported it does not loades the rate and does not
      // disable the exchange rate inputbox
    } else if (t_found == undefined) {
      msg2.innerHTML = `target currency <b>not found</b> for Converting <b>${source_currency}</b> to <b>${target_currency}</b>.\n Enter Exchage rate yourself !`;
      animateSlider(false);
      // to get a smooth animation without jumping arround
      setTimeout(() => ex_rate_box.focus(), 300);
      // if exchange rate is found for the source and target
    } else {
      msg2.innerHTML = `Exchange rate found for Converting <b>${source_currency}</b> to <b>${target_currency}</b> `;
      animateSlider(false);
      loadExRate(source_currency, target_currency);
      // to get a smooth animation without jumping arround
      setTimeout(() => source_amount_box.focus(), 300);
    }
  }
};

// button click event for getting the currencies and fetching the rate
nxt_btn.addEventListener("click", () => {
  console.log("Try Using `Enter` from your keyboard inside the inputbox");
  fetchCurrency();
});

// key press event for getting the currencies and fetching the rate
document.getElementById("get_curr").addEventListener("keyup", (event) => {
  if (event.key == "Enter") {
    fetchCurrency();
  }
});

// this function converts the source amount by the exchange rate
const getConverted = () => {
  // getting the amount and rate in float value
  let amt = parseFloat(source_amount_box.value);
  let r = parseFloat(ex_rate_box.value);

  // basic validations
  if (isNaN(amt) || amt <= 0) {
    alert("Source ammount need to be a positive number");
    source_amount_box.focus();
    return;
  } else if (isNaN(r) || r <= 0) {
    alert("Exchange rate need to be a positive number");
    ex_rate_box.disabled = false;
    ex_rate_box.focus();
    return;
  }
  // setting the output inside an html element
  let res = r * amt;
  // console.log(res)
  output.innerHTML = `Your <b>${amt.toFixed(
    2
  )} ${source_currency}</b> is converted to <b>${res.toFixed(
    2
  )} ${target_currency}</b> 🤑`;
};

// button click event for getting the converted currencies and printing the output
convert_btn.addEventListener("click", () => {
  console.log("Try Using `Enter` from your keyboard inside the inputbox");
  getConverted();
});

// key press event for getting the converted currencies and printing the output
document.getElementById("get_conv").addEventListener("keyup", (event) => {
  if (event.key == "Enter") {
    getConverted();
  }
});

// change button
document.querySelector(".change").addEventListener("click", () => {
  // animate to prev window
  animateSlider(true);
  // reset
  ex_rate_box.disabled = false;
  ex_rate_box.value = "";
  output.innerHTML = "Converted 💰 will appear here.";
});

// swaping source and target currency on button press
document.querySelector(".exchange_button").addEventListener("click", () => {
  let temp = source_currency_box.value;
  source_currency_box.value = target_currency_box.value;
  target_currency_box.value = temp;
});

// document.addEventListener("DOMContentLoaded", () =>)
// loading currency datalist and array on load
loadSupporedCurrencies();
              
            
!
999px

Console