ASP.NET download PDF feature in UpdatePanel unable to refresh UpdateProgress control - javascript

I've two UpdatePanel in a page. The second one has UpdateMode="Conditional" and here there's a link button to produce PDF file.
My goal is to allow the PDF download and in the meantime make a waiting image appear (like an hourglass).
After a few days of studying I reached my goal but i can't hide the image after all operations are terminated.
In the code example i've simplified logic to procude pdf (in complete code i use gridview control data to produce pdf).
If I use an asynchronous PostBackTrigger in UpdatePanel the PDF is not downloaded even if the UpdateProgress (with the expected image) works correctly.
If I use a Synchronous PostBackTrigger in UpdatePanel the PDF is downloaded correctly but the updateProgress does not work because the waiting image remains on the screen. In this case i've used a client side function (postbackButtonClick) to display the image.
I've read many threads but each one is always a little different.
My actual goal is to know if possible on client side when the PDF production operation is complete to hide the image.
Maybe the general approach is wrong?
aspx file
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" EnableCdn="true"> </asp:ScriptManager>
<asp:UpdateProgress ID="UpdateProgress1" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="updateGrid" DisplayAfter="0" >
<ProgressTemplate> <div class="progress"> <img src="../images/ajax-loader.gif" /> Waiting...</div> </ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="updateGrid" runat="server">
<ContentTemplate>
<asp:TextBox class='form-control' ID="txtMat" runat="server" style='width:110px' Text="1672"></asp:TextBox>
<asp:Button class='btn btn-primary' ID="cmdGO" runat="server" Text="Execute"/>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="panelCMD" runat="server">
<asp:LinkButton ID="LinkButton3" OnClientClick="return postbackButtonClick();"
runat ="server" CssClass="btn btn-small btn-primary fullwidth" OnClick="mtdCreatePDF"><i class="icon icon-ok"></i> TEST PDF</asp:LinkButton>
</asp:Panel>
</ContentTemplate>
<Triggers >
<asp:PostBackTrigger ControlID="LinkButton3" />
</Triggers>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress2" ClientIDMode="Static" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UpdatePanel2" DisplayAfter="0" >
<ProgressTemplate>
<div class="progress">
<asp:image id="imgOld" runat="server" imageurl="../images/ajax-loader.gif" />
<br />
<img id="imgLike" src="../images/ajax-loader.gif" /> Attendere...</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
<script src="Test.js" type="text/javascript"></script>
Test.js
function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;
}
cs file
protected void mtdCreatePDF(object sender, EventArgs e)
{
byte[] content = null;
string TypeOutput = "RESPONSE";
string suffix = #"Pdf_PROD\Print.pdf";
string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
if (TypeOutput == "RESPONSE")
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=print.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
//writer.SetCloseStream(false);
Response.BinaryWrite(stream.ToArray());
Response.End();
}
else
{
content = stream.ToArray();
using (FileStream fs = File.Create(nameTGT))
{
fs.Write(content, 0, (int)content.Length);
}
}
}

First, there needs to be a timeoutID for the timeout. We will use it later to disable the timeout. After pdf creation is completed, hideUpdateProgress() function will be called from code-behind to hide the progress image.
Test.js
var timeoutID;
function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
timeoutID = window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;
function hideUpdateProgress()
{
clearTimeout(timeoutID);
updateProgress = $find("UpdateProgress2");
updateProgress.set_visible(false);
}
To call hideUpdateProgress();, you can add this line at the end of mtdCreatePDF function.
ClientScript.RegisterStartupScript(Page.GetType(),
"hideUpdateProgress",
"hideUpdateProgress();",
true);

I solved it in the following way: I moved everything to the client side.
A. I added a client-side event on the click of the link button
<asp:LinkButton ID="LinkButton6" OnClientClick="return TestPDFDEF();" runat="server" CssClass="btn btn-small btn-primary fullwidth"><i class="icon icon-ok"></i> TEST PDF WebService Def</asp:LinkButton>
B. I added a WebMethod to the page that provides a variable of type [byte] to the Ajax call
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public byte[] GetPDF(List<Classes.GridCosts> MyGrid)
{
foreach (Classes.GridCosts rowsGrid in GrMyGridglia)
{
Console.Write(rowsGrid.Field1);
Console.Write(rowsGrid.Field2);
}
string suffix = #"Pdf_PRODOTTI\Print.pdf";
string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
return stream.ToArray();
}
C. I have defined a class for receiving the grid that will be passed to the method
public class GridCosts
{
public string Field1{ get; set; }
public string Field2{ get; set; }
}
D. Added image that appears for hourglass:
$(document).ready(function () {
$('body').append('<div class="progress" id="ajaxBusy"><p><img src="../images/ajax-loader.gif"> Waiting..</p></div>');
$('#ajaxBusy').hide();
//$('#ajaxBusy').css({
// display: "none",
// left: "50%",
// margin: "0px",
// paddingLeft: "0px",
// paddingRight: "0px",
// paddingTop: "0px",
// paddingBottom: "0px",
// position: "fixed",
// right: "3px",
// top: "35%",
// width: "auto"
//});
// Ajax activity indicator bound to ajax start/stop document events
$(document).ajaxStart(function () {
$('#ajaxBusy').show();
}).ajaxStop(function () {
$('#ajaxBusy').hide();
});
});
E. I sent the variable referred to in point B to the user with Javascript
function TestPDFDEF() {
$(function () {
var MyGrid= new Array();
var CostsRow = {};
$('[id*=MyGrid]').find('tr:has(td)').each(function () {
CostsRow.Field1= $.trim($(this).find("td:nth-child(3)").text());
CostsRow.Field2= $.trim($(this).find("td:nth-child(4)").text());
MyGrid.push(CostsRow );
CostsRow = {};
});
type: "POST",
url: "WebService1.asmx/GetPDF",
contentType: "application/json; charset=utf-8",
data: '{MyGrid: ' + JSON.stringify(MyGrid) + '}',
dataType: "json",
beforeSend: function () {
},
success: function (data) {
data = data.d;
var byteArray = new Uint8Array(data);
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([byteArray], { type: 'application/pdf' }));
a.download = 'FileName';
document.body.appendChild(a)
a.click();
document.body.removeChild(a)
},
complete: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
});
}

Related

OnClientClick parameterized from code behind variable

I am not sure what my problem is because when i click the button no error in console and the javascript is not triggered.
asp
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick='<%# "show("+Eval("I") +");" %>' />
server side
public partial class _Default : Page
{
public string ClientID = "1";
public string I = "2";
public string J = "3";
protected void Page_Load(object sender, EventArgs e)
{
//Page.DataBind();
}
}
javascript
function show(str) {
//var str = "test";
console.log(str);
event.preventDefault();
alert(str);
}
I've been referring to below post, but I still couldnt figure it out... will someone help?
How to pass bind or eval arguments with the client function "OnClientClicking"

Internal Server Error in JavaScript ajax with asp.net

I'm still a beginner in JavaScript and ajax. I have this problem in my code where I try to upload an image from an ajaxfileupload but the error for JavaScript will always popup, saying that it has an internal server error. What possible mistakes I made in my code?
Here is the aspx code:
<%# Page Language="C#" AutoEventWireup="true"
CodeFile="CreateBrands.aspx.cs" Inherits="Pages_CreateBrands" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
TagPrefix="asp"%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Music Store</title>
<script src="../Javascript/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
function uploadComplete(sender, args) {
var txt = document.getElementById("validatePicture1");//Your
hiddenfield id
txt.value = "1";
$.ajax({
type: "POST",
url: "CreateBrands.aspx/GetPath1",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
OnSuccess1(result.d);
},
error: function (xhr, status, error) {
OnFailure1(xhr,status,error);
}
});
}
function OnSuccess1(result) {
var pp = document.getElementById("PicturePath1");
pp.value = result;
}
function OnFailure1(xhr,status,error) {
alert("Request: " + xhr + "\n\nStatus: " + status + "\n\nError: " +
error);
}
</script>
<script type="text/javascript">
function uploadComplete2(sender, args) {
var txt = document.getElementById("validatePicture2");//Your
hiddenfield id
txt.value = "1";
$.ajax({
type: "POST",
url: "CreateBrands.aspx/GetPath2",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
OnSuccess1(result.d);
},
error: function (xhr, status, error) {
OnFailure1(xhr,status,error);
}
});
}
function OnSuccess1(result2) {
var pp = document.getElementById("PicturePath2");
pp.value = result;
}
function OnFailure1(xhr,status,error) {
alert("Request: " + xhr + "\n\nStatus: " + status + "\n\nError: " +
error);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div id="wrapper">
<div id="content_area">
<h3> </h3>
<h3 class="headingTitle">Create New Brand(Step 1 of 2):</h3>
<table cellspacing="15" class="brandsTable">
<br/>
<h3 class="headingTitle">Create New Item(Step 2 of 2):</h3>
<table cellspacing="15" class="brandsTable">
<tr>
<td style="width: 160px; height: 37px;">
<strong>Item Type:</strong></td>
<td style="height: 37px">
<asp:RadioButton ID="itemType1" runat="server"
Text="Guitar" AutoPostBack="False" GroupName="itemType"/>
<asp:RadioButton ID="itemType2" runat="server"
Text="Bass" AutoPostBack="False" GroupName="itemType"/>
</td>
</tr>
<tr>
<td style="width: 160px; height: 37px;">
<strong>Item Image1:</strong></td>
<td style="height: 37px">
<br />
<asp:AjaxFileUpload ID="itemFileUpload1"
runat="server" OnUploadComplete="itemUploadImage1_Click"
OnClientUploadComplete="uploadComplete" MaximumNumberOfFiles="1"/>
<asp:HiddenField ID="validatePicture1" Value=""
runat="server" />
</td>
</tr>
<tr>
<td style="width: 160px; height: 37px;">
<strong>Item Image2:</strong></td>
<td style="height: 37px">
<br />
<asp:AjaxFileUpload ID="itemFileUpload2"
runat="server" OnUploadComplete="itemUploadImage2_Click"
OnClientUploadComplete="uploadComplete2" MaximumNumberOfFiles="1"/>
<asp:HiddenField ID="validatePicture2" Value=""
runat="server" />
</td>
</tr>
</table>
<asp:Label ID="lblResult2" runat="server" Text="">
</asp:Label>
<br />
<asp:Button ID="Button1" runat="server"
CssClass="submitButton" Text="Save Item" OnClick="Button1_Click"/>
</div>
</div>
</form>
</body>
</html>
And here is the code-behind. By the way, it also has an object reference null in the method GetPath1 with this line of code: string retval = Session["PicturePath1"].ToString();:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;
public partial class Pages_CreateBrands : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
private void ClearTextFields2()
{
itemBrand.Text = "";
itemModel.Text = "";
itemPrice.Text = "";
itemDescription.Text = "";
itemNeckType.Text = "";
itemBody.Text = "";
itemFretboard.Text = "";
itemFret.Text = "";
itemNeckPickup.Text = "";
itemBridgePickup.Text = "";
itemBridge.Text = "";
itemHardwareColor.Text = "";
}
[System.Web.Services.WebMethod]
public string GetPath1()
{
System.Web.SessionState.HttpSessionState Session =
System.Web.HttpContext.Current.Session;
string retval = Session["PicturePath1"].ToString();
Session["PicturePath1"] = null;
return retval;
}
[System.Web.Services.WebMethod]
public string GetPath2()
{
System.Web.SessionState.HttpSessionState Session =
System.Web.HttpContext.Current.Session;
string retval = Session["PicturePath2"].ToString();
Session["PicturePath2"] = null;
return retval;
}
protected void itemUploadImage1_Click(object sender, AjaxFileUploadEventArgs
e)
{
if (itemType1.Checked)
{
string filename = e.FileName;
Session["PicturePath1"] = filename;
itemFileUpload1.SaveAs(Server.MapPath("~/Images/Brands/String
Instrument Items/Guitar/") + filename);
}
else if(itemType2.Checked)
{
string filename = e.FileName;
Session["PicturePath1"] = filename;
itemFileUpload1.SaveAs(Server.MapPath("~/Images/Brands/String
Instrument Items/Bass/") + filename);
}
}
protected void itemUploadImage2_Click(object sender, AjaxFileUploadEventArgs
e)
{
if (itemType1.Checked)
{
string filename = e.FileName;
Session["PicturePath2"] = filename;
itemFileUpload2.SaveAs(Server.MapPath("~/Images/Brands/String
Instrument Items/Guitar/") + filename);
}
else if (itemType2.Checked)
{
string filename = e.FileName;
Session["PicturePath2"] = filename;
itemFileUpload2.SaveAs(Server.MapPath("~/Images/Brands/String
Instrument Items/Bass/") + filename);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (itemType1.Checked)
{
int item_type =
ConnectionClassBrands.GetIdByType(itemType1.Text);
int item_brandId =
ConnectionClassBrands.GetIdByBrand(itemBrand.Text);
string item_model = itemModel.Text;
double item_price = Convert.ToDouble(itemPrice.Text);
string item_image1 = Session["PicturePath1"].ToString();
string item_image2 = Session["PicturePath2"].ToString();
string item_description = itemDescription.Text;
string item_necktype = itemNeckType.Text;
string item_body = itemBody.Text;
string item_fretboard = itemFretboard.Text;
string item_fret = itemFret.Text;
string item_bridge = itemBridge.Text;
string item_neckpickup = itemNeckPickup.Text;
string item_bridgepickup = itemBridgePickup.Text;
string item_hardwarecolor = itemHardwareColor.Text;
ConnectionClassGuitarItems.AddStringInstrumentItems(item_type,
item_brandId, item_model, item_price, item_image1, item_image2,
item_description, item_necktype, item_body, item_fretboard,
item_fret, item_bridge, item_neckpickup,
item_bridgepickup, item_hardwarecolor);
lblResult2.Text = "Upload successful!" + item_image1 + " and " +
item_image2;
}
else if (itemType2.Checked)
{
try
{
int item_type =
ConnectionClassBrands.GetIdByType(itemType2.Text);
int item_brandId =
ConnectionClassBrands.GetIdByBrand(itemBrand.Text);
string item_model = itemModel.Text;
double item_price = Convert.ToDouble(itemPrice.Text);
string item_image1 = Session["PicturePath1"].ToString();
string item_image2 = Session["PicturePath2"].ToString();
string item_description = itemDescription.Text;
string item_necktype = itemNeckType.Text;
string item_body = itemBody.Text;
string item_fretboard = itemFretboard.Text;
string item_fret = itemFret.Text;
string item_bridge = itemBridge.Text;
string item_neckpickup = itemNeckPickup.Text;
string item_bridgepickup = itemBridgePickup.Text;
string item_hardwarecolor = itemHardwareColor.Text;
ConnectionClassGuitarItems.AddStringInstrumentItems(item_type,
item_brandId, item_model, item_price, item_image1, item_image2,
item_description, item_necktype, item_body,
item_fretboard, item_fret, item_bridge, item_neckpickup,
item_bridgepickup, item_hardwarecolor);
lblResult2.Text = "Upload successful!";
ClearTextFields2();
}
catch (Exception ex)
{
lblResult2.Text = ex.Message;
}
}
else
{
Response.Redirect("~/Pages/OverviewGuitarData.aspx");
}
}
}

Call alert after response.end

Here is my code where I am trying to show alert after response. But no os alert is showing
string filepath = ConfigurationManager.AppSettings["USPPath"].ToString() + urlPDF;
FileInfo file = new FileInfo(Server.MapPath(filepath));
if (file.Exists)
{
ClientScript.RegisterStartupScript(this.GetType(), "somekey", "alert('Some data missing!');", true);
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/pdf";
Response.TransmitFile(file.FullName);
try
{
Response.Flush();
ClientScript.RegisterStartupScript(this.GetType(), "somekeyqw","alert('Some data missing!'); ", true);
// DisplaySucessAlert(true, "Shipping Label downloaded successfully.");
// ScriptManager.RegisterStartupScript(this, this.GetType(), "Popalertxs", "normalalert();", true);
}
finally
{
// DisplaySucessAlert(true, "Shipping Label downloaded successfully.");
// ScriptManager.RegisterStartupScript(this, this.GetType(), "Popalert", "normalalert();", true);
}
}
I have used update panel and the html code look likes
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="btnuspsgenerate" class="btn-def" runat="server" Text="Download USPS label" OnClick="btnuspsgenerate_Click" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnuspsgenerate" />
</Triggers>
</asp:UpdatePanel>
My pdf file gets download but not showing alert.
Here I had used many ways but not able to show alert.
Some of the code I have commented as they where not working
When you use update panel then you can not call javascript like this ..
Try Following Code,
string CloseWindow;
CloseWindow = "alert('Hello World')";
ScriptManager.RegisterStartupScript(UpdatePanelID,UpdatePanelID.GetType(), "CloseWindow", CloseWindow, true);

fire javascript function from asp.net codebehind

This is my javascript function ,
function returnToParent() {
var oArg = new Object();
var oWnd = GetRadWindow();
oArg.ReturnValue = "Submit";
oWnd.close(oArg);
}
And this is how I call this function on client side
<button title="Submit" runat="server" id="close" onclick="returnToParent(); return false;">
OK</button>
I want to fire this function in server side button click event .
What I've done is add new button
<asp:Button runat="server" ID="rtxtSubmitChange" OnClick="rtxtSubmitChange_Click" Text="Submit" />
and in ButtonClick Event ,
protected void rtxtSubmitChange_Click(object sender, EventArgs e)
{
Page.ClientScript.RegisterStartupScript(GetType(),
"MyKey",
"returnToParent();",
false);
}
But It doesn't work . What I am wrong in my code ?
Try
ScriptManager.RegisterStartupScript(this, this.GetType(), this.ClientID, "returnToParent()", true);
OR
ScriptManager.RegisterStartupScript(Page, Page.GetType(), this.ClientID, "returnToParent()", true);
For more details refer :ScriptManager.RegisterStartupScript Method

Sharepoint 2010 XsltListViewWebPart on an application page

I'm trying to add an XsltListViewWebPart control to a sharepoint application dynamically.
When I run ShowDocumentList(pnlAdminCurrentDocuments) on Page_Load everything works fine.
However, if i call the same function on a ajax request, the control loads, but none of the events get fired (i.e. sorting, expanding tree view etc)
XsltListViewWebPart wp;
private void ShowDocumentList(Panel panel)
{
try
{
ShowMessage("<p>No documents to show</p>");
string meetingURL = "http://rl01/sites/nmc/FullMonty";
string meetingId = "6d39de81-a7f7-4cff-9c94-5d2893526dc5";
if (!string.IsNullOrEmpty(meetingURL) && !string.IsNullOrEmpty(meetingId))
{
using (SPSite site = new SPSite(meetingURL))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists.TryGetList("Meeting Documents");
if (list == null)
return;
SPView view = null;
try
{
view = list.Views["Submitted"];
//view = list.Views[0];
}
catch { }
if (view == null)
{
//todo - replace with toolbx message
ShowMessage("Cannot view documents");
}
else
{
wp = new XsltListViewWebPart();
wp.ChromeType = PartChromeType.None;
wp.ListId = list.ID;
wp.ViewGuid = view.ID.ToString();
wp.WebId = web.ID;
wp.XmlDefinition = view.GetViewXml();
wp.XmlDefinition = wp.XmlDefinition.Replace("MEETING_ID", meetingId);
//SetToolbarContext(web);
panel.Controls.Clear();
panel.Controls.Add(wp);
}
}
}
}
}
catch (Exception ex)
{
ShowMessage("");
}
}
The function actually gets the data and does everything but none of the client side functionality on the list view doesn't work. Throws a javascript error even when I mouse over the column names. If I add the control with a full postback without using ajax, everything works as expected.
protected void radAjaxMgr_AjaxRequest(object sender, Telerik.Web.UI.AjaxRequestEventArgs e)
{
ShowDocumentList(pnlAdminCurrentDocuments);
}
HTML markup is as follows
<telerik:RadAjaxManager ID="radAjaxMgr" runat="server" OnAjaxRequest="radAjaxMgr_AjaxRequest">
</telerik:RadAjaxManager>
<asp:UpdatePanel runat="server" ID="pnl1">
<ContentTemplate>
<asp:Panel ID="pnlAdminCurrentDocuments" runat="server" CssClass="i3q_DocumentListHldr submittedDocsPanel">
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Javascript function to raise the ajax call
function test()
{
var ajaxMgr = $find("<%= RadAjaxManager.GetCurrent(this).ClientID %>");
if (ajaxMgr)
{
ajaxMgr.ajaxRequest("Name1;Value1");
}
}
Thanks in advance :-)

Categories

Resources