5

In my Asp.net webforms site I have a form where users select various options and those options are sent back in a postback that generates a PDF report and sends that file back to the user for download via the following code:

    protected void btnTopGenReport_Click(object sender, EventArgs e)
    {
        var stream = new PodMainReportGenerator().GenerateReport(GetReportParameters());

        var bytes = stream.ToArray();
        stream.Close();

        // Set the content headers
        Response.Clear();
        Response.Buffer = true;
        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", "attachment;filename=testReport.pdf");
        Response.AddHeader("Content-Length", bytes.Length.ToString());

        Response.BinaryWrite(bytes);

        Response.End();
    }

The problem is this report can take a good 10 or so seconds to generate due to the amount of data and processing required, but I don't want people getting impatient and clicking the button over and over again.

In a normal page I would add javascript to disable the buttons on click. This works because when postback is complete the server comes back with the form buttons re-enabled. However, since the form's response is not an HTML page but a downloaded file, which I don't know how to detect.

Essentially, how do I disable the form's buttons but re-enable them once we get the response from the server (and the http file transfer is initiated)?

KallDrexx
  • 27,229
  • 33
  • 143
  • 254
  • Prevously asked http://stackoverflow.com/questions/6137172/how-do-i-prevent-users-clicking-a-button-twice – David Oct 19 '12 at 15:24
  • That question only answers half of my issue and doesn't answer how to re-enable the button. Also myButton.Enabled woudln't work because Asp.Net's response isn't re-rendering the HTML since it's just returning file contents – KallDrexx Oct 19 '12 at 15:27

3 Answers3

4

You just need an indicator outside of the response content to notify you that the download is complete. Try using a cookie monitor, where you set the cookie as part of the download response, and in your main page, monitor for the existence of that cookie.

http://gruffcode.com/2010/10/28/detecting-the-file-download-dialog-in-the-browser/

Jesse Taber
  • 2,376
  • 3
  • 23
  • 33
Jerod Venema
  • 44,124
  • 5
  • 66
  • 109
2

Trying to think outside the box here. Instead of disabling/enabling the submit button, maybe you can set a session level variable indicating that the report is running. If the user clicks the submit button again while a previous request is being processed, do not start a new process.

For a better UI experience, you might want to have a AJAX call fired off before the form is submitted to check if a previous process is running. If it is, you can cancel the form submission and display a message along the lines of "Your previous request is still being processed."

Thoughts?

Shai Cohen
  • 6,074
  • 4
  • 31
  • 54
  • The only potential issue I see with that is if the browser will disregard the response with the file download if the user has already reloaded the page due to pressing the button (thus triggering a non-download postback) – KallDrexx Oct 19 '12 at 17:22
  • I'm not sure what you mean, sorry. But that being said, I think the solution posted by @jvenema is the better solution. It looks like it does exactly what you were looking for. – Shai Cohen Oct 19 '12 at 17:33
  • yeah I worded that comment badly. I guess what I was thinking is I don't know how browsers handle the situation where you click on a potential download link, then before the response comes in navigate to another page. – KallDrexx Oct 19 '12 at 17:36
  • I believe this would be an issue for any solution you implement, no? Or am I missing something again? :) – Shai Cohen Oct 19 '12 at 18:17
0

//For disabling the button write the below code on page load.

    System.Text.StringBuilder sbValid = new System.Text.StringBuilder();
    sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { ");
    sbValid.Append("if (Page_ClientValidate() == false) { return false; }} ");
    sbValid.Append("this.value = 'Saving..';");
    sbValid.Append("this.className  = 'Save_Button_Active';");
    sbValid.Append("this.disabled = true;");
    sbValid.Append(this.Page.GetPostBackEventReference(this.btnName));
    sbValid.Append(";");
    this.btnName.Attributes.Add("onclick", sbValid.ToString());
    this.btnName.Attributes.Add("onclick", "this.className  = 'Cancel_Button_Active';");

YOu can also refer to following links for more information:

http://bytes.com/topic/c-sharp/answers/887893-disabled-button-calling-even-handler-button-click

Button disable function after clicking on it

Disable the asp button after first click because it save multiple records in slow connection

Community
  • 1
  • 1
Ruchi
  • 1,238
  • 11
  • 32
  • you can remove the this.classname attributes as I am giving the classname for styles. Thanks. – Ruchi Oct 19 '12 at 15:27
  • That doesn't address the 2nd half of my issue though, which is re-enabling the button after a response has been received. – KallDrexx Oct 19 '12 at 15:28