tags:

views:

418

answers:

2

I have a requirement, wherein i need to show a wait message while an excel report is being executed and when execution is complete, excel is written to response for user to save. Once save is done i need to hide the wait message.

I was able to show wait message but i am not able to hide the same when the execution is complete. I have used Ifames to achieve the same. i do all the processing required for excel in the iframe and write to the response in the same Iframe. i attempted to hide the wait message using Javascript but any JavaScript function written in onload,onunload, onbeforeunload etc of Iframe is not being executed.

Is there any way i can call a JavaScript function , Or is there any other approach to the problem.

+2  A: 

I did something like this a few years ago. I opened a new thread to do the background processing, then redirected to a "waiting" page. The wait page checks the status of the task and if completed, redirects back. That's a real easy solution. Check it out here

Scott
+1 for a good read
Mike Robinson
+2  A: 

Here's how I'd do this:

  • Create an HttpHandler that generates the document, saves it (in cache/on disk/database, your call) and returns an identifier for the generated document
  • Call the HttpHandler using an AJAX call (use jQuery to make this really easy)
  • Use javascript/jQuery to display a waiting message/graphic/animation/whatever
  • In the AJAX request callback, redirect to a page that takes the generated identifier and sends the corresponding document as an attachment using the Content-Disposition header.

As a side note, this would be a little more straightforward in ASP.NET MVC

GenerateDocument HttpHandler stub:

public class GenerateMyDocumentHandler : IHttpHandler
{
    #region [ IHttpHandler Members ]

    public Boolean IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        var docIdentifier = this.GenerateDocument();

        context.Response.ContentType = "text/plain";
        context.Response.Write(docIdentifier.ToString("N"));
    }

    #endregion

    private Guid GenerateDocument()
    {
        var identifier = Guid.NewGuid();

        // Logic that generates your document and saves it using the identifier

        return identifier;
    }
}

Client Script stub:

function generateDocument() {
    var result = $.get('/GenerateDocument.ashx', { any: 'parameters', you: 'need', go: 'here' }, generateDocumentCallback, 'text');
    // display your waiting graphic here
}

function generateDocumentCallback(result) {
    window.location.href = '/RetrieveDocument.ashx/' + result;
}

RetrieveDocument HttpHandler stub:

public class RetrieveDocument : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        var identifier = new Guid(context.Request.Url.Segments[1]);
        var fileContent = this.GetFileAsBytes(identifier);

        context.Response.ContentType = "application/vnd.ms-excel";
        context.Response.AddHeader("Content-Disposition", "attachment; filename=yourfilename.xls");
        context.Response.OutputStream.Write(fileContent, 0, fileContent.Length);
    }

    private Byte[] GetFileAsBytes(Guid identifier)
    {
        Byte[] fileBytes;
        // retrieve the specified file from disk/memory/database/etc

        return fileBytes;
    }

    public Boolean IsReusable
    {
        get
        {
            return true;
        }
    }
}
Daniel Schaffer
exactly what i wanted and worked like magic
rsapru