Closing the browser window from Wicket

On the project I was working on I stumbled upon a problem that when a user makes a certain action, the browser window needs to close. The internet is full of solutions for closing the browser window via JavaScript. This StackOverflow topic offers a great script example how to achieve the closing of the browser using simple JavaScript:

function closeWindows() {
    var browserName = navigator.appName;
    var browserVer = parseInt(navigator.appVersion);
    //alert(browserName + " : "+browserVer);

    //document.getElementById("flashContent").innerHTML = "<br>&nbsp;<font face='Arial' color='blue' size='2'><b> You have been logged out of the Game. Please Close Your Browser Window.</b></font>";

    if(browserName == "Microsoft Internet Explorer"){
        var ie7 = (document.all && !window.opera && window.XMLHttpRequest) ? true : false;  
        if (ie7)
        {  
          //This method is required to close a window without any prompt for IE7 & greater versions.
          window.open('','_parent','');
          window.close();
        }
       else
        {
          //This method is required to close a window without any prompt for IE6
          this.focus();
          self.opener = this;
          self.close();
        }
   }else{  
       //For NON-IE Browsers except Firefox which doesnt support Auto Close
       try{
           this.focus();
           self.opener = this;
           self.close();
       }
       catch(e){

       }

       try{
           window.open('','_self','');
           window.close();
       }
       catch(e){

       }
   }
}

Sadly, Firefox happens to be the exception here, as you cannot close it from the JavaScript. For other browsers, this script should work. Alright, but how do we hook this JavaScript to Wicket? First, we (obviously) have to include the .js file that contains the above script into our page. In Wicket 1.5, we then actually have multiple options for calling this JavaScript from code. Let’s say we have the following class:

public class CloseWindowPage extends WebPage implements IHeaderContributor {

    private AjaxLink&lt;Void&gt; link1;
    private AjaxLink&lt;Void&gt; link2;

    private boolean closeWindow = false;

    @Override
    public void renderHead(IHeaderResponse response) {
        if (this.closeWindow)
            // This JS is executed after the page is completely loaded
            response.renderOnLoadJavaScript("closeWindows();");
    }

    public CloseWindowPage(PageParameters parameters) {
        super(parameters);

        if (!parameters.get("close").isEmpty())
            this.closeWindow = true;

        link1 = new AjaxLink&lt;Void&gt;("link1") {
            @Override
            public void onClick(AjaxRequestTarget target) {}
        };
        link1.add(new AttributeAppender("onclick", "closeWindows();");
        add(link1);

        link2 = new AjaxLink&lt;Void&gt;("link2") {
            @Override
            public void onClick(AjaxRequestTarget target) {
                // Do some stuff...

                // Redirect to this page, set the parameters
                PageParameters params = new PageParameters();
                params.add("close", "true");
                setResponsePage(CloseWindowPage.class, params);
            }
        };
        add(link2);
    }
}

I added two links to our sample page. The first option to call this JS function is not really much of a Wicket solution – basically, you create a HTML link (or a button), and set its onclick attribute to call our JavaScript function, like this:

&lt;a href="#" onclick="closeWindows();" wicket:id="link1"&gt;Click me&lt;/a&gt;

To set the attribute of the element from Wicket, we use the AttributeAppender class, but in essence, it does the same as you would write the event handler in HTML. link1 is an example of such behavior. My case, however, was different; when a user clicks a button/link in our application, the Wicket must do some background work, before the browser should close. In this case, the AttributeAppender will not work. We solve this problem by using the renderHead overriden method, and depending on the page parameter, we inject the JavaScript code calling our funcion into the body onload attribute. All we are left to do is to implement a link, override its onClick method, do the work we need and finally redirect to the same page, using the page parameter. This behavior is demonstrated by the link2 component. I hope I offered some insight and threw an idea or two out there. Now to wait for Firefox to enable the window closing action…

Leave a Reply