Working with Gridviews and File Transfers - asp.net

I need to generate a Excel sheet during RunTime on a ItemCommand_click event in a GridView and transfer the file and then re-bind the GridView with the status change.
As we redirect the response with File transfer , How could I update the GridView?

I was looking to do something very similar on selected index change on the rows to output a reporting services report as a PDF. I was only able to get this to work with a response.redirect to another page that handled the output of the file. It looks like your issue really becomes the rebinding the grid after the status change, if you do a response.redirect, you can't touch your grid...
Take a look at this code. I found it on encosia.com. It looks like you might be able to use the iFrame for your output, and then you can use a JavaScript call to postback the page to rebind the grid maybe.
<html>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" />
<script language="javascript">
// Get a PageRequestManager reference.
var prm = Sys.WebForms.PageRequestManager.getInstance();
// Hook the _initializeRequest event and add our own handler.
prm.add_initializeRequest(InitializeRequest);
function InitializeRequest(sender, args)
{
// Check to be sure this async postback is actually
// requesting the file download.
if (sender._postBackSettings.sourceElement.id == "DownloadFile")
{
// Create an IFRAME.
var iframe = document.createElement("iframe");
// Get the desired region from the dropdown.
var region = $get("Region").value;
// Point the IFRAME to GenerateFile, with the
// desired region as a querystring argument.
iframe.src = "GenerateFile.aspx?region=" + region;
// This makes the IFRAME invisible to the user.
iframe.style.display = "none";
// Add the IFRAME to the page. This will trigger
// a request to GenerateFile now.
document.body.appendChild(iframe);
}
}
</script>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:DropDownList runat="server" ID="Region">
<asp:ListItem Value="N">North Region</asp:ListItem>
<asp:ListItem Value="W">West Region</asp:ListItem>
<asp:ListItem Value="SE">Southeast Region</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" ID="DownloadFile" Text="Generate Report" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
The page that handles the download...
protected void Page_Load(object sender, EventArgs e)
{
string FileResponse;
string Region = Request.QueryString["Region"];
// Code here to fill FileResponse with the
// appropriate data based on the selected Region.
Response.AddHeader("Content-disposition", "attachment; filename=report.csv");
Response.ContentType = "application/octet-stream";
Response.Write(FileResponse);
Response.End();
}

Related

How to get img src that changed by JavaScript in code behind C#.NET

this is my client code:
<form id="form1" runat="server">
<div>
<img id="mm" runat="server" />
</div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<script>
document.onclick = function () {
mm.src = "photo1.jpg";
}
</script>
</form>
and I try to get img src in code behind, but it returns null :
protected void Button1_Click(object sender, EventArgs e)
{
string s1= Request.Form["mm"];
string s2= mm.Attributes["src"];
string s3 = mm.Src;
}
How can I do this?
You simple can not. You can not get on code behind the srcof an image after have been change by javascript.
This is because this information is not travel back to server even by post back.
The work around is to save at the same time with the src to a hidden input control on the value... the same data.
So after the post back you read the value from that input control, because only that type of controls send back their values.
Here is an example base on your code
<asp:HiddenField runat="server" ID="ImgExSrc" />
<script>
document.onclick = function () {
mm.src = "photo1.jpg";
document.getElementById("<%=ImgExSrc.ClientID%>").value = mm.src;
}
</script>
and on code behind you just read the ImgExSrc.Value after the post back. Only with post back you can send your values to the server side.

custom ListView inside Update panel not refreshing

I'm trying to solve this problem.
I have an Accordion inside an UpdatePanel. Inside the Accordion control I dinamically create at most four AccordionPanes, each with a custom ListView that shows some image previews fetched from a database. Each preview is composed by a 160x120 ImageButton. When the user clicks on one of these buttons a popup is opened with the image at real size (by a Seadragon control); he can now rotate the image and save it back to the database. Now, after saving the image, I close the popup and submit a postback by generating a click event on a hidden button inside the UpdatePanel containing the Accordion, but even if I can step through the hidden button event code, the refresh doesn't take place. The hidden button was the last (and most effective) solution I've tried, without success. What am I missing ? (The absolute best solution would be refresh the only image that changed, because sometimes the ListView contains several previews).
This is the
<div>
<table class="style8">
<tr>
<td class="style2">
<asp:UpdatePanel ID="usersPanel" runat="server" >
<ContentTemplate>
<cc1:c1treeview ID="tvUsers" runat="server"
onselectednodeschanged="tvUsers_SelectedNodesChanged" AutoPostBack="True"
onnodecheckchanged="tvUsers_SelectedNodesChanged">
</cc1:c1treeview>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="imagesPanel" runat="server" UpdateMode="Always" >
<ContentTemplate>
<asp:Button ID="hiddenImageRefresh" runat="server" Text="Refresh"
style="display:none;" onclick="hiddenImageRefresh_Click" />
<ajaxToolkit:Accordion ID="accImages" runat="server" >
</ajaxToolkit:Accordion>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
</table>
</div>
And this is the code contained in the hidden button click event, code, that regularly runs when the popup closes. It simply extracts a user code (promo) and rebind the data (LoadImages)
protected void hiddenImageRefresh_Click(object sender, EventArgs e)
{
string promo = "";
if(Session[SessionVariables.CurrentPromoter] != null)
promo = Session[SessionVariables.CurrentPromoter].ToString();
LoadImages(promo, ddlImageType.SelectedValue);
}
Steps to refresh only updated image
Step#1: in JavaScript
//Take one global variable
var selectedImageId="";
Step#2: in JavaScript
//set above var with image id, When user clicks on the ImageButton, which is inside openPopup function
selectedImageId = this.id;
Step#3: in Code-Behind
protected void bSave_Click(object sender, EventArgs e) {
//SaveImage();
#region here get the imageUrl that needs to be updated and send as parameter in closePopup js function
var timeStamp = dImgTag.ToString("yyyyMMdd HH:mm:ss.fff") ;
var promoter = riga["PROMOTER"].ToString();
var pv = riga["PV"].ToString();
var imageUrl = string.Format("../Handlers/ImageLoader.ashx?id={0}&promo={1}&pv={2}", timeStamp, promoter, pv);
#endregion
ClientScriptManager csm = Page.ClientScript;
csm.RegisterStartupScript(Page.GetType(), "closeScript", "closePopup(true,'"+ imageUrl +"');", true);
}
Step#4: in JavaScript
function closePopup(refreshParent, imageUrl) {
if (refreshParent) {
//get the selectedImage and set the source with new url
var selectedImage = window.opener.document.getElementById(selectedImageId);
selectedImage.src = imageUrl;
}
window.close();
}

Asp.net auto response to client

I have this table on my sql server database:
name
family
address
and i have a 2 user's:
User A
User B
i want to when User B insert new record into the table,show in User A gridView.
i use this solution:
User A web browser has a this code:
<script type="text/javascript">
$(document).ready(function () {
setTimeout("RefreshPage()", 5000);
});
function RefreshPage() {
/* var url = "GetOrder.aspx";
$(location).attr("href", url);
*/
location.reload();
};
</script><br/>
that code refresh User A webpage every 5 second and in page load event i write a simple code to run select query and show in gridview.
this method very crazy solution to do this.
can i use other solution and how?
Your code Refresh whole page. Use below code, it will refresh only contain. :)
<asp:ScriptManager ID="scp1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:GridView ID="yourGrid" runat="server"></asp:GridView>
<asp:Button id="btnAutoRefresh" runat="server" style="display:none"
onclick="btnAutoRefresh_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<script type="text/javascript">
$(document).ready(function () {
setInterval("RefreshPage()", 5000);
});
function RefreshPage() {
$("#<%=btnAutoRefresh.ClientID %>").trigger("click");
};
</script>
// code behind
protected void btnAutoRefresh_Click(object sender, EventArgs e)
{
// code for Bind Grid
}
You need to use client notification technique, for example SignalR. You can read more about it here

How to correct ASP.NET webform jquery reference being lost on partial postback

Within an asp.net webform I have some jquery that controls the positioning of elements on the page. Since this is a webform and some of these controls talk to the server to get jquery to work I have the controls nested in an AJAX UpdatePanel to prevent postbacks from resetting my controls.
aspx:
<asp:UpdatePanel ID="searchupdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div id="searchholder" >
<div id="searchoptions">
Close Advanced Search
<br />
Filters
</div>
<div id="search" class="searchcontainer">
<asp:TextBox ID="tbsearchterm" CssClass="watermark" runat="server" OnTextChanged="tbsearchterm_TextChanged" />
<div class="buttons">
<asp:LinkButton runat="server" Text="Search" class="button search-big" ID="btnSearch" OnClick="btnSearch_Click" />
<asp:LinkButton runat="server" Text="Fx" class="button left big" ID="btnOperators" />
<asp:LinkButton runat="server" Text="Save" class="button right big" ID="btnSave" />
</div>
</div>
<div id="divAdvSearch">
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="divBody">
<asp:UpdatePanel runat="server" UpdateMode="Always">
<ContentTemplate>
<div id="divSearchResults" visible="true" runat="server">
<uc:SearchResultsControl ID="SearchResultsControl" runat="server"></uc:SearchResultsControl>
</div>
</ContentTemplate>
</asp:UpdatePanel>
When the search button is clicked I modify the css class for the search control to reposition my search div layer which is the update panel "searchudpatepanel"
searchcontrol.js
$(function () {
$("#searchupdatePanel").addClass("searchmenubar");
$("#btnClose").hide();
});
$(function () {
$("#btnSearch").click(function () {
$(".searchmenubar").animate({ "margin-top": "5px" }, "fast");
$("#btnAdvanceSearch").show();
$("#btnFilters").show();
$("#btnClose").hide();
$("#divAdvSearch").hide();
alert("search");
});
});
The button click also calls serverside code to retrieve and populate the results within a user control called SearchResultsControl ( second update panel)
Where I am confused is when the searchResult Control is loaded with the results all references to the jquery classes are lost. As a result every div element that is hidden or button click that is called ceases to work. Working through this in debug I can see when the user control is called the Page_Load for the default.aspx file is invoked as second time. I assume this partial load is dropping reference to the js files I just don't know how to correct this.
I tried a test within the page load using IsStartupScriptRegistered to see if the js was getting called
string csname = "PopupScript";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsStartupScriptRegistered(cstype, csname))
{
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript> alert('Hello World!') </");
cstext1.Append("script>");
cs.RegisterStartupScript(cstype, csname, cstext1.ToString());
}
Here on the initialization of the page I would see the pop up occur however when the UserControl was loaded I would pass through this a second time in the page load but the alert never displayed( I assume this is due to a partial load so the browser thinks the script is already registered).
The only other thing I can think of is I am overriding the rendering of the UserControl being loaded as it loads a custom result set.
protected override void Render(HtmlTextWriter htw)
{
if (IsPostBack)
{
QueryResponse qr = iu.GetSearchResults(SearchTerm);
int num = qr.TotalMatchesReturned;
SearchData sd = new SearchData();
htw.Write("<table style='width: 100%; height:100%'><tr ><td style='width: 50%'>");
htw.Write("<div id='divResultDetail' runat=server >");
htw.Write("<script type='text/javascript' src='../js/paging.js'></script><div id='pageNavPosition'></div><table id='results'>");
for (int i = 0; i < num; i++)
{
...edited for brevity.
Any suggestions or guidance as to why I am losing reference to the jquery functions? I am not using master pages so I haven't used the ASP ScriptManager.
This all worked fine prior to using UpdatePanels. I define "fine" as: the postback was reloading/registering the js files each time, so they were being reset (which was okay). However, now with some other changes needed I need to look at leveraging UpdatePanels.
Thanks for any suggestions or ideas.
You can use the live or delegate jQuery methods to get your handlers to be bound to any elements added to the page.
Alternatively, if you need some setup to always happen after every partial postback in addition to original page load, you can put it in a pageLoad method instead of document.ready. ASP.NET calls this on page load, and after every partial postback.
function pageLoad()
{
// Setup code here
}
Check this article for more:
http://encosia.com/document-ready-and-pageload-are-not-the-same/
You need to use delegate for the button click. It will assure that all elements present and future will be bound to the event handler.
http://api.jquery.com/delegate/
$("body").delegate("#btnSearch", "click", function () {
$(".searchmenubar").animate({ "margin-top": "5px" }, "fast");
$("#btnAdvanceSearch").show();
$("#btnFilters").show();
$("#btnClose").hide();
$("#divAdvSearch").hide();
alert("search");
});
You need to rebind the elements when the update panel finish updating. Like this,
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
$('#add').click(function () {
});
$('#addPrevious').click(function () {
});
});
Hope this helps.

ASP.NET 3.5: Display UpdateProgress during Page_Load()

I am building an ASP.NET site using Visual Studio 2008 and have a page looking like this (stuff snipped)
<asp:Content ID="Content2" ContentPlaceHolderID="PageContentPlaceHolder" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
the page here..
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="100">
<ProgressTemplate>
<div>
<asp:Image ID="AjaxImage" runat="server" ImageUrl="Ajax.gif" />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</asp:Content>
The page_load starts a long (>5s) process
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LongRunningProcess();
}
}
How can I display the UpdateProgress while the LongRunningProcess is running? It does work when I move the LongRunningProcess() call to a button onclick handler.
Move your page_load code into a new function.
Add a AJAX timer into the ContentTemplate section of your page. Set the interval to 500. (1/2 second)
Double-click on the Timer object in Design view to create a _tick handler.
In the _tick handler created in the previous step, call the following code
protected void My_Timer_Tick(object sender, EventArgs e)
{
My_Timer_Name.Enabled = false;
My_Page_Load_Function(); // Function created in step 1 above)
}
protected void My_Page_Load_Function()
{
System.Threading.Thread.Sleep(5000); // A delay to simulate doing something.
lblMyLabel.Text = "Done!"; // Write output to page.
}
Create a normal div that shows the Ajax.gif so it shows "processing" by default.
In the javascript pageLoad() function, make a call back to the page using Ajax's PageMethods.
function pageLoad(sender, args) {
PageMethods.getVersions(LoadVersionsCallback);
}
The method you are calling in your .aspx.cs file has to be static, it can take parameters and looks something like:
[System.Web.Services.WebMethod]
public static string getVersions()
{
StringBuilder sb = new StringBuilder();
... etc.
return sb.ToString();
}
The javascript function that you specified when you called the method will run when the method completes. It will be passed the results. At the end of this function you hide the Ajax.gif div.
function LoadVersionsCallback(result) {
// do something with the results - I load a dropdown list box.
...etc.
// here is where you hide your div holding the Ajax.gif
}
And then you work on making whatever it is you are doing run in less than 1 second....
I would put a Ajax timer on the page and set it for less than a second... It will only run once and after its first tick then you need to disable it otherwise it will fire again. (you don't want to start your long running process more than once...)
then on the OnTimerTick event I would start your long running process that way your page fully renders and you can display your UpdateProgress while its running.
you out to be able to move the code that you had for your button click to the time tick...
I used JBrooks idea above (i.e. showing the progress indicator as part of a Panel that also includes the Iframe, so that it shows even before the Iframe first loads), but simplified it: style the iframe so that when it does appear it is on top of the animated GIF.
Requires no Javascript or C# code-behind.
Here's the relevant ASPX, followed by the CSS. You'll have to noodle with the "top" setting in the style to cover the image you use.
<asp:Panel ID="DetailPanel" runat="server" CssClass="submitBox detailPanel">
<asp:Table ID="Table1" runat="server" Width="100%">
<asp:TableHeaderRow ID="TableHeaderRow10" runat="server">
<asp:TableCell ID="TableHeaderCell" runat="server"
Font-Bold="true" HorizontalAlign="Center">
Title Text
</asp:TableCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell HorizontalAlign="Center">
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/animated_progress.gif" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<div class="iframeOverlay">
<iframe id="IframeDetail" runat="server" style="width: 100%; height: 100%;" />
</div>
</asp:Panel>
.iframeOverlay
{
z-index: 2;
position: relative;
top: -50px;
}
With Jquery.
<script>
$(document).ready(function() {
$('#<%= UpdateProgress1.ClientID %>').show();
});
</script>
<script> $(document).ready(function() { $('#<%=
UpdateProgress1.ClientID %>').show(); }); </script>
This worked well for me, just had to add it to the end of the BODY section and works like a charm.

Resources