Search code examples
javascripttwitter-bootstrapprogressive-web-appsofflinetoast

How do I trigger Bootstrap Toasts when the visitor is offline?


I have a website that works with the Bootstrap 5 theme and I want to show a Bootstrap Toasts message when the visitor is offline.

Currently the #BTNofflineToast button triggers #offlineToast

I want to remove the button and trigger the display of Toasts #offlineToast automatically when the visitor is offline.

How to do the JS code ?

(function() {

  window.addEventListener('offline', () => {
    // show toast
  });

  window.addEventListener('online', () => {
    // hide toast
  });

});

index.html

<!doctype html>
<html lang="fr" class="h-100">

  <head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="/bootstrap.min.css" rel="stylesheet">

  </head>

  <body class="d-flex flex-column bg-dark text-white text-center">

    <button type="button" class="btn btn-primary m-4" id="BTNupdateToast">Show update toast</button>

    <button type="button" class="btn btn-primary m-4" id="BTNofflineToast">Show offline toast</button>

    <div class="toast-container position-fixed bottom-0 start-50 translate-middle-x mb-3">
      <div id="updateToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
          <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-repeat text-success" viewBox="0 0 16 16">
            <path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z"/>
            <path fill-rule="evenodd" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z"/>
          </svg>
          <strong class="me-auto">Mise à jour disponible</strong>
        </div>
        <div class="toast-body text-start text-dark">
          Cliquez ICI pour mettre à jour.
        </div>
      </div>
      <div id="offlineToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
          <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-wifi-off text-danger" viewBox="0 0 16 16">
            <path d="M10.706 3.294A12.545 12.545 0 0 0 8 3C5.259 3 2.723 3.882.663 5.379a.485.485 0 0 0-.048.736.518.518 0 0 0 .668.05A11.448 11.448 0 0 1 8 4c.63 0 1.249.05 1.852.148l.854-.854zM8 6c-1.905 0-3.68.56-5.166 1.526a.48.48 0 0 0-.063.745.525.525 0 0 0 .652.065 8.448 8.448 0 0 1 3.51-1.27L8 6zm2.596 1.404.785-.785c.63.24 1.227.545 1.785.907a.482.482 0 0 1 .063.745.525.525 0 0 1-.652.065 8.462 8.462 0 0 0-1.98-.932zM8 10l.933-.933a6.455 6.455 0 0 1 2.013.637c.285.145.326.524.1.75l-.015.015a.532.532 0 0 1-.611.09A5.478 5.478 0 0 0 8 10zm4.905-4.905.747-.747c.59.3 1.153.645 1.685 1.03a.485.485 0 0 1 .047.737.518.518 0 0 1-.668.05 11.493 11.493 0 0 0-1.811-1.07zM9.02 11.78c.238.14.236.464.04.66l-.707.706a.5.5 0 0 1-.707 0l-.707-.707c-.195-.195-.197-.518.04-.66A1.99 1.99 0 0 1 8 11.5c.374 0 .723.102 1.021.28zm4.355-9.905a.53.53 0 0 1 .75.75l-10.75 10.75a.53.53 0 0 1-.75-.75l10.75-10.75z"/>
          </svg>
          <strong class="me-auto">Vous êtes hors-ligne</strong>
          <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
        </div>
        <div class="toast-body text-start text-dark">
          Les informations de cette page peuvent être obsolètes.
        </div>
      </div>
    </div>

    <script src="/bootstrap.bundle.min.js"></script>

    <script>
      document.getElementById("BTNupdateToast").onclick = function() {
        var toastElList = [].slice.call(document.querySelectorAll('#updateToast'))
        var toastList = toastElList.map(function(toastEl) {
          return new bootstrap.Toast(toastEl)
        });
       toastList.forEach(toast => toast.show());
      };

      document.getElementById("BTNofflineToast").onclick = function() {
        var toastElList = [].slice.call(document.querySelectorAll('#offlineToast'))
        var toastList = toastElList.map(function(toastEl) {
          return new bootstrap.Toast(toastEl)
        });
       toastList.forEach(toast => toast.show());
      };
    </script>

  </body>

</html>

Solution

    • To test properly, run the code snippet first, then disconnect your internet connection and review the snippet.

    • The message disappears automatically when reconnected.

    var connectionLostToast = new bootstrap.Toast(document.querySelector('#connectionLost'), {
      autohide: false
    });
    
    
    window.addEventListener('offline', function() {
      connectionLostToast.show();
    });
    
    
    
    window.addEventListener('online', function() {
      connectionLostToast.hide();
    });
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc" crossorigin="anonymous"></script>
    
    <div class="toasts">
    
      <div id="connectionLost" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
          <strong class="me-auto">Connection Lost</strong>
          <small>Now</small>
          <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
        </div>
        <div class="toast-body">
          Your internet connection lost!
        </div>
      </div>
    
    </div>