Thursday 2 September 2021

Detecting when a save as dialog is shown to the user

I'm having an issue with an ASP.Net webforms application that uses ajax calls (via jQuery) to load secondary files into an iframe. Those secondary files zip up a bunch of files and then stream them to the user. I have a modal that shows a loading animation while this is happening, but when I set it to be removed when the ajax is complete, it still sometimes takes several seconds or even much longer for the modal to dissapear.

Here's the button:

<asp:Button ID="btnDownloadAll" runat="server" 
    Text="Download All Files" 
    Enabled="false" visibe="false"
    OnClientClick="javascript:document.getElementById('modal').style.width='100%'; downloadAll();"  
    OnClick="btnGenericDownload_Click" 
    ClientIDMode="Static" 
    CssClass="buttons" />

btnGenericDownload_Click in the codebehind doesn't actually do anything. Here's the JS function being called:

function downloadAll() {
            $.ajax({
                url: 'GenerateDownloadFile.aspx?filetype=all',
                type: 'GET',
                done: function () {
                    var iframe = document.createElement("iframe");
                    iframe.src = "GenerateDownloadFile.aspx?filetype=all";
                    iframe.style.display = "none";
                    document.body.appendChild(iframe);
                },
                complete: function () {
                    clearScreen();
                }
            });
        }

function clearScreen() {
            document.getElementById("modal").style.width = "1px";
        }

I'm wondering if there's any way to get this to sync better - to detect when the save as is being shown or when the file exists in the folder, which I am able to do in the codebehind, but not sure how to integrate that into the dynamic aspect of the ajax request. Currently the function that checks for the file is activated when certain form elements are clicked or changed...

Edit: just tried changing the downloadAll() function to this:

function downloadAll() {
        document.getElementById('modal').style.width = '100%';
        $.ajax({
            url: 'GenerateCNDownloadFile.aspx?filetype=all',
            type: 'GET',
            success: function () {
                var iframe = document.createElement("iframe");
                iframe.src = "GenerateCNDownloadFile.aspx?filetype=all";
                iframe.style.display = "none";
                document.body.appendChild(iframe);

            },
            done: function () {
                clearScreen();
            }
        });
    }

The file that is being called GenerateCNDownloadFile.aspx, has the following function in its codebehind which is what actually streams the file to the browser and initiates the Save As dialog:

public void StreamFileToBrowser(string sfilename, byte[] fileBytes)
    {
        try
        {
            Response.Clear();
            Response.ClearHeaders();

            Response.AppendHeader("Content-disposition", String.Format("attachment; filename=\"{0}\"", System.IO.Path.GetFileName(sfilename)));
            Response.AppendHeader("Content-Type", "binary/octet-stream");
            Response.AppendHeader("Content-length", fileBytes.Length.ToString());

            Response.BinaryWrite(fileBytes);

            if (Response.IsClientConnected)
                Response.Flush();
        }
        catch (Exception ex)
        {
            ErrorLog("StreamFileToBrowser: " + ex.Message);
        }
    }


from Detecting when a save as dialog is shown to the user

No comments:

Post a Comment