Validator causes improper behavior for double click check - asp.net

I have following script to prevent a button from submitting twice by double clicking. It works fine.
But the scenario gets clumsy when I added a Required Field validator. If I try to submit with a blank value in textbox, the validator fires. But when I entered value in textbox and try to submit again it does not do a postback.
I understand the reason, in the first button click itself, the variable isActionInProgress is set as 'Yes' irrespective of the validation error.
What is the best way to overcome this challenge?
MARK UP
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.8.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var isActionInProgress = 'No';
$('.myButton').click(function (e) {
if (isActionInProgress == 'No') {
isActionInProgress = 'Yes';
}
else {
e.preventDefault();
//alert('STOP');
}
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtEmpName" runat="server"></asp:TextBox>
<asp:Button ID="Button1" CssClass="myButton" runat="server" Text="Submit" ValidationGroup="ButtonClick"
OnClick="Button1_Click" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="txtEmpName"
runat="server" ErrorMessage="RequiredFieldValidator" ValidationGroup="ButtonClick" Text="*"></asp:RequiredFieldValidator>
</div>
</form>
</body>
REFERENCES
Page_ClientValidate is validating multiple times.
Hide redundant error message in ASP.Net ValidationSummary
MSDN - ASP.NET Validation in Depth

I think somthin like this:
$('.myButton').click(function (e) {
if(Page_IsValid){
if (isActionInProgress == 'No') {
isActionInProgress = 'Yes';
}
else {
e.preventDefault();
//alert('STOP');
}
}
});

Related

javascript in asp.net

<asp:RadioButtonList ID="RdoBtnHasNotified" runat="server" RepeatDirection="Horizontal" AutoPostBack="True" OnSelectedIndexChanged="RdoBtnHasNotified_SelectedIndexChanged">
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0" Selected="True">No</asp:ListItem>
</asp:RadioButtonList>
<asp:TextBox ID="TxtHowNotified" runat="server" TextMode="MultiLine" MaxLength="100"></asp:TextBox>
I want to enable the TextBox by clicking on the RadioButtonList, without using autopostback=true. How can I do this with JavaScript?
You can use jQuery to manipulate input's enabled state (HTML translation for TextBox) or you can use ASP.NET Ajax so you can set both controls inside of update panel in this case you won't see page being reloaded on postback which must happen in order for you to change status of TextBox on some other event.
Tbh i would go with ASP.NET Ajax because my experience shows that jQuery does not work that well with ASP.NET controls when it comes to complex stuff ie. ASP.NET uses javascript for event activation which can cause either jQuery or ASP.NET not to work as you may expected.
Good luck with update panels...
Using jQuery, you can have a fairly custom result by hooking in to the changes on the radio buttons...
$("#<%= RdoBtnHasNotified.ClientID %> > input[type=radio]").change(function(){
// this function is called whenever one of the radio button list's control's change
// the $(this) variable refers to the input control that triggered the event
var txt = $("#<%= TxtHowNotified.ClientID %>");
if($(this).val()=="1") {
txt.removeAttr("disabled");
} else {
txt.attr("disabled", true);
}
});
Each ListItem renders a radio button with the same name parameter; I would suggest running the app and looking at the generated source to get an idea of what you need to do to listen for the radio button events. Essentially the ID of the radio button list is the name parameter, so you can get the group of radio buttons as (using JQuery):
$("input[name='<%= rbl.ClientID%>']").click(function() {
var tb = $("#textboxid");
//do something here; this points to the radio button
});
HTH.
Here you go:
<%# 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 RdoBtnHasNotified_PreRender(object sender, EventArgs e)
{
foreach (ListItem item in RdoBtnHasNotified.Items)
item.Attributes.Add("onclick", string.Format("toggleTextBox(this,'{0}');", TxtHowNotified.ClientID));
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
function toggleTextBox(radioButton, textBoxId) {
document.getElementById(textBoxId).disabled = radioButton.value != "1";
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:RadioButtonList ID="RdoBtnHasNotified" OnPreRender="RdoBtnHasNotified_PreRender"
runat="server" RepeatDirection="Horizontal">
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0" Selected="True">No</asp:ListItem>
</asp:RadioButtonList>
<asp:TextBox ID="TxtHowNotified" runat="server" TextMode="MultiLine" MaxLength="100" Enabled="false"></asp:TextBox>
</div>
</form>
</body>
</html>
Write the code in the following way
<script type="text/javascript">
$(document).ready(function() {
$("input[name='RdoBtnHasNotified']").change(function() {
$("input[name='RdoBtnHasNotified']:checked").val() == '1' ? $('#TxtHowNotified').removeAttr("disabled") : $('#TxtHowNotified').attr('disabled', 'true');
});
});
</script>
and also disable the textbox (Enabled="false") since initialy the value of the "RdoBtnHasNotified" is "No".
$('#<%= RdoBtnHasNotified.ClientID %> > input[type=radio]').click(function()
{
var txtbox = $('#<%= TxtHowNotified.ClientID %>');
if($(this).val() == '1')
{
document.getElementById('#<%= TxtHowNotified.ClientID %>').disabled = false;
}
else
{
document.getElementById('#<%= TxtHowNotified.ClientID %>').disabled = true;
}
});
I think using change event will not fire in IE.

Prevent ASP.net __doPostback() from jQuery submit() within UpdatePanel

I'm trying to stop postback on form submit if my custom jQuery validation returns false.
Is there any way to prevent the __doPostback() function finishing from within the submit() function?
I'd assumed:
$('#aspnetForm').submit(function () { return false; });
would do the trick, but apparently that's not the case: does anyone have a suggestion?
The submit() function does block the postback (it won't postback if you pause at a breakpoint in firebug), but I can't seem to stop the event happening after the submit() function is complete!
Cheers, Ed
EDIT
OK, I had a quick mess about and discovered that the fact that the button I'm using to cause the postback is tied to an updatepanel as an asyncpostbacktrigger seems to be the problem: If I remove it as a trigger (i.e. cause it to product a full postback), the is no problem preventing the postback with return false;
Any ideas why the async postback would not be stoppable using return false?
You have to use the client side PageRequestManager to properly handle AJAX submit events. (e.g. prevent an async postback.)
If you are not in total control of the page, there can be JavaScript on the page that just calls __doPostBack() without going through any page logic.
In this case - in addition to the above -, you have to store the old window.__doPostBack() and provide your own - as #tucaz mentioned in his comments.
(...and as you mentioned, it can get quite perplexing with chaining.)
For regular submits (non-AJAX), you can provide an event handler as others have pointed out.
This page might be of help and has some code samples that use PageRequestManager. In particular:
initialize : function()
{
...
this._onSubmitHandler = Function.createDelegate(this, this._onSubmit);
this._onPartialUpdateEnd = Function.createDelegate(this, this._onUpdateEnd);
if (typeof(Sys.WebForms)!== "undefined" && typeof(Sys.WebForms.PageRequestManager)!== "undefined")
{
Array.add(Sys.WebForms.PageRequestManager.getInstance()._onSubmitStatements, this._onSubmitHandler);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(this._onPartialUpdateEnd);
}
else
$addHandler(document.forms[0], "submit", this._onSubmitHandler);
},
Edit:
Following the above, this, for example works fine for me (.Net 3.5 SP1, Button1 is trigger in the updatepanel, etc...):
<%# 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>
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.js" charset="utf-8"
type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
</asp:UpdatePanel>
</form>
<script type="text/javascript">
(function($, undefined) {
var submitHandler = function(e) {
return false;
}
if (typeof (Sys.WebForms) !== "undefined" && typeof (Sys.WebForms.PageRequestManager) !== "undefined") {
Array.add(Sys.WebForms.PageRequestManager.getInstance()._onSubmitStatements, submitHandler);
} else {
$("form").submit(submitHandler);
}
})(jQuery);
</script>
</body>
</html>
$('#yourPostButton').click(function(){
return false;
});
This should do!

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 Checkbox value at postback is wrong?

We have a checkbox that is initially disabled and checked. It is then enabled on the client side through javascript. If the user then unchecks the box and presses the button to invoke a postback, the state of the checkbox remains as checked on the server side. This is obviously undesirable behaviour. Here is an example.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="testcb.aspx.cs" Inherits="ESC.testcb" %>
<!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>
</head>
<body>
<form id="form1" runat="server">
<script type="text/javascript">
function buttonClick() {
var cb = document.getElementById('<%= CheckBox1.ClientID %>');
cb.disabled = false;
cb.parentNode.disabled = false;
}
</script>
<div>
<asp:CheckBox ID="CheckBox1" runat="server" Checked="true" Enabled="false" />
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="buttonClick(); return false;" />
<asp:Button ID="Button2" runat="server" Text="Button2" OnClick="button2Click" />
</div>
</form>
</body>
</html>
And the Server-side code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ESC
{
public partial class testcb : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void button2Click(object sender, EventArgs e)
{
string h = "";
}
}
}
So we break at the "string h" line and check the value of CheckBox1.Checked. It is true, even if it is unchecked on the form.
This is a known problem with ASP.NET - for some reason ASP.NET won't update a checkbox on postback if it was disabled during page load and not checked for postback. I don't know exactly why that is though - if you make the checkbox unselected by default and select it, the value is changed on the server correctly.
The workaround is to add a hidden field to the page that represents the state of the checkbox, then update the field's value to "ON" or "OFF" for example, whenever the checkbox is clicked.
Then on the server you check the value of the hidden field, not the checkbox itself, as the hidden field is always posted.
I had a similar problem to this where the Checked property of the CheckBox object was not being updated correctly, to get the actual posted value you can check:
Request.Form[CheckBox1.UniqueID]
it will be 'on' if the box is checked and null if not.
Since you're already using Javascript to manipulate the controls state in the browser, I suggest you just disable the checkbox on the page load event in stead. Then your postbacks will work just fine...
<head>
<script type="text/javascript">
function buttonClick() {
var cb = document.getElementById('<%= CheckBox1.ClientID %>');
cb.disabled = false;
cb.parentNode.disabled = false;
}
</script>
</head>
<body onload="document.getElementById('<%= CheckBox1.ClientID %>').disabled = true;">
<form id="form1" runat="server">
<div>
<asp:checkbox id="CheckBox1" runat="server" checked="true" />
<asp:button id="Button1" runat="server" text="Button" onclientclick="buttonClick(); return false;" />
<asp:button id="Button2" runat="server" text="Button2" onclick="button2Click" />
</div>
</form>
</body>
I may not understand the problem correctly, but can't you just use the Form from the Request to retrieve the CheckBox value? So in button2Click() in the code behind file you'd do this:
Request.Form[CheckBox1.UniqueID]
You can use something like this.
if ((Request.Params["Checkbox1"] ?? "").ToString() == "on")
If it isn't checked it won't pass it in the first place, but this should account for that.
Here is an alternative solution if you need to avoid recompiling your source code.
It just enables the checkbox for a split second before submitting the form.
1: Add the following parameter to your submit button:OnClientClick="EnableCheckbox()"
2: Add this simple function somewhere on the page to enable it
<script>
function EnableCheckbox() {
document.getElementById("<%=chkMyCheckbox.clientID %>").disabled = false;
}
</script>

jQuery's $() function always returns 'undefined' with AJAX

i've noticed that popup shows BEFORE text gets updated in the textbox, i guess js gets called before the page gets rendered ... that would explain the 'undefined' popup ... how do i make sure js gets called AFTER the page is rendered?
rewriting to make it as simple as possible:
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtRcaNotes" runat="server" TextMode="MultiLine" Width="800px"></asp:TextBox><br />
<asp:Button ID="btnDoneWithRcs" runat="server" OnClick="btnDoneWithRcs_Click" Text="Action Completed / Update Notes" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(
function(){doStuff();}
);
function doStuff()
{
$(document).ready(function() {
$('txtRcaNotes').hide();
alert($('txtRcaNotes').attr('id'));
});
}
</script>
</body>
Code Behind:
protected void btnDoneWithRcs_Click(object sender, EventArgs e)
{
txtRcaNotes.Text += "asdfadf";
}
TEXTBOX DOESN'T GET HIDDEN, ALERT() RETURNS 'UNDEFINED'
You're just missing your id selector syntax. Try:
$('#<%= txtRcaNotes.ClientID %>').hide();
alert($('#<%= txtRcaNotes.ClientID %>').attr('id'));
Note the addition "#" prepended before each selector.
One thing you could try is using Firebug, or some other DOM inspector and check the actual element IDs that are being generated by ASP.NET before and after your AJAX call and see if they are the same.

Resources