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.
Related
When I change the selection of my dropdown, the Change event does not fire. I put a breakpoint in the method and the program does not stop.
This is my markup:
<form id="form1" runat="server">
<div style='text-align:center;'>
<a style='text-decoration:none;font-size:16px;color:blue;background-color:white;width:200px;padding:4px;' href='LocationDetails.aspx?Location_ID=0' target='detailPanel'> Add Location
</a></div>
 
<div style='text-align:left;'>
<asp:Label ID="FacilityTypeLbl" runat="server">Facility Type:</asp:Label>
<asp:DropDownList ID="FacilityTypeDDL" runat="server" AutoPostBack="true" EnableViewState="true" OnSelectedIndexChanged="FacilityTypeDDL_SelectedIndexChanged">
</asp:DropDownList>
</div>
<hr/>
<%ListLocations()%>
</form>
This is my Page_Load method to populate the list and it works fine.
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
GetServiceTypes()
FacilityTypeDDL.DataSource = dtServiceTypes
FacilityTypeDDL.DataTextField = dtServiceTypes.Columns("Title").ToString()
FacilityTypeDDL.DataValueField = dtServiceTypes.Columns("ID").ToString()
FacilityTypeDDL.DataBind()
End If
End Sub
This is my change event:
Protected Sub FacilityTypeDDL_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles FacilityTypeDDL.SelectedIndexChanged
strFacilityValue = FacilityTypeDDL.SelectedValue
ListLocations()
End Sub
I put a breakpoint at the first line of code and after changing the dropdown selection it does not stop at this event.
What am I doing wrong?
UPDATE
This is my entire markup. Can there be something wrong this it?
<%# Page Language="VB" AutoEventWireup="true" CodeFile="Locations.aspx.vb" Inherits="Editor_Locations" %>
<!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="LocationHead" runat="server">
<title>Locations</title>
<meta http-equiv="Content-Language" content="en-us"/>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
</head>
<body>
<form id="form1" runat="server">
<div style='text-align:left;'>
<asp:Label ID="FacilityTypeLbl" runat="server">Facility Type:</asp:Label>
<asp:DropDownList ID="FacilityTypeDDL" runat="server" AutoPostBack="true" EnableViewState="true" OnSelectedIndexChanged="FacilityTypeDDL_SelectedIndexChanged">
<asp:ListItem>Test1</asp:ListItem>
<asp:ListItem>test2</asp:ListItem>
<asp:ListItem>Test34</asp:ListItem>
</asp:DropDownList>
</div>
<hr/>
</form>
</body>
</html>
UPDATE
This application is a web site, not a web application. (I didn't know there was a difference but now I do.) In trying to figure out way the SelectedIndexChange event will not fire, I added a button and a click event. When I change the selection in the dropdown list, no event fires. When I click the button, the click event fires, then the selectedindexchange event fires.
I don't think the event SelectedIndexChanged is going to work.
Is there any other way to wire up a Postback when the dropdown list changes?
Can I somehow use __doPostback from a javascript function call when the list changes?
Any suggestions would be greatly appreciated!
I could not get the asp:DropdownList to fire the SelectedIndexChanged event. So this is how I completed the task.
Adding the dropdown dynamically as shown above and adding the change event that calls a javascript:
onchange='UpdateLocationList()'
This function had to be put in a .js file. This web site had a .js file already. It also had some AJAX calls that I used to complete the task.
In the UpdateLocationList(), I get the ID of the service type that was set as a value attribute in the dropdown. Then I use a function that is already part of the .js file to the LocationDetails page using the Service Type ID to display only the facilities of that service type. This is the function:
function updateLocationList() {
var ddlFacilityType = document.getElementById("FacilityTypeDDL");
var facilityValue = ddlFacilityType.options[ddlFacilityType.selectedIndex].value;
processAjax("/editor/Locations.aspx?Location_ID=" + facilityValue, "navPanel");
}
Works like a charm.
Thanks for all of your help.
I create a chart, and save it in the path server.mappath("/images/chart/chartname.png"), and if I go to the path, the image is there, and I can open it on my computer, but what I would really like to do is display the image on the page after I create it, preferably asynchronously. I've tried putting a asp:image control in the update panel and changing the url, but that doesn't work. I've tried a bunch of different ways, if someone could point me to the right direction, that would be great. I won't post any code simple because what I have so far IS working. Once I start attempting to print the image I'll post snippets if I have answers.
Edit: Here is some code
The button event that starts the whole thing:
Protected Sub btnCreate_Click(sender As Object, e As EventArgs) Handles btnCreate.Click
Dim worker As New backgroundWorker
'Check input
worker.RunWorker({})
Session("worker") = worker
Timer1.Enabled = True
End Sub
This starts the worker, which generates the chart fine, and starts the timer which is used to update the panel. Eventually in that code, this happens
Dim imgpath As String = Server.MapPath("images/chart/test.png")
chart.SaveImage(imgpath, ChartImageFormat.Png)
chartImg.ImageUrl = "~/images/chart/test.png"
Now, I know that the panel is being updated after this code is executed, because I output some messages to a multiline textbox, and they do appear. All these controls are also in the contentTemplate of the updatePanel.
Setting the ImageUrl property of an ASP.Net image control, while within and update panel, should do the trick without having to use Javascript, although that method can be very efficient. UpdatePanels tend to be "heavy", that is the ScriptManager, UpdatePanel, and ASP.Net ViewState tend to send a lot of information back and forth via their AJAX methods. You can see what I mean by using Fiddler to watch your web traffic.
That being said, I was able to achieve the desired effect in the following manner. I have two static images, Image1.jpg and Image2.jpg, but it should work with your dynamically generated image, as long as the URL is correct.
Here's the text of my ASPX page:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Image ID="Image1" runat="server" ImageUrl="~/Image1.jpg" Width="300"></asp:Image><br />
<asp:Button runat="server" ID="btnSwitchImage" Text="Switch" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
And here is the code-behind:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load( object sender, EventArgs e )
{
btnSwitchImage.Click += new EventHandler( btnSwitchImage_Click );
}
void btnSwitchImage_Click( object sender, EventArgs e )
{
Image1.ImageUrl = "~/Image2.jpg";
}
}
As long as the button and image controls are within the UpdatePanel's ContentTemplate everything should be relayed via AJAX. Once again, use Fiddler to confirm this.
If this example works for you but you still can't get your application working try posting some code in your question. It might help everyone analyze the problem directly.
As per my experience uploading of files does not work in asynchronous mode.You should use Jquery library to upload file asynchronously.
Check this link.
http://www.9lessons.info/2011/08/ajax-image-upload-without-refreshing.html
I do not know ajax but you can do it with the help of javascript. Here is the code I tested on my system which works fine.
<body>
<p>
welcome to judge site</p>
<form id="form1" runat="server">
<script language="javascript" type="text/javascript">
function PrintImage()
{
printWindow = window.open ("", "mywindow","location=1,status=1,scrollbars=1,width=600,height=600");
printWindow.document.write("<div style='width:100%;'>");
printWindow.document.write("<img id='img' src='" + document.getElementById('iconId').src + "'/>");
printWindow.document.write("</div>");
printWindow.document.close();
printWindow.print();
}
</script>
<div>
<img id="iconId" alt="photo" src="iconId.png" style="width: 500px; height: 360px" /><br />
<input type="button" id="btnPrint" value="Print Image" onclick="PrintImage()" />
</div>
</form>
There are other more examples you can find on following link (Above code is also from this source but edited by me to make it work on my system)
Visit http://forums.asp.net/p/1463001/3369521.aspx
First off, I know that what I am doing here seems entirely impractical and not good design, but I am trying to increase performance in this ASPX that contains 8,000+ lines of markup. Because of the complexity of this page (not to mention messiness) and short deadline, rewriting it to use clientside binding with AJAX/JSON is just not an option, so I have to continue to use serverside binding.
The page I am working on contains around 13 individual sections, each one loading its own entity from the database. Right now, the page initially loads ALL entities synchronously, so you can imagine that this page can sometimes take 5 seconds or longer to load. My goal here is to employ a quick fix that will load these sections only when the section is expanded so that we load only the sections that are requested by the user, thus increasing performance and conserving database resources.
The sample code below should be easy to paste right into a VB.NET WebForm if you're interested in trying this out for yourself. Just name the page asyncupdatepanels.aspx.
The problem:
Overall, my solution is working fairly well. In cmUpdate_Click, I use Threading.Thread.Sleep(2000) to simulate a call to the database to retrieve data. When you click one of the buttons, it pauses for 2 seconds and then sets the appropriate Panel's .Visible property to True.
The issue occurs when you click one button and then click the the other before the first one is finished updating. For example, if you click Show Panel 1 then quickly click Show Panel 2, only Panel 2 shows even though both button clicks are triggered in the codebehind.
Maybe asynchronous UpdatePanel is the wrong term to use here. Regardless, I need to find a way to show the panels as if they were executed in separate asyncronous threads. I want to be able to click these buttons pretty much near the same time and have both panels show.
If anyone has any other solutions to my problem that will not require major changes to the way I bind controls in each section, I'd love to hear it. The method I am using now is pretty much a hack, but it will work for now until we eventually rewrite this whole thing in MVC/c#.
Edit: The production code doesn't actually call a Javascript function by use of a button's OnClientClick. Instead, it uses a jQuery accordion. I just wanted to keep the sample code simple. For now, focus on __doPostBack("<%=cmUpdate.ClientID %>", ButtonId); regardless of how it's ultimately called.
ASPX
<%# Page Language="vb" AutoEventWireup="false" EnableEventValidation="false" CodeBehind="asyncupdatepanels.aspx.vb" Inherits="JsonJqueryDevex.asyncupdatepanels" %>
<!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 runat="server">
<title></title>
<script language="javascript" type="text/javascript">
function UpdateIt(ButtonId) {
__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
return false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:Button ID="cmShow1" Text="Show Panel 1" ClientIDMode="Static" OnClientClick="javascript:return UpdateIt(this.id);" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl1" Visible="false" runat="server">
Panel 1 content
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="cmShow2" Text="Show Panel 2" ClientIDMode="Static" OnClientClick="javascript:return UpdateIt(this.id);" runat="server" />
<asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl2" Visible="false" runat="server">
Panel 2 content
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<div style="display: none">
<asp:UpdatePanel UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Button ID="cmUpdate" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</form>
</body>
</html>
Codebehind:
Public Class asyncupdatepanels
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub cmUpdate_Click(sender As Object, e As System.EventArgs) Handles cmUpdate.Click
Dim Param As String = Request("__EVENTARGUMENT")
Threading.Thread.Sleep(2000)
Select Case Param
Case "cmShow1"
pnl1.Visible = True
Case "cmShow2"
pnl2.Visible = True
End Select
End Sub
End Class
How about disabling the appropriate buttons on click?
Say,
function UpdateIt(ButtonId) {
$('#<%=cmShow1.ClientID %>').attr('disabled', true);
$('#<%=cmShow2.ClientID %>').attr('disabled', true);
__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
return false;
}
Then, in your code behind, after the sleep, enable them again (cmShow1.Enabled = true / cmShow2.Enabled = true) - the UpdatePanel call will handle the rest.
I would do an AJAX call to your server-side in the page_load event of the page where your updated panel is. You would then call the Update method of your update panel when your processing is done.
You won't have to wait for the processing to be done to do whatever you want to do meanwhile.
Javascript(with jQuery):
function ajaxCall() {
$.ajax({
url: "YourPage.aspx"
});
}
You can process your AJAX call in the Page_Load in your .NET.
I know that you said using AJAX wouldn't be a good option, but this is fairly short and simple.
I have a simple aspx file
<%# Page Language="VB" AutoEventWireup="false" CodeFile="test4.aspx.vb" Inherits="test4" %>
<!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">
<body>
<form id="form1" runat="server">
<div id="content">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</div>
</form>
</body>
</html>
And this is the test4.aspx.vb code file
Partial Class test4
Inherits System.Web.UI.Page
Protected Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
TextBox2.Text = TextBox1.Text
End Sub
End Class
Now the problem is that even if i type something in the textBox1 the textchanged event if not firing why??. What should i do??
You need to enable AutoPostBack on the TextBox that results in the event.
The problem with your code is it's a server-side event trying to invoke a client-side event. The text needs to be entered in TextBox1 and then it will result in the AutoPostBack.
<asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True"></asp:TextBox>
Based on your need though. It may be better to populate the TextBox2 with the value from TextBox1 using JavaScript.
Your TextBox is a server control, and text changed is a server event. It is not meant to be fired each time you type a letter, rather it is fired if the text value is different from the value at the time of the last server post back.
If you need to run some kind of code each time a letter is pressed you will need to register and handle the client-side events OnKeyUp / OnKeyDown / OnKeyPress with VB or JavaScripting.
On your .Aspx, add on your TextBox:
OnTextChanged="TextBox1_TextChanged"
I know I'm late to the party with this one, but I still wanted to tell my story.
I had a text changed event handler on a read-only TextBox.
JavaScript changed the TextBox to read/write, but the event wouldn't fire. Probably because the back-end still thought it was read-only.
I fixed the issue by moving all changes between R/O and R/W to the back-end. Now it works.
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.