1

I have this JS function that is trigger by a click event. It's supposed to store some data and then open a window with an input form. The original code is something like:

function myClickFunction(){
    $('html').mask('Loading...');
    SaveData( function(){ //callback function
        window.open(...);
        $('html').unmask();
    });
}

The problem is that the window.open is blocked by the popup blocker. If I do:

function myClickFunction(){
    $('html').mask('Loading...');
    SaveData();
    $('html').unmask();
    window.open(...);
}

it works just fine but of course I only want to open the window when SaveData() completes.

SaveData() performs an ajax call and in an attempt to make solution #2 work I have tried setting async: false in the ajax call but that just blocks my $('html').mask('Loading...') call.

My setup is similar to https://stackoverflow.com/a/11670238/1480182 but an additional problem is that this has to run on Safari on iPad. And in this particular browser there's no way of making to windows/tabs communicate meaning that when I open the new window I halt any js execution on the opening tab :-(

How should I approach this?

Community
  • 1
  • 1
CJe
  • 1,928
  • 3
  • 24
  • 53
  • Do you need a real popup? You could perhaps overlay a full-size iframe? – towr Dec 27 '13 at 06:48
  • See comment to answer below pls – CJe Dec 27 '13 at 07:00
  • 1
    Can you open a new window that handles all of the functions of `myClickFunction`? i.e. show loading screen, save data, then set location. (You could perhaps use localStorage to transfer the data.) – towr Dec 27 '13 at 07:20
  • Hmmm... That _might_ be a way to but... the popup windows content varies as this is a dynamic solution used with multiple popup windows. Might be easier just to rewrite the code to use jqueryui. What's localStorage? Will that work with older browsers? – CJe Dec 27 '13 at 07:31
  • localStorage is a place where you can persistently store data for webapplication (it's accessible for all pages of the same origin). An important difference with cookies is that it doesn't get sent to the server each request (or ever). It's [pretty well supported](http://caniuse.com/namevalue-storage), but you could always fall back on cookies where it's not supported (or use a [polyfill](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills#web-storage-localstorage-and-sessionstorage) ). – towr Dec 27 '13 at 08:09
  • It works!!! Now I only have to write a special case for the evil browser v7. Thanks a million. If you write it up as an answer I'll mark it as the correct one. – CJe Dec 27 '13 at 08:26

3 Answers3

2

Popup blockers often block popup windows if they are not opened in direct response to a user action. Because the ajax call is asynchronous, it's completion function is sometime after a user action and is NOT in direct response to a user action as far as the browser can tell, so it may get blocked. There is no simple way around this except opening the popup window only in direct response to the user action.

The next obvious question/workaround is whether you really need a separate browser window/tab? Can you make your app work by using an overlay in your original window? An overlay would have zero restrictions and you could do anything you wanted with it.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I have tried using jqueryui dialog but the issue here is that the contents of the popup window is loaded from a url assuming to live in it's own window. This is an existing solution so not something I can easily rewrite. – CJe Dec 27 '13 at 06:57
  • @CJe - you can put an iframe in your dialog and load the content into the iframe. – jfriend00 Dec 27 '13 at 16:09
1

You could open a new window and let it handle the saving and redirect instead of doing it in myClickFunction. The data can be transferred between pages via localstorage.

So, for example, something like

function myClickFunction(){
    window.localStorage.tmpData = JSON.stringify(getData());
    window.localStorage.tmpRedirecturl = '...';
    window.open('saveandredirect.html);
}

And in saveandredirect.html

$(function(){
    $('html').mask('Loading...');
    var data = JSON.parse(window.localStorage.tmpData);
    var redirecturl = localStorage.tmpRedirecturl;

    delete window.localStorage.tmpData; // clear storage
    delete localStorage.tmpRedirecturl;

    SaveData(data, function(){
        window.location = redirectUrl;
        $('html').unmask();
    });
})
towr
  • 4,147
  • 3
  • 20
  • 30
0

By using popup windows, you trigger an action to the client computer. You cannot control the actions on the client computer. The user could always disable the popups... I would suggest to consider using the jquery overlay tool, which would put your target page on an overlay...

Hope I helped!

Pantelis Natsiavas
  • 5,293
  • 5
  • 21
  • 36