DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 968,873 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Animate Loading Indicator on Button With Vanilla Javascript
Anwar Sadat Ayub
Anwar Sadat Ayub

Posted on

Animate Loading Indicator on Button With Vanilla Javascript

Hi there πŸ™‹πŸΎβ€β™‚οΈ,

In today's post, we are making a loading indicator on a submit button. This is a common feature nowadays to display/hide spinner on a button while application is in a busy state. I did this at a very basic level i.e. without any complicated code. There are several ways to do this. Please do not hesitate to share them with us 😊.

Basic skills in HTML, CSS and Javascript will be just fine to follow this post.

To the coding part, we will only need 3 files;

  • index.html
  • style.css
  • main.js

Start by creating an html boiler plate:

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Loading Indicator</title>
</head>
<body>

</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Next we bring in our css and javascript files into the index.html;

index.html
    <link rel="stylesheet" href="style.css" />
    <script src="main.js" defer></script>
Enter fullscreen mode Exit fullscreen mode

To get a feel of submitting a data, we will create a dummy form and add two input elements and a submit button even though we will not submit any data.

index.html
    <form class="sampleForm">
      <h1>Login form</h1>
      <div>
        <input type="text" placeholder="Enter email" />
      </div>
      <div>
        <input type="password" placeholder="Enter password" />
      </div>
      <button id="btnSubmit">
        <span id="btnSubmitText">Submit</span>
      </button>
    </form>
Enter fullscreen mode Exit fullscreen mode

From the code we just added, we have a;

  • form with an id of sampleForm
  • 2 input elements ( a text and a password type both with placeholders)
  • a submit button with a child span element with an id of btnSubmitText

At this point we will use fontawesome's spinner icon. We include the cdn but you can also download the kit and set it up manually if you are familiar with the process.

index.html
<!-- Fontawesome cdn -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
   integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />
Enter fullscreen mode Exit fullscreen mode

We will now add two child elements in the buttom: the fontawesome's spinner icon and span element as below;

index.html
<button id="btnSubmit">
  <span id="btnSubmitText">Submit</span>
  <i class="fa-solid fa-spinner fa-spin"></i>
</button>
Enter fullscreen mode Exit fullscreen mode

The fa-spinner class adds the spinner icon and to animate the icon, we add fa-spin class. There are other animations like beat, fade, bounce, shake, etc, all at fontawesome animation.

Next we add some styles to our form.

style.css
.sampleForm {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
input {
  padding: 10px;
  margin: 5px;
  width: 250px;
}
button {
  background-color: orange;
  color: white;
  border: none;
  font-size: 20px;
  padding: 10px;
  width: 150px;
  height: 50px;
  cursor: pointer;
}
.fa-spinner {
  display: none;
}

Enter fullscreen mode Exit fullscreen mode

The button has a fixed width and height. This is to maintain the same button size when we toggle the icon and text. Initially we are hiding the icon and showing the text on the button. When we click on the button, the text will be set to display:none and the icon will be set display:block. Let's do that right now.

In the main.js file, add the following code

main.js
const btnSubmit = document.getElementById('btnSubmit')

btnSubmit.addEventListener('click', (event) => {
  event.preventDefault()

})
Enter fullscreen mode Exit fullscreen mode

So we grab the submit button and assign it to btnSubmit then listen to the click event on the submit button. By default, a submit form button causes a web page to refresh each time it is clicked. To prevent that, we pass the event argument to the callback function and called the preventDefault() function of the event object.

Now when the button is clicked, we want to hide the text (which is currently displayed) and display the spin icon (which is currently hidden). Let's write that code

main.js
  //Hide the text
  document.getElementById('btnSubmitText').style.display = 'none'

  //Display the spin icon
  document.querySelector('.fa-spinner').style.display = 'block'
Enter fullscreen mode Exit fullscreen mode

Our code targets the span element that contains the text by id and assign the display property of it's style object to none which causes it to hide. On the hand, the icon is now displayed by setting it display property to block.

At this point, when we click the submit button, the submit text will hide and the spin icon will display.

Phewwwww...now that was a lot and you deserve the applause πŸŽ‰πŸ™ŒπŸ½πŸΎπŸ₯³πŸ₯³πŸŽ‰πŸŽ‰πŸ™ŒπŸ½
Image description

But we are not quite done yet. Our spin icon keeps spinning until we refresh the page and obviously we don't want that.
Normally when we send a form request, we expect a response and after the response, our button text should display and spin icon hidden.

To do that, we just do reverse of our code as below;

main.js
  document.getElementById('btnSubmitText').style.display = 'block'
  document.querySelector('.fa-spinner').style.display = 'none'
Enter fullscreen mode Exit fullscreen mode

Now after adding this code, it happens so fast that we don't see the spin icon right? We can fake a request/response by adding a delay of 2 seconds using the setTimeout function.

Our main.js file will now look like this;

main.js
const btnSubmit = document.getElementById('btnSubmit')

btnSubmit.addEventListener('click', (event) => {
  event.preventDefault()

  //Hide the text
  document.getElementById('btnSubmitText').style.display = 'none'

  //Display the spin icon
  document.querySelector('.fa-spinner').style.display = 'block'

  //2 seconds delay
  setTimeout(() => {
    //Show the text after 2 seconds
    document.getElementById('btnSubmitText').style.display = 'block'

    //Hide the spin icon after 2 seconds
    document.querySelector('.fa-spinner').style.display = 'none'
  }, 2000)
})

Enter fullscreen mode Exit fullscreen mode

As I mentioned earlier, this is just for basic level coding but you can definitely make this code better. Think of how you can make it reusable by introducing functions in the code.

You can download the files from my github repo. Please don't forget to leave a like πŸ‘πŸΌ.

Thanks for spending time to read and see you on the next one.

Top comments (0)

In defense of the modern web

I expect I'll annoy everyone with this post: the anti-JavaScript crusaders, justly aghast at how much of the stuff we slather onto modern websites; the people arguing the web is a broken platform for interactive applications anyway and we should start over;

React users; the old guard with their artisanal JS and hand authored HTML; and Tom MacWright, someone I've admired from afar since I first became aware of his work on Mapbox many years ago. But I guess that's the price of having opinions.