ASP.NET checkbox won't postback when onclick is defined - asp.net

I intend to answer my own question here - I think this could be difficult to fathom. I have two checkboxes, the second of which has a postback, which should only fire if the first one is checked. Here's what I wrote
<asp:CheckBox ID="chkTC" runat="server" Text="I have read and accept the Terms & Conditions" /><br />
<asp:CheckBox ID="chkRegister" runat="server" AutoPostBack="true" onclick =" var bOK = document.getElementById('chkTC').checked; if (!bOK) { alert('You must agree to the Terms and Conditions'); } return bOK; " />
The onclick code is a copy the code I use if I want to determine if a button should postback.
However, there was no postback from the second checkbox, even if the first was ticked.

I found that ASP.NET doesn't have a defined 'onclick' property for checkboxes, but will pass any onclick code supplied through to the generated HTML. However, it also utilises the onclick attribute to effect the postback. The onclick code that I supplied was prepended to the code that makes the postback happen. And because I used a return statement, it was not being executed. Sorry if this is obvious - it wasn't to me.
So the fix is to only execute a return when I don't want the postback
<asp:CheckBox ID="chkRegister" runat="server" AutoPostBack="true" onclick =" var bOK = document.getElementById('chkTC').checked; if (!bOK) { alert('You must agree to the Terms and Conditions'); return false; }" />

Related

onclick event of the link button inside the reapeator control fires at the time of binding data to reapeator control

I have a Linkbutton inside a Repeater control.
My code in the aspx page :
<asp:LinkButton ID="lnkBtnOpenSuplmnt" runat="server"
Text= "OpensupLink"
OnClientClick='<%# Eval("ClaimId", "return confirm(\"Reopen the assignment for claim {0} to issue a supplement?\")" ) %>'
OnClick ='<%# lnk_OpenSupplement(Eval("ClaimId"))%>'>
</asp:LinkButton>
Then on the code behind
protected string lnk_OpenSupplement(object profileId)
{
string retStr = "success";
.........
return retStr;
}
In the page_load :
repeater.DataSource = recentAssignments;
repeater.DataBind();
The strange thing happening here is : in the Repeator's databind the lnk_OpenSupplement method gets fired, which is unwanted functionality. How can i avoid this. or can some body point out where am I going wrong.
Thanks in advance
BB
You're databinding the output of that method to the OnClick event.
Meaning, you're saying OnClick = "success", which isn't what you're expecting to happen.
<%# something %> means 'Execute something when binding this element and use the return value here'.
I'd recommend you take a look at how to bind command arguments to the ItemCommand event.
Here are some articles that describe how to do this:
http://ondotnet.com/pub/a/dotnet/2003/03/03/repeater.html
http://www.asp.net/data-access/tutorials/custom-buttons-in-the-datalist-and-repeater-vb
After hooking up the event, your button would then become:
<asp:LinkButton ID="lnkBtnOpenSuplmnt" runat="server"
Text= "OpensupLink"
OnClientClick='<%# Eval("ClaimId", "return confirm(\"Reopen the assignment for claim {0} to issue a supplement?\")" ) %>'
CommandName="MyCommand"
CommandArgument='<%# Eval("ClaimId") %>'>
</asp:LinkButton>
I think the <%# tag for the OnClick is evaluating the function on databind, try removing that and changing it to:
OnClick ='lnk_OpenSupplement'
You will have to work out the "ClaimId" on the server side as well, but you should be able to do that using the standard event arguments that would get passed into lnk_OpenSupplement.
The culprit is the following line:
OnClick ='<%# lnk_OpenSupplement(Eval("ClaimId"))%>'>
The <%# ... %> tag will be triggered during data binding. Effectively what the code is doing is executing lnk_OpenSupplement on data binding, and assigning it's return value to OnClick.

imagebutton with onclientclick isn't firing onclick event

I have an imagebutton with an postbackurl and an onclientclick script. When i added the onclientclick code, if my javascript validation passes (aka returns true), the page just seems to perform a postback (the screen just seems to refresh itself), rather than post to the postbackurl. Any ideas why this is happening?
Sample:
<asp:ImageButton ID="imgSendInfo" runat="server" SkinID="SendInfo" PostBackUrl="MyUrlOnAnotherSite" onClientClick="javascript:return onFormSubmit(this.form);return document.MM_returnValue" />
UPDATE:
OK, so I decided to change what JS functions I'm calling now since calling Multiple functions definitely wasn't helping. Here's my updated code. All I'm doing now is validating a single textbox and returning true or false. Even this simple function is causing the postback URL to never get called. Could it have anything to do with the fact that I'm trying to call a function to return a true or false?
My validation function:
function valForm() {
if (document.getElementById('FName').value == '') {
alert('no');
return false;
}
else {
alert('yes');
return true;
}
}
My ImageButton:
<asp:ImageButton ID="imgSendInfo" runat="server" SkinID="SendInfo" PostBackUrl="SetOnCodeBehind" onClientClick="javascript:return valForm();" />
OK figured out a workaround. I REMOVED the return statement from the onclientclick, since the return is what was messing with the postback. I then added requiredfieldvalidators to the page, but Im not displaying any text. This way, 2 sets of validation are occurring (booo), but the first displays my alert messages (this is how the client wants validation performed), and the second prevents the form from posting.
My imagebutton:
<asp:ImageButton ID="imgSendInfo" runat="server" SkinID="SendInfo" PostBackUrl="SetOnCodeBehind" ValidationGroup="enroll" CausesValidation="true" onClientClick="javascript:onFormSubmit(this.form);document.MM_returnValue;" />
My requiredfieldvalidation group:
<asp:RequiredFieldValidator ID="reqVal1" runat="server" ErrorMessage="" ValidationGroup="enroll" ControlToValidate="FName" InitialValue="" />
<asp:RequiredFieldValidator ID="reqVal2" runat="server" ErrorMessage="" ValidationGroup="enroll" ControlToValidate="LName" InitialValue="" />
Did you know that your onClientClick js-function returns twice? return document.MM_returnValue never gets reached.
Is your PostBackUrl's page in your application? You can even validate the previous page on serverside:
If Page.PreviousPage.IsValid Then
' Handle the post back
Else
Response.Write("Invalid")
End If
For further information: MSDN LinkButton.PostBackUrl

OnClick vs OnClientClick for an asp:CheckBox?

Does anyone know why a client-side javascript handler for asp:CheckBox needs to be an OnClick="" attribute rather than an OnClientClick="" attribute, as for asp:Button?
For example, this works:
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
and this doesn't (no error):
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
but this works:
<asp:Button runat="server" OnClientClick="alert('Hi');" />
and this doesn't (compile time error):
<asp:Button runat="server" OnClick="alert('hi');" />
(I know what Button.OnClick is for; I'm wondering why CheckBox doesn't work the same way...)
That is very weird. I checked the CheckBox documentation page which reads
<asp:CheckBox id="CheckBox1"
AutoPostBack="True|False"
Text="Label"
TextAlign="Right|Left"
Checked="True|False"
OnCheckedChanged="OnCheckedChangedMethod"
runat="server"/>
As you can see, there is no OnClick or OnClientClick attributes defined.
Keeping this in mind, I think this is what is happening.
When you do this,
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
ASP.NET doesn't modify the OnClick attribute and renders it as is on the browser. It would be rendered as:
<input type="checkbox" OnClick="alert(this.checked);" />
Obviously, a browser can understand 'OnClick' and puts an alert.
And in this scenario
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
Again, ASP.NET won't change the OnClientClick attribute and will render it as
<input type="checkbox" OnClientClick="alert(this.checked);" />
As browser won't understand OnClientClick nothing will happen. It also won't raise any error as it is just another attribute.
You can confirm above by looking at the rendered HTML.
And yes, this is not intuitive at all.
Because they are two different kinds of controls...
You see, your web browser doesn't know about server side programming. it only knows about it's own DOM and the event models that it uses... And for click events of objects rendered to it. You should examine the final markup that is actually sent to the browser from ASP.Net to see the differences your self.
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
renders to
<input type="check" OnClick="alert(this.checked);" />
and
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
renders to
<input type="check" OnClientClick="alert(this.checked);" />
Now, as near as i can recall, there are no browsers anywhere that support the "OnClientClick" event in their DOM...
When in doubt, always view the source of the output as it is sent to the browser... there's a whole world of debug information that you can see.
You are right this is inconsistent. What is happening is that CheckBox doesn't HAVE an server-side OnClick event, so your markup gets rendered to the browser. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.checkbox_events.aspx
Whereas Button does have a OnClick - so ASP.NET expects a reference to an event in your OnClick markup.
For those of you who got here looking for the server-side OnClick handler it is OnCheckedChanged
I was cleaning up warnings and messages and see that VS does warn about it:
Validation (ASP.Net): Attribute 'OnClick' is not a valid attribute of element 'CheckBox'. Use the html input control to specify a client side handler and then you won't get the extra span tag and the two elements.
Asp.net CheckBox is not support method OnClientClick.
If you want to add some javascript event to asp:CheckBox you have to add related attributes on "Pre_Render" or on "Page_Load" events in server code:
C#:
private void Page_Load(object sender, EventArgs e)
{
SomeCheckBoxId.Attributes["onclick"] = "MyJavaScriptMethod(this);";
}
Note: Ensure you don't set AutoEventWireup="false" in page header.
VB:
Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
SomeCheckBoxId.Attributes("onclick") = "MyJavaScriptMethod(this);"
End Sub
You can do the tag like this:
<asp:CheckBox runat="server" ID="ckRouteNow" Text="Send Now" OnClick="checkchanged(this)" />
The .checked property in the called JavaScript will be correct...the current state of the checkbox:
function checkchanged(obj) {
alert(obj.checked)
}
You can assign function to all checkboxes then ask for confirmation inside of it. If they choose yes, checkbox is allowed to be changed if no it remains unchanged.
In my case I am also using ASP .Net checkbox inside a repeater (or grid) with Autopostback="True" attribute, so on server side I need to compare the value submitted vs what's currently in db in order to know what confirmation value they chose and update db only if it was "yes".
$(document).ready(function () {
$('input[type=checkbox]').click(function(){
var areYouSure = confirm('Are you sure you want make this change?');
if (areYouSure) {
$(this).prop('checked', this.checked);
} else {
$(this).prop('checked', !this.checked);
}
});
});
<asp:CheckBox ID="chk" AutoPostBack="true" onCheckedChanged="chk_SelectedIndexChanged" runat="server" Checked='<%#Eval("FinancialAid") %>' />
protected void chk_SelectedIndexChanged(Object sender, EventArgs e)
{
using (myDataContext db = new myDataDataContext())
{
CheckBox chk = (CheckBox)sender;
RepeaterItem row = (RepeaterItem) chk.NamingContainer;
var studentID = ((Label) row.FindControl("lblID")).Text;
var z = (from b in db.StudentApplicants
where b.StudentID == studentID
select b).FirstOrDefault();
if(chk != null && chk.Checked != z.FinancialAid){
z.FinancialAid = chk.Checked;
z.ModifiedDate = DateTime.Now;
db.SubmitChanges();
BindGrid();
}
gvData.DataBind();
}
}
One solution is with JQuery:
$(document).ready(
function () {
$('#mycheckboxId').click(function () {
// here the action or function to call
});
}
);

Stop postback on TextChanged

I have a textbox in an aspx page that has a TextChanged event attached to it.
I also have a validator attached to the textbox.
When the text is changed, the validate triggers but in case there is an error the textchanged event is still called. Do you know if it's possible to stop the postback on textchanged if the validator fires?
<asp:TextBox ID="txtQuantity" runat="server" AutoPostBack="true" ontextchanged="txtQuantity_TextChanged"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqQuantity" ControlToValidate="txtQuantity" runat="server" ErrorMessage="The quantity is mandatory."></asp:RequiredFieldValidator>
You can move validation to client side adding EnableClientScript="true" attribute. Postback won't occur as check will be performed with JS.
Other than that you can check whether page is valid when performing callback function for TextChanged event so that to define whether function can proceed. You should add ValidationGroup attribute to your validator and call Page.Validate function specifying that group before Page.IsValid is checked.
Upd
Here's the tip.
Add your own JS function, e.g.:
function IsValid( args ) {
if( args.value.length == 0 ) {
return false;
}
else {
return true;
}
}
In Page_Load event add this code:
txtQuantity.Attributes[ "onchange" ] = "if ( IsValid(this) == false ) return;";
This won't mess up auto postback when input is correct, but will prevent postback otherwise.
Add CausesValidation="true" for the text box and it will be good. If the validation is not valid there won't be any post-back.
<asp:TextBox ID="txtQuantity" runat="server" AutoPostBack="true" ontextchanged="txtQuantity_TextChanged" CausesValidation="true"></asp:TextBox>
Just sharing an inline, shorter version of the accepted answer:
<asp:TextBox ID="txtQuantity" runat="server"
AutoPostBack="true" ontextchanged="txtQuantity_TextChanged"
onchange="if (this.value.length == 0) return;"></asp:TextBox>
Having the same problem with a RequiredFieldValidator, the above worked for me.
Known nag: the designer complains that "onchange" is not a valid server-side attribute.
try it after change AutoPostBack="true" as AutoPostBack="false"..
What I do is in my client validation function I test the event type I am in. If the event shows me in a change event, I claim the validation passed and leave.
if (event.type === 'change') {
args.IsValid.true;
return;
}
I believe this is the best solution as you can leave the validator wired up and the textbox set as you like and no longer worry about the change event causing the validation.

DropdownList autoposback after client confirmation

I have a dropdownlist with the autopostback set to true. I want the
user to confirm if they really want to change the value,
which on post back fires a server side event (selectedindexchanged).
I have tried adding an onchange attribute "return confirm('Please click OK to change. Otherwise click CANCEL?';") but it will not postback regardless of the confirm
result and the value in the list does not revert back if cancel
selected.
When I remove the onchange attribute from the DropdownList tag, the page does postback. It does not when the onchange attribute is added. Do I still need to wire the event handler (I'm on C# .Net 2.0 ).
Any leads will be helpful.
Thanks!
Have you tried to set the onChange event to a javascript function and then inside the function display the javascript alert and utilize the __doPostback function if it passes?
i.e.
drpControl.Attributes("onChange") = "DisplayConfirmation();"
function DisplayConfirmation() {
if (confirm('Are you sure you want to do this?')) {
__doPostback('drpControl','');
}
}
You can utilize the the CustomValidator control to "validate" dropdown by calling a javascript function in which you do the confirm():
<asp:DropDownList ID="TestDropDown" runat="server" AutoPostBack="true" CausesValidation="true"
ValidationGroup="Group1"
OnSelectedIndexChanged="TestDropDown_SelectedIndexChanged">
<asp:ListItem Value="1" Text="One" />
<asp:ListItem Value="2" Text="Two" />
</asp:DropDownList>
<script type="text/javascript">
function ConfirmDropDownValueChange(source, arguments) {
arguments.IsValid = confirm("Are you sure?");
}
</script>
<asp:CustomValidator ID="ConfirmDropDownValidator" runat="server"
ClientValidationFunction="ConfirmDropDownValueChange" Display="Dynamic" ValidationGroup="Group1" />
The following works when the DropDownList is triggering partial postbacks:
// caching selected value at the time the control is clicked
MyDropDownList.Attributes.Add(
"onclick",
"this.currentvalue = this.value;");
// if the user chooses not to continue then restoring cached value and aborting by returning false
MyDropDownList.Attributes.Add(
"onchange",
"if (!confirm('Do you want to continue?')) {this.value = this.currentvalue; return false};");
Currently, you're always returning the result of the confirm(), so even if it returns true, you'll still stop execution of the event before the postback can fire. Your onchange should return false; only when the confirm() does, too, like this:
if (!confirm('Please click OK to change. Otherwise click CANCEL?')) return false;
Overriding the onchange attribute will not work if you have have AutoPostBack set to true because ASP.NET will always append the following to the end of your onchange script:
;setTimeout('__doPostBack(\'YourDropDown\',\'\')', 0)
If you set AutoPostBack to false, then overriding onchange with a "confirm and __doPostBack" type script (see above, err.. below) will work but you may have to manually create the __doPostBack function.
if (!confirm('Please click OK to change. Otherwise click CANCEL?')) return false;
Always returns so dropdownlist's OnSelectedIndexChanged event fires whether user clicks OK or CANCEL.
Make sure your event is wired:
dropDown.SelectedIndexChanged += new EventHandler(dropDown_SelectedIndexChanged);
You can also apply a client-side attribute to return the confirmation. Set the index accordingly if cancelled.
dropDown.Attributes.Add("onchange", "javascript: return confirm('confirmation msg')");
<asp:DropDownList runat="server" ID="ddlShailendra" AutoPostBack="True" OnSelectedIndexChanged="ddlShailendra_SelectedIndexChanged" onchange="javascript: { if(confirm('Click ok to prevent post back, Cancel to make a postback'))return true;} " >
<asp:ListItem Text="tes" Value="1" ></asp:ListItem>
<asp:ListItem Text="test" Value="-1"></asp:ListItem>
</asp:DropDownList>
Write the function inline and dont have a "return" for the condition in which you want a post back. This works and is as per the standards.

Resources