Search code examples
javascriptbootstrap-modalhidebootstrap-5

How to hide Bootstrap 5 modal only on success?


Using bootstrap 5

I have a modal which I show when #truck_modal is clicked which works just fine like so:

(this code is at the top of my js file)

document.addEventListener('DOMContentLoaded', function() {
    document.querySelector('#add_truck').addEventListener('click', AddTruck);

    const truck_modal = document.querySelector('#staticBackdrop');
    const modal = new bootstrap.Modal(truck_modal, {
        backdrop: 'static'
    });

    document.querySelector('#truck_modal').addEventListener('click', () => {
        modal.show();
    });
})

Now, if I add the following to the above function it works.

document.querySelector('#add_truck').addEventListener('click', () => {
     modal.hide();
});

But here it runs when #add_truck is clicked regardless if the AddTruck function was successful or not, I only want it to hide if the AddTruck function is successful, so I tried the following.

function AddTruck() {

    ... some validations ...

    fetch('/inbound/add_truck', {
        
        ... some fetch code ...

    })
    .then(response => {
        jsonResponse = response.json();
        status_code = response.status;

        // console.log(jsonResponse);
        // console.log(status_code);

        if(status_code != 200) {
            alert('There was an error!');

        } else{
            origin.value = '';
            produce.value = '';
            license_num.value = '';
            loaded_weight.value = '';

            // document.querySelector('#add_truck').addEventListener('click', () => {
            //     modal.hide();
            // });
            modal.hide();
            // hideFunc();

            alert('Success!!!')
        }

        return status_code
    })
    .catch(error => {
        console.log(error)
    })

}

Even tried this:

function hideFunc() {
    const truck_modal = document.querySelector('#staticBackdrop');
    const modal = new bootstrap.Modal(truck_modal, {
        backdrop: 'static'
    });

    modal.hide();
}

What am I doing wrong here? Please help...

Or is this a feature?

EDIT

These are my js, bootstrap and jquery scripts

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
<script src="{% static 'utils.js' %}"></script>

And I added $('#truck_modal').modal('hide'); to the else block where I'm trying to hide it.


Solution

  • I had this problem too and sadly it was between chair and keyboard :( (And maybe a little bit in not clearly written docs. Just to justify myself :) )

    Your modal already exists. So calling:

    function hideFunc() {
        const truck_modal = document.querySelector('#staticBackdrop');
        const modal = new bootstrap.Modal(truck_modal, {
            backdrop: 'static'
        });
    
        modal.hide();
    }
    

    Will not work, because by this you are creating new modal. So, you create a new modal, set its backdrop to static and then you hide it. Without even showing it.

    Instead of creating a new one, you want to call / address the already existing one, by using bootstrap.Modal.getInstance. Like this:

    function hideFunc() {
        const truck_modal = document.querySelector('#staticBackdrop');
        const modal = bootstrap.Modal.getInstance(truck_modal);    
        modal.hide();
    }
    

    This way you can make yourself custom Modal (Dropdown, Popover, ...) handlers. It is only briefly described in the documentation, so it is easy to overlook it.