3

I was asked to take a look at what should be a simple problem with one of our web pages for a small dashboard web app. This app just shows some basic state info for underlying backend apps which I work heavily on. The issues is as follows:

On a page where a user can input parameters and request to view a report with the given user input, a button invokes a JS function which opens a new page in the browser to show the rendered report. The code looks like this:

$('#btnShowReport').click(function () {
    document.getElementById("Error").innerHTML = "";

    var exists = CheckSession();

    if (exists) {
        window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
    }
});

The page that is then opened has the following code which is called from Page_Load:

    rptViewer.ProcessingMode = ProcessingMode.Remote
    rptViewer.AsyncRendering = True
    rptViewer.ServerReport.Timeout = CInt(WebConfigurationManager.AppSettings("ReportTimeout")) * 60000
    rptViewer.ServerReport.ReportServerUrl = New Uri(My.Settings.ReportURL)
    rptViewer.ServerReport.ReportPath = "/" & My.Settings.ReportPath & "/" & Request("Report")

    'Set the report to use the credentials from web.config
    rptViewer.ServerReport.ReportServerCredentials = New SQLReportCredentials(My.Settings.ReportServerUser, My.Settings.ReportServerPassword, My.Settings.ReportServerDomain)
    Dim myCredentials As New Microsoft.Reporting.WebForms.DataSourceCredentials
    myCredentials.Name = My.Settings.ReportDataSource
    myCredentials.UserId = My.Settings.DatabaseUser
    myCredentials.Password = My.Settings.DatabasePassword
    rptViewer.ServerReport.SetDataSourceCredentials(New Microsoft.Reporting.WebForms.DataSourceCredentials(0) {myCredentials})

    rptViewer.ServerReport.SetParameters(parameters)

    rptViewer.ServerReport.Refresh()

I have omitted some code which builds up the parameters for the report, but I doubt any of that is relevant.

The problem is that, when the user clicks the show report button, and this new page opens up, depending on the types of parameters they use the report could take quite some time to render, and in the mean time, the original page becomes completely unresponsive. The moment the report page actually renders, the main page begins functioning again. Where should I start (google keywords, ReportViewer properties, etc) if I want to fix this behavior such that the other page can load asynchronously without affecting the main page?

Edit -

I tried doing the follow, which was in a linked answer in a comment here:

            $.ajax({
                context: document.body,
                async: true,   //NOTE THIS
                success: function () { 
                    window.open(Address);
                }
            });

this replaced the window.open call. This seems to work, but when I check out the documentation, trying to understand what this is doing I found this:

The .context property was deprecated in jQuery 1.10 and is only maintained to the extent needed for supporting .live() in the jQuery Migrate plugin. It may be removed without notice in a future version.

I removed the context property entirely and it didnt seem to affect the code at all... Is it ok to use this ajax call in this way to open up the other window, or is there a better approach?

Mark W
  • 2,791
  • 1
  • 21
  • 44
  • 1
    There is an explanation of why window.open is blocking, and a method to get around it here: [window.open() works different on AJAX success] (http://stackoverflow.com/questions/10223388/window-open-works-different-on-ajax-success) – Justin Ryan Nov 25 '14 at 08:26
  • @JustinRyan Can you elaborate on the answer(s) given in the link? I'm not sure how I can apply that to the code above. – Mark W Nov 25 '14 at 15:07
  • 1
    [This one may be more clear](http://stackoverflow.com/questions/9793774/window-openurl-different-behavior-same-code-different-timing), and the asker seems to have the same situation you are in. Though I don't remember reading the exact reason why, browsers will block when a window.open call is made from code, but not when it results from a user interaction. So, in your case, the calling window waits for the report to finish before responding. The proposed solutions all seem to involve opening a blank window first, then a timeout, and finally loading your desired URL. (cont...) – Justin Ryan Nov 25 '14 at 20:04
  • 1
    (...cont) This is what [David's answer](http://stackoverflow.com/a/27129734/242584) proposes. The second link I provided used a prompt of some sort to finally load the report, thus causing the calling window to unblock upon user interaction with the prompt. – Justin Ryan Nov 25 '14 at 20:07

3 Answers3

2

Using a timeout should open the window without blocking your main page

$('#btnShowReport').click(function () {
  document.getElementById("Error").innerHTML = "";

  var exists = CheckSession();

  if (exists) {
    setTimeout(function() {
      window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
    }, 0);
  }
});
David Sdot
  • 2,343
  • 1
  • 20
  • 26
0

This is a long shot, but have you tried opening the window with a blank URL first, and subsequently changing the location?

$("#btnShowReport").click(function(){
    If (CheckSession()) {
        var pop = window.open ('', 'showReport');
        pop = window.open ('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>', 'showReport');
    }
})
Justin Ryan
  • 1,409
  • 1
  • 12
  • 25
-1

use

`$('#btnShowReport').click(function () {
 document.getElementById("Error").innerHTML = "";

 var exists = CheckSession();

 if (exists) {
     window.location.href='<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1")       %>';

 }
 });`

it will work.

raths
  • 31
  • 5
  • This will change the parent window location. The OP wants a new window. – Justin Ryan Nov 26 '14 at 09:54
  • <%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %> what is returned? – raths Nov 26 '14 at 12:34
  • It appears, that returns the URL to retrieve the report. – Justin Ryan Nov 26 '14 at 20:20
  • I tried your js code.It will produce output as it will. no error or hang. Please check you disabled click event of `#btnShowReport` after ajax started.because I thinking that you will tigger that event repeatedly which cause hang for `async: true` attr. – raths Nov 30 '14 at 14:43
  • Are you referring to the answer that I posted? There were no Ajax calls in my code, only a simple click event handler triggering two calls to `window.open`. – Justin Ryan Dec 01 '14 at 04:12