master_j02
master_j02

Reputation: 405

Cancel SetTimeout function if a button is clicked?

I have a setTimeout function which basically sets a timer for displaying an AJAX message, and whether the message is an alert-success it redirects to a certain page, if the message is not a success message it stays on the current form page.

Now in the AJAX message displayed I have a close button, which if clicked does the same redirects depending on if the message was an alert-success or not. I don't want the user to have to wait for the timeout if they choose to click the X button in the message.

let timer;
let ajax_msgs_div = document.getElementById('ajax_messages');
function displayMessages(alert_class, message) {
    let ajax_msg = `<div class="alert alert-dismissible ${alert_class}" role="alert">
                        <button type="button" class="close" data-dismiss="alert"></button>
                          <span>${message}</span>
                  </div>`


    timer = window.setTimeout(function() {
        let close_btn = document.getElementsByClassName('close')[0];
        if (alert_class == 'alert-success'){
            close_btn.click(location.href="{{ django redirect url on success}")
        } else {
            close_btn.click();}
        }, 3500);

    ajax_msgs_div.innerHTML += ajax_msg;
}

Now the set timeout works perfectly, but I want the user to be able to click the close button themselves, rather than having to wait for the timer, if they choose to.

Edit

I now have this working thanks to Doan's response! Any tips for reducing the redundancy? I tried setting the close button just once as a global var

let close_button = document.getElementsByClassName('close')[0];

But was only executing with the timeout function. So I had to grab the button again to use for the AddEventListener functionality.

let timer;
let ajax_msgs_div = document.getElementById('ajax_messages');
function displayMessages(alert_class, message) {
    let ajax_msg = `<div class="alert alert-dismissible ${alert_class}" role="alert">
                        <button type="button" class="close" data-dismiss="alert"></button>
                          <span>${message}</span>
                  </div>`


    timer = window.setTimeout(function() {
        let close_btn = document.getElementsByClassName('close')[0];
        if (alert_class == 'alert-success'){
            close_btn.click(location.href="{{ django redirect url on success}")
        } else {
            close_btn.click();}
        }, 3500);

    ajax_msgs_div.innerHTML += ajax_msg;

    let close_button =  document.getElementsByClassName('close')[0];
    close_button.addEventListener("click", () => {
        clearTimeout(timer);
        if (alert_class == 'alert-success'){
        location.href = {{ django redirect url on success }};
        } else {
            close_button.click();
        }
    });
}

Upvotes: 1

Views: 2524

Answers (1)

Doan Van Thang
Doan Van Thang

Reputation: 997

You can set the click event to clear the setTimeout with clearTimeout(timer); and call location.href directly

    function redirect_func(){
        if (alert_class == 'alert-success'){
            location.href = {{ django redirect url on success }};
        } else {
            close_button.click();
        }
    }

    timer = window.setTimeout(redirect_func, 3500);

    ajax_msgs_div.innerHTML += ajax_msg;

    let close_button =  document.getElementsByClassName('close')[0];
    close_button.addEventListener("click", () => {
        clearTimeout(timer);
        redirect_func();
    });

Upvotes: 2

Related Questions