Call server side function after AsyncFileUpload complete upload - asp.net

I don't know why calling another function inside the OnUploadedComplete does not work in ordinary way, It's my code:
ASP.NET code:
<asp:AsyncFileUpload ID="AsyncFileUpload1" runat="server"
OnUploadedComplete ="UploadFile1"
OnClientUploadComplete="uploadComplete" ThrobberID="myThrobber"
onclientuploaderror="uploadError" CompleteBackColor="White" />
VB.NET code:
Protected Sub UploadFile1(ByVal sender As Object, ByVal e As System.EventArgs)
'saveing file on disk, this part works fine, but calling
'myfunction() does not work properly
myfunction()
End Sub
Sub myfunction()
mylabel.Text="done" 'this does not work
insert_records_to_db() 'this works
End Sub

This is because an AsyncFileUpload-Control is rendered in an IFrame(normally a FileUpload is only possible with full postbacks due to security reasons), therefore it does not have the normal behaviour of UpdatePanels.
You can workaround it by handling the clientside OnClientUploadComplete to trigger a hidden button that causes an asynchronous postback.
OnClientUploadComplete="uploadComplete"
function uploadComplete() {
$get("<%=btnShowUploadResult.ClientID %>").click();
}
<asp:Button ID="btnShowUploadResult" runat="server" CausesValidation="false" Text="hidden" Style="display: none" />
You can store your message in the serverside OnUploadedComplete into a Session variable and read it in btnShowUploadResult.Click handler.

I believe it's due to how the AsyncFileUpload control works, see this for more information.
Couldn't you just use the client side javascript function to change your label text?

Related

AjaxFileUpload does not work in ASP.NET VB.Net

AjaxFileUpload works on visible TabContainer control TabPanels yet not on ones that are initially invisible and then set to visible.
I believe the issue would be resolved if the visibility property of the TabPanels is set by JavaScript rather than from the server but doesn't know how to do it.
Please help me to fix this issue. Thanks.
ASPX Code:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="AjaxFileUpload.aspx.vb" Inherits="_Default" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" EnablePageMethods="true"></asp:ToolkitScriptManager>
<p>AjaxFileUpload works on visible TabContainer control TabPanels yet not on ones that are initially invisible and then set to visible.</p>
<p>I believe the issue would be resolved if the visibility property of the TabPanels is set by JavaScript rather than from the server.</p>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TabContainer ID="TabContainer1" runat="server" ActiveTabIndex="0">
<asp:TabPanel ID="TabPanel1" runat="server" HeaderText="TabPanel 1">
<ContentTemplate>
<asp:Button ID="btnShow" runat="server" Text="Show"></asp:Button>
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="TabPanel2" runat="server" HeaderText="TabPanel 2" Visible="false">
<ContentTemplate>
<asp:Button ID="btnHide" runat="server" Text="Hide"></asp:Button>
<asp:AjaxFileUpload ID="AjaxFileUpload1" runat="server" AllowedFileTypes="txt,xls,xlsx,doc,docx,msg,pdf,bmp,gif,jpg,jpeg,png" MaximumNumberOfFiles="5" Width="500px" OnUploadComplete="AjaxFileUpload1_OnUploadComplete"></asp:AjaxFileUpload>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Backend VB.Net Code:
Imports System.IO
Imports AjaxControlToolkit
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub btnShow_Click(sender As Object, e As System.EventArgs) Handles btnShow.Click
If TabPanel2.Visible = False Then TabPanel2.Visible = True
TabContainer1.ActiveTabIndex = 1
AjaxFileUpload1.Visible = True
End Sub
Protected Sub btnHide_Click(sender As Object, e As System.EventArgs) Handles btnHide.Click
If TabPanel2.Visible = True Then TabPanel2.Visible = False
End Sub
Protected Sub AjaxFileUpload1_OnUploadComplete(ByVal sender As Object, ByVal e As AjaxFileUploadEventArgs)
Dim strPath As String = Server.MapPath("~/Uploads")
If Not Directory.Exists(strPath) Then Directory.CreateDirectory(strPath)
Dim sFilename As String = System.IO.Path.GetFileName(e.FileName)
Dim sUploadPath As String = "~/Uploads/"
AjaxFileUpload1.SaveAs(Server.MapPath(sUploadPath) + sFilename)
Dim filePath As String = Server.MapPath("~/Uploads/" & e.FileName)
Dim filename As String = Path.GetFileName(filePath)
End Sub
End Class
Actually, even if you set a textbox with visible=false, then the control is NOT sent down to the web page. So, you can't client side even turn that simple text box to become visible.
Use style, and display none.
The page first time is initialized, and that includes js wriing up the ajax up-loader.
So, put the mess in a div (with the control, and anything else you need to hide/show)
, say like this:
<div id="uploader" runat="server" style="display:none;width:50%">
<ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server"
ChunkSize="8192"
ClientIDMode="Static"
ViewStateMode="Enabled" />
</div>
So, if you are in SERVER side code (some button postback), then you can show the "div" like this:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.uploader.Style("display") = "inline"
End Sub
and to hide:
Me.uploader.Style("display") = "none"
Remember, while we are in a post back, all that "jazz" JavaScript STILL needed to do it dance on the FIRST page load. (so, we can't use visible = false) on first page load (and against the control or div). You need the full page to load - including the truckload of code that ONLY runs the FIRST time the ajaxupload control loads. If it not a first page load - the control will not setup and initialize correctly.
So, by using style, then the control is rendered when the page is first loaded. And this concept not only applies to the ajax, but say for a hidden text box or what not? Again, using style with display none.
In fact, DURING the process of a user selecting files, and up-loading with that control? Well, you don't want a post back. But when the whole up-load is done? And the server side events (such as saving the files), then I often DO WANT some final code, or even the web page to move on. I do want a final post-back to move on. But, I need a post-back client side!
In place of using a JaveScript _dopostback? (which forces you to write parameter code in the server side page load event? I just drop a asp button on the form some place, and HIDE it (of course with style="display:none").
Now I can use client side js to to "click" of that hidden button. The beauty is then the server side event code stub for the single button code runs, and I don't have write up event code with _doPostBack + code in load event for a code stub server side to run!
Now, in the above, I displayed the up-loader using a server side code-behind.
But, you can ALSO rather easy have client side code to hide or show that div.
If you using jQuery()?
Well, jQuery has .hide(), and .show() (and guess what!!! - .hide()/.show() actually sets the style for you!!! - so even jQuery assumes that you hide or show controls with style, since using the "SomeControl.visible" is near use-less (since anything set visible = false is NOT rendered client side - so then you can't hide/show anyway!!!).
So, to hide/show that with jQuery, you could use this client side:
function show() {
$('#uploader').show();
}
function hide() {
$('#uploader').hide();
}
And, if you not using jQuery, and want to hide/show the div? (javascript).
This will work:
function showl2() {
var mydiv2 = document.getElementById('<%=uploader.ClientID%>');
mydiv2.style.display = "inline";
}
function hidel2() {
var mydiv = document.getElementById('<%=uploader.ClientID%>');
mydiv.style.display = "none";
}
So, the simple concept here is that the control has to render on the page load and must do the first time. So, it has to come down to the browser side. Any control not visible will not be sent down to the client side. However, using css means the control is sent down client side - in all cases.
Now, after a upload, and I want a full post back of the page? Well, as note, this can be difficult, since after the ajax server side events run (such as saving the file), you do NOT get a final post back when all is said and done.
So, I set a client side event for the ajax up-loader like this:
<ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server"
AllowedFileTypes="pdf,zip"
ChunkSize="8192"
OnClientUploadCompleteAll="UpLoadDone"
/>
So, note the above client side event - all code (both server and client is done). But we now want a postback from the client side.
So, in the UpLoadDone routine?
I have this:
function uploaddone() {
document.getElementById('<%= btnProof.ClientID %>').click();
}
So, I get a post back and ALSO the code in the button stub server side also runs. And that btProof is hidden with style. But, it is a regular asp.net button. I just wanted it to be clicked after the ajax file up-load is done. But, there not really a way to get the ajax up-load to fire a postback when all is said and one. But, once again:
The concept of a hidden control with style is used - since if I hide that button with .visible = false, then in fact the button would not exist client side, and never be rendered or placed into the browser client side.

asp.net popup div with buttons no firing VB code behind, just javascript

I have the following code in ASP.net / VB.
When a button is pressed on the page, the div_yes_no (see code below) popsup as a YesNO message. The popup shows two buttons (YES and NO)
<div id="div_yes_no" class="messagepopup" runat="server">
<br/>
<span class="desc">Are you sure you want to transfer this data (Y/N) ?</span>
<br/>
<asp:Button ID="btnYES" runat="server" Text="Yes" OnClientClick="ShowCoverNONE(''); Hide2();" OnClick="btnYES_Click" CssClass="STD_button" />
<asp:Button ID="btnNO" runat="server" Text="No" OnClientClick="ShowCoverNONE(''); Hide2();" CssClass="STD_button" />
</div>
This is the code in VB which should run when btnYES is clicked:
Protected Sub btnYES_Click(sender As Object, e As EventArgs)
MsgBox("hello")
.... actual code
End Sub
The problem is that the btnYES_Click code is not firing, just the javascript fires: OnClientClick="ShowCoverNONE(''); Hide2();"
Any ideas what's missing and or how to do this a better way?
You can't use the MsgBox("hello") in ASP.NET as you use it in windows forms application. Can you try by removing it?
ASP.Net with VB.NET as Code-behind usualy does not use the OnClick attribute on Buttons. Instead you need to add the Handles-clause with the button's name in your VB.Net Code-behind code. Like this:
Protected Sub btnYES_Click(sender As Object, e As EventArgs) Handles btnYES.Click
MsgBox("hello")
.... actual code
End Sub
Please also look at this page: How to use OnClick and OnClientClick events to Prevent Double Clicking on your ASP.Net Buttons.
Ok, I finally found the answer to this problem. For others in case they encounter the same, the problem was that the code
asp:Button ID="btnYES" runat="server" Text="Yes" OnClientClick="ShowCoverNONE(''); Hide2();" OnClick="btnYES_Click" CssClass="STD_button" />
was NOT within the Ajax ContentTemplate/updatepanel:
</ContentTemplate>
</asp:UpdatePanel>
Once I put it there, it all worked as normal.

ImageButton not firing

I have the following button:
<asp:ImageButton ID="imgbtnEditInfo" runat="server" ImageUrl="~/images/EditInformation.png" AlternateText="EditInformation" CommandName="EditDetails" CommandArgument="<%# Container.DataItemIndex %>" OnClick="lnkEdit_Click" Enabled="true" />
I have the following method but looks like it is not hitting the method:
Protected Sub lnkEdit_Click(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub
Wondering if I am missing something. I put a breakpoint on the Protected Sub lnkEdit_Click but on click of the imagebutton I do not go there.
You're working with Data Controls (GridView or DataList etc). To respond to the button/linkbutton/imagebutton events, you must have to handle the parent - data control's events.
Without seeing more of your page it is hard to say. A couple things to check:
Is the ImageButton inside a <form runat="server">?
Have you compared your page to the VB sample at ImageButton Class to see if anything might have been missed?

How to determine which button caused postback

I have 2 button controls. When I click one i'm trying to determine which one caused a postback in the page load. How to do determine this?
What about using CommandName and CommandArgument has shown in this example. This way you can have just one handler.
<asp:Button id="Button1"
Text="Sort Ascending"
CommandName="Sort"
CommandArgument="Ascending"
OnCommand="CommandBtn_Click"
runat="server"/>
<asp:Button id="Button2"
Text="Sort Descending"
CommandName="Sort"
CommandArgument="Descending"
OnCommand="CommandBtn_Click"
runat="server"/>
Do you come from a Classic ASP background? When I first used ASP.NET, the same question occurred to me.
Consider an alternative approach:
Rather than detect the postback in the Form_Load, and then figure out what triggered it, create a specific event handler for each of your buttons. This is the whole point of Web Forms - so you can develop apps in very similar ways as you would Windows applications.
Really input with type button sends its value within post request. For example if you have you'll get in Post button-name=Quote like it's simple text input. So you can just check if post contains value for the button using code like following (sorry for my vb):
Dim isQuote As Boolean = HttpContext.Current.Request.Form(SubmitQuote.UniqueID) IsNot Nothing
so if it's not Nothing (null) then post has been sent by SubmitQuote button.
BTW for me HttpContext.Current.Request("__EVENTTARGET") didn't work either.
In my implementation there are several forms on my page; if a post-back was triggered by certain button controls further operations are necessary.
The controls are of the following type, which do not populate Request["__EVENTTARGET"]
Button (at the root of the form)
Image Button (nested within a Datagrid)
I determine if the following button controls instigated the post-back, by reviewing that the UniqueID of the control was passed to the form request within the Page_Load sub:
- ASP.NET:
<asp:Button ID="Button1" runat="server" />
<asp:Button ID="Button2" runat="server" />
To simply handle whether the following nested image button instigated the post-back I take advantage of the OnClientClick attribute which calls to a javascript function that will populate the value of a supplementary hidden field control with the UniqueID of the instigating control, then review the hidden control value similarly in the Page_Lode sub:
- ASP.NET:
<script type="text/javascript">
function SetSource(SourceID) {
var hiddenField = document.getElementById("<%=HiddenField1.ClientID%>");
hiddenField.value = SourceID;
}
</script>
<asp:HiddenField ID="HiddenField1" runat="server" Value="" />
<asp:ImageButton ID="ImageButton1" runat="server" OnClientClick="SetSource(this.id)" />
The Page_Load would then implement by some means:
-VB.NET
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
' ...
If Not Page.IsPostBack Then
If Not String.IsNullOrEmpty(Me.Page.Request.Form(Button1.UniqueID)) Then
' ...
ElseIf Not String.IsNullOrEmpty(Me.Page.Request.Form(Button2.UniqueID)) Then
' ...
ElseIf Not Me.Page.Request.Form(HiddenField1.UniqueID) Is Nothing _
And Not String.IsNullOrEmpty(Me.Page.Request.Form(HiddenField1.UniqueID)) Then
' ...
HiddenField1.Value = String.Empty
Else
' ...
End If
End If
End Sub
on page load check this
String ButtonID = Request["__EVENTTARGET"];

Cancel a cross-page postback?

I have a page that has several ListBoxes that have some cascading filtering based on the selected values using an AutoPostBack. The form takes all the selected values and generates an excel doc by cross-page posting to a different ASPX. The problem is, after clicking submit once, it will continually fire the cross-page postback every time a selection has changed.
<asp:ScriptManager runat="server" />
<asp:UpdatePanel UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:ListBox ID="ParentItems" runat="server" SelectionMode="Multiple" AutoPostBack="true"></asp:ListBox>
<asp:ListBox ID="ChildItems" runat="server" SelectionMode="Multiple" AutoPostBack="true"></asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="Submit" runat="server" PostBackUrl="~/AnotherPageThatGeneratesAnExcelDoc.aspx" />
How do I cancel the cross-page postback from the ListBoxes' SelectedIndexChanged events?
Here's the event in the codebehind:
Protected Sub ParentItems_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ParentItems.SelectedIndexChanged
'' do some filtering of the ChildItems ListBox
'' tried these but they do not work
''Submit.Enabled = False
''Submit.PostBackUrl = String.Empty
'' I also tried wrapping the button in a PlaceHolder and hiding/removing it, neither worked
''Buttons.Visible = False
''Buttons.Controls.Remove(Submit)
End Sub
This is my current solution using javascript. It works, but seems like a hack:
// using jQuery, add a click event that resets the form action
$("select[multiple]").click(function () {
this.form.action = this.form._initialAction;
});
Edit: adding a click event in the codebehind:
ParentItems.Attributes("onclick") = "this.form.action = this.form._initialAction;"
The problem is that using the PostbackUrl property resets the form action to a new URL, and your Ajax calls (or any subsequent postbacks) use whatever the current action of the form is.
Your solution doesn't work because the submit button isn't part of your UpdatePanel, so it never gets modified.
The easiest solution might be to move your Excel file generating code out of the page it's in, and into the page you're looking at, in the click handler of the button.
You also could probably include an iframe on the page you're looking at, and on submit, rather than going to a new page, set the source of the iframe to the Excel-generating page.
Both of these would avoid the need for using the PostbackUrl.

Resources