asp:DropdownList not firing for SelectedIndexChanged event - asp.net

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>
&nbsp
<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.

Related

intercept __doPostBack function

According to this post you can intercept the post by overriding this function __doPostBack but it wont work. If I view the generated source I am not able to see the function that is meant to be auto generated and causes asp.net to make the postback.
where is this function? and how do I intercept it?
I'm using asp.net 4 and vs 2012
Default.aspx
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script>
//breaks here as it cant find __doPostBack
var __original = __doPostBack;
__doPostBack = myFunction();
function myFunction() {
alert('intercept');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" ></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
</body>
</html>
Default.aspx.vb
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim txt As String = TextBox1.Text
End Sub
End Class
An ASP.NET Button renders an <input type="submit" /> to postback the form, and will never use this method. The __doPostBack method is only used for elements that are not input buttons that do not normally cause a POST operation to the server. This is a function that's inside one of the Microsoft's JavaScript file, and only gets rendered out on the client. Common uses for __doPostBack are LinkButton controls, controls that may have AutoPostBack="true", and others.
Also, there may be a call to WebForms_DoPostBack... something named like that that also posts back, but internally calls __doPostBack.
If you are trying to prevent postback on click of your button, attach to the submit event of the form, and cancel the postback operation that way.

ASP.NET WebForms: Asynchronous UpdatePanel?

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.

TextChanged event function not working

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.

ASP.NET/HTML input button value on postback

According to the info in:
Which values browser collects as a postback data?
the value of the HTML input button is sent in a post back. I'm testing in ASP.NET with IE and I am not finding this to be the case.
The markup for my test case is:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Test.aspx.vb" Inherits="Test" %>
<!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>test postback</title>
<script type="text/javascript">
function doTest() {
var button = document.getElementById("btnTest");
button.value = "new-value";
alert("button contents = " + button.value);
return true;
}
</script>
</head>
<body>
<form id="myForm" runat="server">
<div>
<asp:Panel ID="pnlTest" runat="server"
DefaultButton="btnTest">
Textbox:
<asp:TextBox ID="txtTest" runat="server" />
<asp:Button ID="btnTest" runat="server"
Text="change" OnClientClick="doTest()" />
</asp:Panel>
</div>
</form>
The code behind is:
Partial Class Test
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
txtTest.Text = btnTest.Text
End Sub
End Class
My result is that the value of the input button is always "change" when the browser loads the page, but I was expecting it to be "new-value" after postback. The Javascript doTest() function is changing the value when the button is clicked.
Is there something more I'm supposed to do for ASP.NET or IE to get the input button value posted back? Or is the information about this functionality
wrong?
In a case like this I would probably use:
<input type="button" ID="btnTest" runat="server" onclick="doTest()" value="change" />
Note the runat="server".
While asp:button probably renders similarly, if what you really want it an HTML button input, you can use that. Yes, ASP.NET will pick up the value on the server side.
Also, do a view source and make sure the ASP.NET panel is not munging up the ID of the input. More generally, have you tested this without the asp:panel tag? I wonder if that affects anything.
I believe IE just hates input submits....
But you should also know...
ASP uses viewstate to ensure there is no tampering with server controls. The value of the submit button is stored in the view state and most likely the only way to modify the value of it is to use the ASP.NET JS API.
More commonly you see this problem with <selects> (Options added to by javascript lost in postback), but <input type="submit" /> is very similar
It's not that it's not being set, but the javascript sets the value, which gets reset back to "change" on the postback. If you're looking for a button that works with your javascript, use the client input control:
<input type="button" ID="btnTest" onclick="doTest()" />
Otherwise, if you want a server control, you should set btnTest.Text on the server side.
You are using the wrong id for the button. ASP.NET gives each control a unique id. It is made up of all the ids in the chain to your control.
Therefore your button probably has an id something like ctl00_pnlTest_btnTest. This is why your JavaScript is not setting the buttons text.
view source in your browser to see the actual ID of the control and adjust your JavaScript accordingly.
From code you can get the actual ID used in the page with the ClientID property. So you could change your JavaScript to:
var button = document.getElementById("<%= btnTest.ClientID %>");
Just tried Marc's solution like this:
<script type="text/javascript">
function doTest() {
var button = document.getElementById("btnTest1");
button.value = "new-value";
alert("button contents = " + button.value);
return true;
}
</script>
<input type="submit" id="btnTest1" name="btnTest1" value="Submit 1" runat="server" onclick="doTest()" />
When I posted back the Load event still had Submit 1 as the value of the button. You could use a hidden field, set that value with the button in JS and post back. That does in fact work.
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>test postback</title>
<script type="text/javascript">
function doTest() {
var button = document.getElementById("btnTest1");
button.value = "new-value";
alert("button contents = " + button.value);
var hdn = document.getElementById("hdnTextboxName");
hdn.value = button.value;
return true;
}
</script>
</head>
<body>
<form id="myForm" runat="server">
<div>
<asp:Panel ID="pnlTest" runat="server" DefaultButton="btnTest">
Textbox:
<asp:TextBox ID="txtTest" runat="server" /><asp:HiddenField ID="hdnTextboxName" runat="server" ClientIDMode="Static" />
<asp:Button ID="btnTest" runat="server" Text="change" OnClientClick="doTest()" ClientIDMode="Static" />
</asp:Panel>
</div>
</form>
</body>
</html>
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
txtTest.Text = hdnTextboxName.Value
End Sub

asp.net dropdown list postback to anchor

How can I go to an anchor tag on the page when the myDropDownList_SelectedIndexChanged() event fires?
I am using regular ASP.NET Forms.
Update: The following is valid for an ASP.NET Button. I would like to achieve the same functionality (going to #someAnchor) when I select an option from the Dropdown list.
<asp:Button ID="btnSubmit" runat="server" Text="Do IT" Width="186px" PostBackUrl="#myAnchor" CausesValidation="false" />
Update: I will try to further explain details that I didn't cover in enough detail initially.
This is a long page and in the middle of the page there is a dropdown list. Below the dropdown list is a label that will change based on the item selected from the dropdown. The update of the label will occur during the postback. At this point the page needs to remain focused on the dropdown. I tried to use AJAX to accomplish this, but other implementation details prevent that from working. The ability to go to an anchor tag after the postback would be a simple solution. Here is a simplified version of what I am trying to accomplish.
<%# Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub myDropDown_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
myLabel.Text = myDropDown.SelectedValue
'When this finishes, go to #myAnchor
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Imagine many lines of text here.
<a name="myAnchor"></a>
<asp:DropDownList ID="myDropDown" runat="server" OnSelectedIndexChanged="myDropDown_SelectedIndexChanged" asdf="asdf" PostBackUrl="#myAnchor"></asp:DropDownList>
<asp:Label ID="myLabel" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
This could do the trick
<asp:DropDownList ID="DropDownList1" runat="server"
onchange="document.location= this.value">
<asp:ListItem Text="Anchor" Value="#anchor"></asp:ListItem>
<asp:ListItem Text="Anchor2" Value="#anchor2"></asp:ListItem>
</asp:DropDownList>
You mention myDropDownList_SelectedIndexChanged() (server code) but you must do it on client side, unless you have a good reason to go to the server
Add this to your page load and you will be good to go.
Page.MaintainScrollPositionOnPostBack = true;
I would use JavaScript--either register the script in your codebehind, or have an asp:Literal which is only visible after the SelectedIndexChanged event. Modify the location.href to append your anchor.
One way to do this is to use the forms.Controls bla bla bla properties in ASP.NET.
however I would suggest you to use a asp.net hyperlink control or link button and this would allow you to access it directly with its ID.
thanks,
MNK.
This requirement has simple javascript solution.But the problem is the design is flawed.Once you move to a new area in screen you cant access the navigation select list without scrolling back.Anyway something like the following works
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>
<!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 type="text/javascript">
function Goto(x) {
window.location = "#"+x.value;
}
</script>
</head>
<body>
<select id="Select1" name="D1" onchange="Goto(this);">
<option value="Loc1" >go to 1 </option>
<option value="Loc2">go to 2 </option>
<option value="Loc3">go to 3 </option>
<option value="Loc4">go to 4 </option>
</select><form id="form1" runat="server">
</form>
<strong> <a href="#" id="Loc1" >Location 1</a></strong>
blah
<strong>Location 2</strong>
<strong>Location 3</strong>
<strong>Location 4</strong>
</body>
</html>
Here is what I have implemented to accomplish my desired result.
Protected Sub myDropDown_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles myDropDown.SelectedIndexChanged
Response.Redirect("Default.aspx?myDropDown=" & myDropDown.SelectedItem.Text.ToString.Trim & "#myAnchor")
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim myDropDownValue As String = Request.QueryString("myDropDown")
If myDropDownValue <> "" Then
myDropDown.Items.FindByText(myDropDownValue).Selected = True
Label1.Text = GetTextBasedOnDropDownSelection(myDropDownValue)
End If
End If
End Sub
If your dropdown list contains three items say for example:
Page1
Page2
Page3
Give the dropdownlist a property of AutoPostBack="true" and then in the dropdown OnSelectedIndexChanged method write the following:
if (DDl.SelectedIndex == 1) {
Response.Redirect("~/page1");
}
else if (DDl.SelectedIndex == 2) {
Response.Redirect("~/page2");
}

Resources