Close spModal from an onLoad catalog client script for a record producer

Lima Beauvais
Giga Guru

Good afternoon,

I used the script below within an onLoad catalog client script for a record producer to open a modal window. I want to close the popup window when the user selects the browser back button. I tried modalInstance.dismiss(); but it is not working. I would appreciate your input for a solution. Thanks!

 

var returnURL = "some URL";
var modalInstance = spModal.open({
backdrop: true,
keyboard: false,
noDismiss: true,
message: txtContent,
title: 'Popup Title',
size: 'lg',
buttons: [{
label: 'I Agree',
primary: true
},
{
label: 'I Disagree',
cancel: true
}
]

}).then(function() {
// user agrees
}, function() {
top.window.location.replace(returnURL);
}, function() {
spModal.open({
widget: 'widget-id'
});

});

1 ACCEPTED SOLUTION

I found a workaround for now. It is ugly. I just reload the window when the user selects the back button to get rid of the spModal. I was able to fix the addListesner issue by preceding window with top. I will keep digging until I can close the spModal but for now the users have to live with the workaround. Here's the working code:

top.window.addEventListener('popstate', function(event) {
    if (modalInstance) {
        top.window.location.reload();
    }
});


View solution in original post

7 REPLIES 7

Medi C
Giga Sage

Hello @Lima Beauvais,

Handling the browser's back button to close a modal is tricky because the back button navigates to the previous page instead of triggering standard JavaScript events. However, you can try using the popstate event to detect when the user presses the back button and then close the modal accordingly and see if that would help.

 

I have tested the following on my browser console and it seems to work.

var returnURL = "some URL";
var modalInstance = spModal.open({
    backdrop: true,
    keyboard: false,
    noDismiss: true,
    message: txtContent,
    title: 'Popup Title',
    size: 'lg',
    buttons: [{
        label: 'I Agree',
        primary: true
    },
    {
        label: 'I Disagree',
        cancel: true
    }]
}).then(function() {
    // user agrees
}, function() {
    top.window.location.replace(returnURL);
}, function() {
    spModal.open({
        widget: 'widget-id'
    });
});

// Add a history entry so that we can detect when the back button is pressed
history.pushState(null, null, location.href);

// Listen for the back button press event
window.addEventListener('popstate', function(event) {
    if (modalInstance) {
        modalInstance.dismiss(); // Close the modal
    }
});

 

I hope this helps!

 


If you found this helpful, please hit the thumbs-up button and mark as correct. That helps others find their solutions.

Thanks Medi C for your reply. You are right handling the back button to close a modal is tricky. My first attempt is to find the right command to close the modal. My main issue is to close the spModal before even listening to the back button of the browser. I try closing the model right after open it using this line "modalInstance.dismiss();", but it is giving me this error: TypeError: modalInstance.dismiss is not a function

Hello @Lima Beauvais,

 

Is my understanding correct that you want to close the modal as soon as it loads? (Do you really need that modal in this case)

What could be throwing the error is that spModal.open() returns a promise, you need to ensure that you dismiss the modal after it fully initializes.

 

Please try the following ways:

var modalInstance = spModal.open({
    backdrop: true,
    keyboard: false,
    noDismiss: true,
    message: txtContent,
    title: 'Popup Title',
    size: 'lg',
    buttons: [{
        label: 'I Agree',
        primary: true
    },
    {
        label: 'I Disagree',
        cancel: true
    }]
}).then(function() {
    // User agrees
}, function() {
    // User disagrees
}, function() {
    // Ensure modal is closed as soon as it loads
    modalInstance.dismiss();
});

 

If .dismiss() does not work as expected inside .then(), you can use setTimeout() to delay closing the modal slightly, ensuring it has fully loaded.

 

spModal.open({
    backdrop: true,
    keyboard: false,
    noDismiss: true,
    message: txtContent,
    title: 'Popup Title',
    size: 'lg',
    buttons: [{
        label: 'I Agree',
        primary: true
    },
    {
        label: 'I Disagree',
        cancel: true
    }]
}).then(function(modalInstance) {
    setTimeout(function() {
        modalInstance.dismiss();
    }, 100); // Small delay to ensure the modal is initialized
});

If you found this helpful, please hit the thumbs-up button and mark as correct. That helps others find their solutions.

My long term goal is close the modal when the user selects the browser's back button. But first I want to make sure the command to close the spModal works. That is why temporarily I am trying o close it after it displays. When the command works, I will work on closing it when the user selects the back button. The first code you provided threw an error with the addListener. This second example with the timeout did not close the modal but it did not throw an error. I will keep digging.
Note: Sorry, I just checked and it is still throwing that same error:
Uncaught TypeError: modalInstance.dismiss is not a function