Home > OS >  show bootstrap toast by calling javascript class method
show bootstrap toast by calling javascript class method

Time:04-21

I would like to show a bootstrap toast by calling something like this:

let my_toast = new myToast('title', 'hello world');
my_toast.show();

So far I am loading the html from an external file myToast.html:

  <div  style="z-index: 11">
<div id="liveToast"  role="alert" aria-live="assertive" aria-atomic="true">
    <div >
    <img src=""  alt="">
    <strong >
      <div id="toast-title">
        Bootstrap
      </div>
    </strong>
    <small><div id=""></div></small>
    <button type="button"  data-bs-dismiss="toast" aria-label="Close"></button>
    </div>
    <div id="toast-body" >
        Hello, world! This is a toast message.
    </div>
</div>
</div>

and adding this to a <div id="mydiv"></div> on the main page, changing the title and body and call the Tost.show() method:

<script>
    class myToast{
        toast_html; 

        constructor(title, message) {
            this.title = title;
            this.message = message;
            
            let template_html;
            $.ajax({
                async: false, // resume if finished
                type: 'GET',
                url: "myToast.html",
                success: function(data) {
                    template_html = data;
                }
            });

            console.log("var html: "   html); 

            let toast_div = document.createElement("div");
            toast_div.id = "toast_wrapper";              
            toast_div.innerHTML = template_html;            
            toast_div.querySelector("#toast-title").innerHTML = (this.title);
            toast_div.querySelector("#toast-body").innerHTML = (this.message);

            this.toast_html = toast_div;
        }
    }

    let to = new myToast('title', 'hello world');
    $("#mydiv").append(to.toast_html);

    var toastLiveExample = document.getElementById('liveToast');
    var toast = new bootstrap.Toast(toastLiveExample);

    toast.show();
</script>

Are there better/shorter solutions?

CodePudding user response:

You could transfer your HTML template code to your JavaScript, so you don't have an extra ajax call to a external HTML template. This way you can also add changes to the layout of the toast (perhaps you want a danger, success, info or warning toast type). The trick is to create the elements during the initialization of Toast class.

I will provide the implementation which you can test below.

Ref: Bootstrap 5 Toast - getOrCreateInstance

/* Implementation */
function Toast(title, description) {
    var toastElement = buildToast(title, description);
    var toastWrapper = getOrCreateToastWrapper();
    toastWrapper.append(toastElement);
    this.bootstrapToast = bootstrap.Toast.getOrCreateInstance(toastElement);
    
    this.show = function() {
        this.bootstrapToast.show();
    }
    
    this.hide = function() {
        this.bootstrapToast.hide();
    }
    
    this.dispose = function() {
        this.bootstrapToast.dispose();
    }
}

/* Example CTA */
var title = 'Bootstrap';
var description = 'Hello, world! This is a toast message.';
var toast = new Toast(title, description);
toast.show();

/* Utility methods */
function getOrCreateToastWrapper() {
    var toastWrapper = document.querySelector('body > [data-toast-wrapper]');
    
    if (!toastWrapper) {
        toastWrapper = document.createElement('div');
        toastWrapper.style.zIndex = 11;
        toastWrapper.style.position = 'fixed';
        toastWrapper.style.bottom = 0;
        toastWrapper.style.right = 0;
        toastWrapper.style.padding = '1rem';
        toastWrapper.setAttribute('data-toast-wrapper', '');
        document.body.append(toastWrapper);
    }
    
    return toastWrapper;
}

function buildToastHeader(title) {
    var toastHeader = document.createElement('div');
    toastHeader.setAttribute('class', 'toast-header');
    
    var img = document.createElement('img');
    img.setAttribute('class', 'rounded me-2');
    img.setAttribute('src', '');
    img.setAttribute('alt', '');
    
    var strong = document.createElement('strong');
    strong.setAttribute('class', 'me-auto');
    strong.textContent = title;
    
    var closeButton = document.createElement('button');
    closeButton.setAttribute('type', 'button');
    closeButton.setAttribute('class', 'btn-close');
    closeButton.setAttribute('data-bs-dismiss', 'toast');
    closeButton.setAttribute('data-label', 'Close');
    
    toastHeader.append(img);
    toastHeader.append(strong);
    toastHeader.append(closeButton);

    return toastHeader;
}

function buildToastBody(description) {
    var toastBody = document.createElement('div');
    toastBody.setAttribute('class', 'toast-body');
    toastBody.textContent = description;
    
    return toastBody;
}

function buildToast(title, description) {
    var toast = document.createElement('div');
    toast.setAttribute('class', 'toast');
    toast.setAttribute('role', 'alert');
    toast.setAttribute('aria-live', 'assertive');
    toast.setAttribute('aria-atomic', 'true');
    
    var toastHeader = buildToastHeader(title);
    var toastBody = buildToastBody(description);
    
    toast.append(toastHeader);
    toast.append(toastBody);
    
    return toast;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

  • Related