How to create toasts using bootstrap 5
Updated: 6th December 2022
Tags: javascript bootstrap5 css
b5toastjs (method 1)
While using bootstrap 5 I wanted to ditch toastr and everything that was tied to jquery.
Besides, why do I need a big library if my goal is to show simple toast in the bottom left.
So I checked documentation to bootstrap 5. That was weird. Bootstrap 5 docs with live toast didn’t work as expected.
Anyway, I wanted to go fancy - to create multiple toasts like my beloved toastr did.
For toast to show we need to create that element and place in toast container.
<div class="position-fixed bottom-0 start-0 p-3" id="toast-container"></div>
and some js to create
//0. get our container
const toastContainerElement = document.getElementById("toast-container");
const delay = 10000;
const myToast = {
//here the core function.
//1. We get color, message and optional title
show: function (color, message, title) {
title = title ? title : '';
const html =
`<div class="toast align-items-center mt-1 text-white bg-${color} border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
<b>${title}</b>
<div>${message}</div>
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>`;
//2. We create toast element from template above^
const toastElement = htmlToElement(html);
//3. We place toast elemet into container
toastContainerElement.appendChild(toastElement);
//4. Wrap toast into bootstrap toast (for fancy animation, etc)
const toast = new bootstrap.Toast(toastElement, { delay: delay, animation: true });
toast.show();
//5. remove toast after delay + 3seconds to allow fancy bootstrap animation
setTimeout(() => toastElement.remove(), delay + 3000);
},
//helper functions for lazy people
error: function (message, title) {
myToast.show('danger', message, title);
},
success: function (message, title) {
myToast.show('success', message, title);
}
};
//helper function
function htmlToElement(html) {
var template = document.createElement('template');
html = html.trim();
template.innerHTML = html;
return template.content.firstChild;
}
So I created my function 2 years ago. But yesterday I decided to share it and make it as simple library script.
It is the same but wrapped in b5toast object and added optional delay. Here final js code:
const b5toastContainerElement = document.getElementById("toast-container");
const b5toast = {
delayInMilliseconds: 7000,
htmlToElement: function (html) {
const template = document.createElement("template");
html = html.trim();
template.innerHTML = html;
return template.content.firstChild;
},
show: function (color, message, title, delay) {
title = title ? title : "";
const html = `<div class="toast align-items-center mt-1 text-white bg-${color} border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
<b>${title}</b>
<div>${message}</div>
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>`;
const toastElement = b5toast.htmlToElement(html);
b5toastContainerElement.appendChild(toastElement);
const toast = new bootstrap.Toast(toastElement, {
delay: delay?delay:b5toast.delayInMilliseconds,
animation: true
});
toast.show();
setTimeout(() => toastElement.remove(), delay?delay:b5toast.delayInMilliseconds + 3000);
},
error: function (message, title, delay) {
b5toast.show("danger", message, title, delay);
},
success: function (message, title, delay) {
b5toast.show("success", message, title, delay);
},
};
Source code b5toast
Demo b5toast
The shortest usage is to include container and script and run b5toast.success('my message');
There are optional title and delay in docs to library.
b5toastSingle (method 2)
Funny story. I wanted to make other more simple version with reusing single bootstrap toast. But their example was broken.
//beware broken example. will have some glitches when running new toast if previous is at the end of his life
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')
if (toastTrigger) {
toastTrigger.addEventListener('click', () => {
const toast = new bootstrap.Toast(toastLiveExample)
toast.show()
})
}
Few days I didn’t get why they don’t fix it, and somehow I did fix it for them. On button click, they wrap element in their toast functionality and show. So I tried to move wrapping up. And eureka! This fixed toast’ glitches. Here fixed example.
//fixed version by js noob, me xD
const toastTrigger = document.getElementById('liveToastBtn');
const toastLiveExample = document.getElementById('liveToast');
const toastBootstrap = new bootstrap.Toast(toastLiveExample);
if (toastTrigger) {
toastTrigger.addEventListener('click', () => {
toastBootstrap.show();
});
}
Anyway, here my b5toastSingle function demo
Basically we place html at the bottom of page
<div class="toast-container position-fixed bottom-0 start-0 p-3">
<div id="b5toastSingle" class="toast align-items-center mt-1 text-white bg-success border-0" role="alert"
aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
<b id="b5toastSingleTitle"></b>
<div id="b5toastSingleMessage"></div>
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"
aria-label="Close"></button>
</div>
</div>
</div>
And add 18 lines of js
(function () {
const b5toastSingle = document.getElementById('b5toastSingle');
const b5toastSingleTitle = document.getElementById('b5toastSingleTitle');
const b5toastSingleMessage = document.getElementById('b5toastSingleMessage');
const colorsUsed = ['bg-success', 'bg-primary', 'bg-info', 'bg-danger', 'bg-warning'];
const b5toastSingleElementToast = new bootstrap.Toast(b5toastSingle, {
delay: 5000,
animation: true
});
window['b5toastSingle'] = function (color, message, title) {
title = title ? title : "";
b5toastSingleTitle.innerHTML = title;
b5toastSingleMessage.innerHTML = message;
b5toastSingle.classList.remove(...colorsUsed);
b5toastSingle.classList.add('bg-'+color);
b5toastSingleElementToast.show();
}
})();
Not sure if it is better than b5toast.js, but it works. Only one toast at a time, but who needs more? Material design guys say only one snackbar should be shown at any moment.
Choose what you like I go with b5toast.js as I wanna go fancy with multiple toasts xD besides I’m using it 2 years, so I got used to it.