Sweetalert: Tab key not working after opening two Sweet Alert Modals in a row

Created on 15 Oct 2014  ·  20Comments  ·  Source: t4t5/sweetalert

Hello,

It seems that when the SweetAlert dialog opens another one after it's done, the tab key stops working, all other keystrokes are okay.

You can recreate this using the example on http://tristanedwards.me/sweetalert.

This one specifically:

swal({      title: "Are you sure?",   
            text: "Your will not be able to recover this imaginary file!",   
            type:  "warning",   
            showCancelButton: true,   
            confirmButtonColor: "#DD6B55",   
            confirmButtonText: "Yes, delete it!",   
            cancelButtonText: "No, cancel plx!",   
            closeOnConfirm: false,   
            closeOnCancel: false }, 
            function(isConfirm){  
                 if (isConfirm) {     
                 swal("Deleted!", "Your imaginary file has been deleted.", "success");  
                 } else {     
                 swal("Cancelled", "Your imaginary file is safe :)", "error");   
                 } });

I believe it's copying over the keystroke handling from the previous modal, specifically in the closeModal() function, this part:

 // Reset the page to its previous state
    window.onkeydown = previousWindowKeyDown;
    document.onclick = previousDocumentClick;
    if (previousActiveElement) {
      previousActiveElement.focus();
    }

Perhaps it's simply focusing on the previous modal and registering back it's keydown and onclick?

help wanted

Most helpful comment

To implement the fix by @jayquest without changing the library, I used the following code:

var previousWindowKeyDown = window.onkeydown;
swal({
title: 'Are you sure?',
closeOnConfirm: false,
closeOnCancel: false
}, function (isConfirm) {
window.onkeydown = previousWindowKeyDown;
if (isConfirm) {
swal('Deleted!', 'Your imaginary file has been deleted.', 'success');
} else {
swal('Cancelled', 'Your imaginary file is safe :)', 'error');
}
});

All 20 comments

From that example I can't really see that what you are saying is true,
Becaues the 'tab' key is just moving between the buttons,
when I get the second modal I have only one button, so no matter how much you will press the tab button it'll always stay on it's single one button it has.

Sorry I didn't make that clear!

Yes it's tabbing IN the model, but after you close the second modal, you lose the ability navigate the web page with the tab key (No modals on screen just the web page).

I've attempted a fix at jack126guy/sweetalert@issue127. It seems to work insofar as the focus returns to the button on the page.

However, it reveals another issue: You still can't tab to another button, and when you hit Enter to show the alert again, things get weird.

Yes I attempted a similar fix to yours but with a window global variable to make sure it's an element from the website other than SweetAlert, it does focus the element on the document but the Tab key is still not working.

What seems to have fixed it for now is removing the stopEventPropagation(e) in the if(keycode == 9) clause in the handleKeyDown method. But I'm guessing there are other side-effects to this...

I would show you a commit but I did some other changes to the library as well that others might not want.

So in case anyone wants a temporary fix for this bug, here's a repo I forked from this project: https://github.com/heero-yuy/sweetalert.git

It works 100% for all my projects so far but I haven't tested it extensively to make sure my changes didn't break any other functionality.

i fixed it inserting the two line of code above on the begin of the function sweetAlert or swal at the line 215, i don´t know if its the best solution, but its working for me.

/*
 * Global sweetAlert function
 */
var sweetAlert, swal;

sweetAlert = swal = function() {

    if(previousWindowKeyDown !== undefined && window.onkeydown !== previousWindowKeyDown)`
        window.onkeydown = previousWindowKeyDown;

:+1: . This should get some priority.

The fix by @jayquest seems to work.

To implement the fix by @jayquest without changing the library, I used the following code:

var previousWindowKeyDown = window.onkeydown;
swal({
title: 'Are you sure?',
closeOnConfirm: false,
closeOnCancel: false
}, function (isConfirm) {
window.onkeydown = previousWindowKeyDown;
if (isConfirm) {
swal('Deleted!', 'Your imaginary file has been deleted.', 'success');
} else {
swal('Cancelled', 'Your imaginary file is safe :)', 'error');
}
});

To expand on @amoralidad 's fix you can use this to include only once after you include the sweet alert library in your project and it will decorate the swal service so your code and the library stays unobstructed (without coding the fix above in every call) until a permanent fix is made.

(function (){

    var _swal = window.swal;

    window.swal = function(){

        var previousWindowKeyDown = window.onkeydown;

        _swal.apply(this, Array.prototype.slice.call(arguments, 0));

        window.onkeydown = previousWindowKeyDown;

    };

})();

I can confirm this bug as well and the above workaround works well too! :+1:

Yup, the workaround of @JustinWinthers works fine!

however, it seems to f-up using escape and enter keys in the dialog

The workaround of @amoralidad worked for me. Thanks!

thanks @jayquest... @t4t5 please fix this in master branch!

I just submitted a pull request with my solution. https://github.com/t4t5/sweetalert/pull/547

@JustinWinthers , using your code breaks the type: 'input'. When trying to click on "Cancel" button to close the dialog, it says swal.showInputError is not a function.

For an example, go to http://clubcare.no/dashboard and tap on Glemt passord ( forgot password )

Removing your function makes it work again. Any ideas on how to get rid of this behavior ? Thank you!

@jayquest Thank you for fixing this issue.

Hi @JustinWinthers

I tried your suggestion to fix this tabbing issue after SweetAlert opens. It fixed the issue, however I started getting this error when I try to close the Sweetalert using swal.close(); when the cancel button is clicked:

swal.close is not a function

This is similar to what @EduardJS said above. Is there a way to get them working? I feel we got so close but due to this error, I had to remove your suggested code. Any help will be great.

Cheers,
Neel.

The simplest possible solution based on the workaround of @JustinWinthers that I could found (without modifying the library), is to hook only into the swal.close function and set the window.onkeydown to the previous window.onkeydown event handler:

(function (){
    var close = window.swal.close;
    var previousWindowKeyDown = window.onkeydown;
    window.swal.close = function() {
        close();
        window.onkeydown = previousWindowKeyDown;
    };
})();

or in my case even simpler:

(function (){
    var close = window.swal.close;
    window.swal.close = function() {
        close();
        window.onkeydown = null;
    };
})();

With this workaround it is now also possible to use the Enter and Escape keys in the dialog.

The error messages mentioned by @Mr-Anonymous and @EduardJS also no longer occur.

@kosst Perfect. Thank you so much for sharing that. I tried your code and it works perfect. Thank you so much!!

Cheers,
Neel.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yrshaikh picture yrshaikh  ·  4Comments

voodoo6 picture voodoo6  ·  4Comments

rafatux picture rafatux  ·  5Comments

adiwithadidas picture adiwithadidas  ·  4Comments

Untit1ed picture Untit1ed  ·  5Comments