Button OnClick event not firing with one textbox in the form - asp.net

I came across a very strange occurrence with ASP.NET onclick event in IE (other browsers doesn't seem to have this problem). When there is only one textbox field in a form, the onclick event doesn't fire when you enter text and hit Enter/Return. The event does fire when you click on the actual submit button. When there are two or more fields in the form, hitting Enter/Return works just fine.
It's very strange. Thought it was something with my IE, but checked other machines, and every one of them had the same problem.
I had setup this really simple page as a test:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void btnSubmit_Click(object sender, EventArgs e)
{
Response.Write(((Button)sender).Text);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="txtBox2" runat="server" ></asp:TextBox>
<asp:Button ID="btnSubmit" OnClick="btnSubmit_Click" Text="Submit" runat="server" />
</div>
</form>
</body>
</html>
When one of the textbox is removed, the btnSubmit_Click event doesn't behave as expected.

The defaultButton property of Panel or Form is used to ensure Enter Key Submission. Typically people used to Enter Key submission and if it is disabled, it might be annoying certain times.
The defaultButton really provides a way to handle Enter Keys for respective portions of the page when the focus is there.
Source: multiple submit buttons and the enter key

Related

asp:DropdownList not firing for SelectedIndexChanged event

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.

asp:Label with nested control disappears on setting CssClass

Is it improper to nest another control within asp:Label?
When I have another control (e.g., a button) inside my asp:Label, and I try to change CssClass on the label during an event handler, the entire label seems to disappear. I'll be grateful if someone can help me find what I might be doing wrong.
Bad1.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Bad1.aspx.cs" Inherits="Bad1" %>
<!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>Badness?</title>
</head>
<body>
<form id="form1" runat="server">
<asp:CheckBox ID="CheckBox1" runat="server" Text="check and uncheck me" AutoPostBack="True" OnCheckedChanged="CheckBox1_CheckedChanged" />
<br />
<br />
<asp:Label ID="Label1" runat="server" > See me now? <asp:Button runat="server" /> </asp:Label>
</form>
</body>
</html>
Bad1.aspx.cs:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Bad1 : System.Web.UI.Page
{
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
var lab = Page.FindControl("Label1") as Label;
lab.CssClass = "foo";
}
}
Symptom: Page displays correctly at first, and after first click on "check and uncheck me". But when I click on the checkbox a second time, the label ("See me now") disappears, never to come back. If I remove the button from within the label, there's no problem. So, is the nesting what's incorrect?
I would look into using a Panel instead of a Label.
<asp:Panel ID="Panel1" runat="server" CssClass="someStyle">
<asp:Button ID="Button1" runat="server" Text="Hi"></asp:Button>
</asp:Panel>
If you're looking to style the button, then you should apply your CssClass to the button directly. Use a Panel if you're trying to apply a style to that region/block.

Page_load fires twice for UpdatePanel refresh whilst having a jQuery bound change event on a drop down list

I've tried to wrap up my problem with a complete example below - the original problem is part of a jQuery plug-in that I'm writing to extend the behaviour of an ASP.NET ajax application I already have.
The aspx page below has one drop down list which is marked for auto post back. I've also bound a change event using jquery (which ultimately I will swap for a .live() event to maintain the binding after the update panel refresh.) The problem is, when the jQuery event is bound I see two ajax begin requests and page_loads fire but only one ddlTest_OnselectedIndexChanged event. One of the page loads is malformed too - the content-length states it's about 300 bytes long whilst the totalBytes is 0 and form data empty. This does not happen if I bind to the click event of a button.
Can someone explain why the erroneous page_load event is firing please??
<%# Page Language="C#" AutoEventWireup="true" %>
<%# Import Namespace="System.Diagnostics" %>
<!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">
<script runat="server">
private void Page_Load(object sender, EventArgs e)
{
Debug.WriteLine(Request.Headers["Content-Length"]);
Debug.WriteLine(Request.TotalBytes);
Debug.WriteLine(Request.Form.ToString());
Debugger.Break();
}
private void ddlTest_OnSelectedIndexChanged(object sender, EventArgs e)
{
Debugger.Break();
}
</script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandler);
$("#<%=ddlTest.ClientID%>").change(function() { alert('jQuery binding fired'); });
});
function beginRequestHandler() {
alert("Started ajax call");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="SciptManager" runat="server" />
<asp:UpdatePanel ID="updTest" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlTest_OnSelectedIndexChanged" >
<asp:ListItem>First</asp:ListItem>
<asp:ListItem>Second</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Update : I've narrowed the problem down even further. Firefox and Chrome both work as I would expect whilst IE is having a problem. I've also simplified the erroneous code to the example below. It's hard to believe it's this simple but the jQuery .change() method on the drop down list triggers the onchange event on the select element twice! I'll look for other people who've had this problem and report back my findings!
<%# Page Language="C#" AutoEventWireup="true"%>
<!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">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#ddlTest').change(function() { alert('jQuery event fired'); });
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:DropDownList id="ddlTest" runat="server" onchange="alert('element event');">
<asp:ListItem Text="First" />
<asp:ListItem Text="Second" />
</asp:DropDownList>
</form>
</body>
</html>
The call of $("#<%=ddlTest.ClientID%>").change(... is probably trigger your drop down list and because of your autopostBack, you get an second refresh of your page.
It looks like I've uncovered a bug in the latest version of jQuery :(. If I change the test back to version 1.3.2 it works fine! I've also found a reference to a bug raised with jQuery.
Take out the autopostback=true = it is firing one postback and the change event is another.

ASP.NET TextBox OnTextChanged triggered twice in Firefox

Hi I'm facing a weird problem that only happens in FF. I have a TextBox control with OnTextChanged handler. The event handler is working fine most of the time, but when the user changed the text and press Enter in FF, the OnTextChanged event is called twice. I observed the problem in Firebug that the first request is actually canceled because of the second event.
Test.aspx
<%# Page Language="C#" AutoEventWireup="True" CodeFile="~/Test.aspx.cs" Inherits="T.Test" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Custom TextBox - OnTextChanged - C# Example</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:ScriptManager runat="server" ID="SM">
</asp:ScriptManager>
<h3>Custom TextBox - OnTextChanged - C# Example</h3>
<asp:UpdatePanel runat="server" ID="Panel1">
<ContentTemplate>
<asp:Panel runat="server" ID="Panel2">
<asp:TextBox ID="TextBox1" AutoPostBack="true" OnTextChanged="OnTextChanged" runat="server">Hello World!
</asp:TextBox>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Test.aspx.cs
using System;
using System.Web.UI;
namespace T
{
public partial class Test : Page
{
protected void OnTextChanged(object sender, EventArgs e)
{
var a = 0;
}
}
}
Put a break point # var a, and you'll be able to see that after changing text and press enter in FF (v3.5.7), the OnTextChanged event is invoked twice.
So my question is, what's the best way to properly handle OnTextChanged event so that hitting enter in the textbox doesn't trigger double postback.
Regards,
I don't know why it's isolated to FireFox, but if you remove the AutoPostBack property, that will solve the problem.
There is also an explanation here of why it's posting back twice.
I know its an old thread but maybe helpful for others.
I had the same issue when validating the text entered. I was getting 2 events fired so I put this script at the top of the page which causes the enter to just tab to the next control instead of submitting the form. The text box remained the same AutoPostBack="true" OnTextChanged="xxx_TextChanged"
''''
<script type="text/javascript">
$('body').on('keydown', 'input, select', function (e) {
if (e.key === "Enter") {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this) + 1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
</script>
''''

ASP.NET, JQUERY: How do I pick up values populated on the client AFTER the last postback?

I have a legacy system where I want to improve the user experience.
On one of the forms there are 2 drop down listboxes; the change of one ddl cascades to the next.
On the current form, this is acheived by selectedindexchanged event from which the other ddl can be repopulated.
Although this works, in order for the event to be fired, the control has to have the autopostback=true property set.
This postback creates a bad user experience.
So the simple solution is to put the ddls into an update panel control. However doing this has the odd knock on effect of disabling my JQuery Cluetip controls. I do not know why this is.
In which case it is time I finally got round to populating my controls using JQuery and/or AJAX.
So I have tried the following solution below in a test application.
However when I click on the submit button, the changes I make to the Sub Categories ddl are not being picked up in the code behind event for my button (a server side control).
The reason appears to be that the client side updates happened after the last postback, and so on the server the control still has the previous values.
How do I pick up the new values on server side, or should I try something else?
I am using a server control button because that is what the orginal legacy code does, and changing everything to client side would be a big job.
The web page;
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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>
<link href="CSS/RM.css" rel="stylesheet" type="text/css" />
<script type='text/javascript' src='http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js'></script>
<script type='text/javascript' src='Default.js'></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Test Categories</h1>
<table>
<tr>
<th class="wid3">Category:</th>
<td class="wid4"><asp:DropDownList
ID="Categories_ddl" runat="server" DataSourceID="odsCategories"
DataTextField="Category1" DataValueField="Category_ID"
>
</asp:DropDownList>
</td>
<th class="wid3">Sub Category:</th>
<td class="wid4"><select
ID="Sub_Categories_ddl" runat="server" DataSourceID="odsSub_Categories_4_Category"
DataTextField="Sub_Category1" DataValueField="Sub_Category_Id">
</select></td>
</tr>
</table>
<asp:ObjectDataSource runat="server" ID="odsCategories"
TypeName="ClassLibraryRiskManCategories.DAL" SelectMethod="GetCategories" />
<asp:ObjectDataSource runat="server" ID="odsSub_Categories_4_Category"
TypeName="ClassLibraryRiskManCategories.DAL" SelectMethod="GetSubCategories">
<SelectParameters>
<asp:ControlParameter ControlID="Categories_ddl" Name="categoryId"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
<div style="padding:100px"><asp:Button runat="server" ID="btnTest" Text="Submit"
onclick="btnTest_Click" /></div>
</div>
</form>
</body>
</html>
The JScript
$(document).ready(function() {
$("#Categories_ddl").change(function() {
$("#Sub_Categories_ddl").html("");
var CategoryId = $("#Categories_ddl > option:selected").attr("value");
if (CategoryId != 0) {
$.getJSON('LoadSubCategories.ashx?CategoryId=' + CategoryId, function(Sub_Category1) {
$.each(Sub_Category1, function() {
$("#Sub_Categories_ddl").append($("<option></option>").val(this['Sub_Category_Id'].toString()).html(this['Sub_Category1']));
});
});
}
});
});
ASP.NET cannot really be told to commit any changes to a control between postbacks unless they are performed in a fashion that it expects (such as editing a textbox). Arbitrarily changing a DropDownList's options outside of a server event is one case of a non-trackable change (at least in any reasonable sense). Fortunately, using an UpdatePanel as you were before is a viable approach and correcting the issue you described with your tooltips is actually quite straightforward.
To address the issue of your jQuery Cluetips not appearing after an UpdatePanel postback, you will need to reinitialize the plugin just after the partial refresh as it is no longer registered to elements existing in the DOM (since your the partial refresh replaced those elements). You can achieve this by wrapping the plugin initializer in a javascript method called pageLoad():
function pageLoad() {
// do some javascript here
}
Any javascript method called pageLoad() will automatically be called by ASP.NET after every full and partial page load. With this technique you will be able to restore your jQuery Cluetips after you repopulate the DropDownLists from the UpdatePanel's postback. Take a look at this excellent article on the ASP.NET AJAX Client Life-Cycle Events for more information.

Resources