Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Async Dislogs Example</title>
  <script src="//cdn.jsdelivr.net/bluebird/3.0.5/bluebird.js"></script>
  <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
      var time = document.getElementById('time-stamp');
      clockTick();
      setInterval(clockTick, 1000);
      function clockTick() {
        time.innerHTML = '' + new Date();
      }
    });
  </script>
  <style type="text/css">
    #progress-dialog {
      width: 200px;
      margin: auto;
      border: thin solid black;
      padding: 10px;
      background: lightgreen;
    }
    #progress-dialog .progress-bar {
      border: 1px solid black;
      margin: 10px auto;
      padding: 0;
      height: 20px;
    }
    #progress-dialog .progress-bar>div {
      background-color: blue;
      margin: 0;
      padding: 0;
      border: none;
      height: 20px;
    }
    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <p>The current time is <span id="time-stamp"></span>.</p>
  <p id="output">Ready</p>
  <button id="action">Show Progress Bar</button>
  <div id="progress-dialog" class="hidden">
    <div class="message">foobar</div>
    <div class="progress-bar">
      <div></div>
    </div>
    <div>
      <button class="cancel">Cancel</button>
    </div>
  </div>
</body>
</html>
 
var noop = function() {
  return this;
};
function UserCanceledError() {
  this.name = 'UserCanceledError';
  this.message = 'User canceled dialog';
}
UserCanceledError.prototype = Object.create(Error.prototype);
function Dialog() {
  this.setCallbacks(noop, noop);
}
Dialog.prototype.setCallbacks = function(okCallback, cancelCallback) {
  this._okCallback     = okCallback;
  this._cancelCallback = cancelCallback;
  return this;
};
Dialog.prototype.waitForUser = function() {
  var _this = this;
  return new Promise(function(resolve, reject) {
    _this.setCallbacks(resolve, reject);
  });
};
Dialog.prototype.cancel = function() {
  this._cancelCallback(new UserCanceledError());
};
Dialog.prototype.show = noop;
Dialog.prototype.hide = noop;
function ProgressDialog() {
  Dialog.call(this);
  this.el           = document.getElementById('progress-dialog');
  this.messageEl    = this.el.querySelector('.message');
  this.progressBar  = this.el.querySelector('.progress-bar>div');
  this.cancelButton = this.el.querySelector('button.cancel');
  this.attachDomEvents();
}
ProgressDialog.prototype = Object.create(Dialog.prototype);
ProgressDialog.prototype.attachDomEvents = function() {
  var _this = this;
  this.cancelButton.addEventListener('click', function() {
    _this.cancel();
  });
  
};
ProgressDialog.prototype.show = function(message) {
  this.messageEl.innerHTML = '' + message;
  this.el.className = '';
  return this;
};
ProgressDialog.prototype.hide = function() {
  this.el.className = 'hidden';
  return this;
};
ProgressDialog.prototype.setProgress = function(percent) {
  this.progressBar.style.width = percent + '%';
};
function delayedPromise(progressCallback) {
  var step = 10;
  return new Promise(function(resolve, reject) {
    // So first run of nextTick will set progress to 0
    var progress = 0 - step;
    function nextTick() {
      if (progress >= 100 ) {
        resolve('done');
      } else {
        progress += step;
        progressCallback(progress);
        setTimeout(nextTick, 500);
      }
    }
    nextTick();
  });
}
document.addEventListener('DOMContentLoaded', function() {
  var button = document.getElementById('action');
  var output = document.getElementById('output');
  var prompt = new ProgressDialog();
  button.addEventListener('click', function() {
    var pendingProgress = true;
    var waitForPromise = delayedPromise(function(progress) {
      if (pendingProgress) {
        prompt.setProgress(progress);
      }
    });
    
    button.disabled = true;
    prompt.show('Simulating a file upload.');
    
    Promise.race([waitForPromise, prompt.waitForUser()])
      .then(function() {
        output.innerHTML = 'Progress completed';
      })
      .catch(UserCanceledError, function() {
        output.innerHTML = 'Progress canceled by user';
      })
      .catch(function(e) {
        console.log('Error', e);
      })
      .finally(function() {
        pendingProgress = false;
        button.disabled = false;
        prompt.hide();
      });
  });
});
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
sukimapro
0viewers