Reputation: 1
I have an ASP application which has a page where the user can select different options which are then used to generate an excel report. The report processing is triggered through a button click. I would like to add a loading message on the button click to show the user that the report is running since depending on the options selected it can take a couple minutes to generate the file.
My issue is the Report Processing code runs through the code behind and I cannot figure out a way to have the button click function on ascx.vb trigger a page update while at the same time running the processing code and downloading the report. I have tried Async but I dont think I'm using it right.
I'm still a beginner so it is hard to follow a lot of the examples online. Any recommendations for how to accomplish this would be appreciated.
Here is my code for the button click:
Private Async Sub DownloadExcelReport_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DownloadExcelReport.Click
DownloadInProgress.Visible = True
Await Task.Run(Sub()
ProcessExcelReport() 'long running sub (not an async function).
End Sub)
End Sub
And here is the (condensed) HTML code for the UI form
<header class="header bg-light bg-gradient b-b pull-in" style="margin-top:-10px; margin-bottom: 10px;">
<p class="h4">Report Download</p>
</header>
<section class="hbox wrapper">
<section class="panel panel-default">
<div class="panel-top-border"></div>
<asp:Panel ID="DownloadInProgress" runat="server" Visible="false">
<div class="alert alert-info">
<i class="fa fa-info-sign"></i><strong>Notice!</strong> Report Download is in progress. Report will download when complete.
</div>
</asp:Panel>
<asp:Panel ID="Panel2" runat="server" style="padding-left: 20px; padding-bottom: 20px; padding-right:20px; padding-top:20px;">
<div>
<asp:Label ID="lbl2" runat="server" class="newlwoverridelabel">Scope</asp:Label>
<asp:DropDownList runat="server" AutoPostBack="true" ID="ScopeCombo" OnSelectedIndexChanged="ScopeCombo_SelectedIndexChanged" CssClass="form-control m-b" Width="200px" style="display:inline-block">
</asp:DropDownList>
<asp:Label ID="Label2" runat="server" class="newlwoverridelabel">Report Name</asp:Label>
<asp:DropDownList ID="reportSelect" AutoPostBack="true" runat="server" CssClass="form-control m-b" Width="400px" style="display:inline-block" OnSelectedIndexChanged="reportSelect_SelectedIndexChanged">
</asp:DropDownList>
</div>
<div style='margin-left:5px;margin-bottom:5px;'>
<asp:Button runat="server" Text="Download Excel Report" ID="DownloadExcelReport" />
</div>
</asp:Panel>
</section>
</section>
Upvotes: 0
Views: 1443
Reputation: 3767
As Paulo Morgado says, use asynchronous code in ASP.NET Web Forms code-behind is useless for your requirement. The right way is using the ajax or updatepanel to achieve your requirement.
I suggest you could try to use ajaxtoolkit updatepanel and UpdateProgress control to achieve your requirement.
The code example:
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="ShowProgess.aspx.vb" Inherits="VBidentityTrue.ShowProgess" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server">
</asp:ScriptManager>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<div class="modal">
<div class="center">
<img alt="" src="loading.gif" />
</div>
</div>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<header class="header bg-light bg-gradient b-b pull-in" style="margin-top: -10px; margin-bottom: 10px;">
<p class="h4">Report Download</p>
</header>
<section class="hbox wrapper">
<section class="panel panel-default">
<div class="panel-top-border"></div>
<asp:Panel ID="DownloadInProgress" runat="server" Visible="false">
<div class="alert alert-info">
<i class="fa fa-info-sign"></i><strong>Notice!</strong> Report Download is in progress. Report will download when complete.
</div>
</asp:Panel>
<asp:Panel ID="Panel2" runat="server" Style="padding-left: 20px; padding-bottom: 20px; padding-right: 20px; padding-top: 20px;">
<div>
<asp:Label ID="lbl2" runat="server" class="newlwoverridelabel">Scope</asp:Label>
<asp:DropDownList runat="server" AutoPostBack="true" ID="ScopeCombo" OnSelectedIndexChanged="ScopeCombo_SelectedIndexChanged" CssClass="form-control m-b" Width="200px" Style="display: inline-block">
</asp:DropDownList>
<asp:Label ID="Label2" runat="server" class="newlwoverridelabel">Report Name</asp:Label>
<asp:DropDownList ID="reportSelect" AutoPostBack="true" runat="server" CssClass="form-control m-b" Width="400px" Style="display: inline-block" OnSelectedIndexChanged="reportSelect_SelectedIndexChanged">
</asp:DropDownList>
</div>
<div style='margin-left: 5px; margin-bottom: 5px;'>
<asp:Button runat="server" Text="Download Excel Report" ID="DownloadExcelReport" OnClick="DownloadExcelReport_Click" />
</div>
</asp:Panel>
</section>
</section>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
Code-behind:
Public Class ShowProgess
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Sub ScopeCombo_SelectedIndexChanged(sender As Object, e As EventArgs)
End Sub
Protected Sub reportSelect_SelectedIndexChanged(sender As Object, e As EventArgs)
End Sub
Protected Sub DownloadExcelReport_Click(sender As Object, e As EventArgs)
'ProcessExcelReport()
System.Threading.Thread.Sleep(5000)
End Sub
End Class
Upvotes: 0
Reputation: 14846
Beware that that isn't how you're supposed to use asynchronous code in ASP.NET Web Forms.
You need to use page async tasks.
That being said, nothing in async changes the HTTP protocol and, if you want some behavior on the client side, you need to implement it on the client, as Anu showed.
Upvotes: 0
Reputation: 325
You can try to add some loading gif next to button (or any other where you want to show progress icon) set default display 'none'. And onbutton client click set it display ON.
<div style='margin-left:5px;margin-bottom:5px;'>
<asp:Button runat="server" Text="Download Excel Report" ID="DownloadExcelReport" OnClientClick="showHideProgress(1)" /> <img id="loading" src="/loading.gif" style="display:none;"/>
</div>
Add function in script block
function showHideProgress(type)
{
if(type==1) {$('#loading').show();}
else {$('#loading').hide();}
}
Upvotes: 1