Stacking Dynamically Created Bootstrap Toast Notifications


A project I'm currently working on implements the Bootstrap 5 CSS framework.  One of the things i want to do is pop toast notifications to let the user know, in a subtle way, the result of actions that they take - a pretty common thing these days.

Bootstrap has a nice Toast implementation but it expects the toast HTML structure to be built and then lets you manage that via JavaScript.  BUT, what if you want something a little more flexible and sophisticated?  Maybe the notifications will sometimes come several at a time and you'd like to stack them.

Bootstrap has a solution for that too - but again, it expects the HTML structure of multiple toast sections to be built and in place.  

What I really wanted was to be able to dynamically create the toast structure, insert it into the DOM and, if applicable, have them stack nicely rather than overlap.

Here's what I ended up with, and it works pretty nicely.

The HTML for the Toast Container looks like this:

     <!--toast messaging-->  
     <div class="toast-container" id="toastContainer"></div>  

The Javascript

   popToast: function (bodyText) {  
     //when we pop a toast notification  
     //we are dynamically creating the toast element and adding it to the default.html toastContainer  
     //we also try to figure out how to stack them b/c bootstrap doesn't do that - even if placed in a toast-container div  
   
     //get the container and count/calculate the bottom placement of the toast about to be added  
     var container = document.getElementById("toastContainer");  
     var containerCount = container.childElementCount;  
     var noticePlacement = containerCount === 0 ? "5px" : (containerCount * 105) + "px";  
   
     //the static template  
     var toastTemplate = `<div style="z-index: 9999;width:400px;${noticePlacement};position:fixed;margin-left:40%;margin-right:40%" class="toast" role="alert" aria-live="assertive" data-bs-delay="4000" aria-atomic="true">  
         <div class="toast-header" style="background-color:skyblue">  
           <strong class="me-auto" style="color:white">iQueue</strong>  
           <small style="color:white">moments ago</small>  
           <button type="button" class="btn-close" data-bs-dismiss="toast" style="color:white" aria-label="Close"></button>  
         </div>  
         <div class="toast-body" id="divMainToast">  
           ${bodyText}  
         </div>  
       </div>`;  
   
     //create the template and toast elements/add to container  
     var newToastTemplate = document.createElement("template");  
     newToastTemplate.innerHTML = toastTemplate.trim();  
     var newToast = newToastTemplate.content.firstChild;  
     document.getElementById("toastContainer").appendChild(newToast);  
   
     //create/show the bs toast object from the dynamically created toast element  
     var bsToast = new bootstrap.Toast(newToast);  
     bsToast.show();  
       
     //remove this toast element from the container when it fires the hidden event  
     newToast.addEventListener("hidden.bs.toast", function () {  
       document.getElementById("toastContainer").removeChild(newToast);  
     })  
   },  

Notes

In a nutshell, when popToast() is called, it adds a bootstrap toast structure to the container.  The toastTemplate string pulls in the values for the body of the toast and the placement needed to stack.  Placement is a calculation based on the number of existing notifications - to get a stacked effect.

I did a little playing with the standard format of the toast (made it wider, used my own color scheme, etc).

It's important to remember to remove the toast from the container when its "hidden" event is fired - that's what the addEventListener() does at the end.  This keeps the container child count accurate.

There are probably much better ways to accomplish this - but this approach does what i need it to do with little extraneous coding required.

No comments:

Post a Comment

Microsoft Power Pages - Importing JS Libraries

  INTRODUCTION Microsoft Power Pages is a platform for developing web sites - from very simple... to surprisingly complex.  However, with ad...