atslash
atslash

Reputation: 11

Display gif after confirm until loading is finished in javascript

I have a form that includes a Submit button. After the submit button is clicked, a confirmation popup appears. Once the confirm condition is met, an HTTP post takes place. However, sometimes that post can take a while. As such, I would like to display a loading gif after the confirm condition is met, up until the post response comes back, whereby the page is already reloading.

Upvotes: 1

Views: 1546

Answers (1)

Rico Kahler
Rico Kahler

Reputation: 19252

I would suggest using an element as some sort of modal then setting the css property visibility to and from hidden and visible.

Then you can add event handlers to your button presses and requests to hide or show this element.

See the example below:

const requestButton = document.querySelector('.request');
const yes = document.querySelector('.yes');
const no = document.querySelector('.no');
const confirmation = document.querySelector('.confirmation');
const loading = document.querySelector('.loading');
const content = document.querySelector('.content');

requestButton.addEventListener('click', event => {
  confirmation.style.visibility = 'visible';
});

yes.addEventListener('click', event => {
  // instead of a setTimeout, you'd actually make a request using `fetch` or jquery ajax
  loading.style.visibility = 'visible';
  confirmation.style.visibility = 'hidden';
  window.setTimeout(() => {
    // the code in this callback would be the same code you'd put in your `success` callback
    // i.e. this code should run when the request finishes
    loading.style.visibility = 'hidden';
    const p = document.createElement('p');
    p.innerText = 'Loaded!';
    content.appendChild(p);
  }, 2000);
});

no.addEventListener('click', event => {
  confirmation.style.visibility = 'hidden';
});
.hidden-center {
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  top: 0;
  left: 0;
  visibility: hidden;
}

.modal {
  background-color: lightgray;
  padding: 3em;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<div class="content">
  <button class="request">load a thingy?</button>
</div>
<div class="confirmation hidden-center">
  <div class="modal">
    Are you sure?
    <div>
      <button class="yes">Yes</button>
      <button class="no">No</button></div>
  </div>
</div>
<div class="loading hidden-center">
  <div class="modal">
    <div>Loading...</div>
    <i class="fa fa-spinner fa-spin fa-3x"></i>
  </div>
</div>

EDIT:

Reading the comments above, it looks like your application is not a single page application (I just assume nowadays). Instead of attaching an event listener to the button click, you need to attach the event listener to the form like so:

document.querySelector('#my-form-id').addEventListener('submit', event => {/*code to show loading*/})

Also, you probably don't need to add an event listener for the request coming back because the new document will replace the current one.

Upvotes: 1

Related Questions