I've got a checkbox that's set up as below:
<asp:CheckBox ID="myCheckbox" runat="Server" OnClick="showLoadingScreen(this.checked);" AutoPostBack="true" Text="Check me for more data!" />
The function showLoadingScreen is as below:
function showLoadingScreen(isChecked) {
if (isChecked)
{
document.getElementById('form1').style.display='none';
document.getElementById('img_loading').style.display='block';
}
else { return false; }
}
I've added the else clause in hopes that I can get it to only post back when the checkbox is checked, but it's posting back in either case.
I've got a grid on the page (inside form1) that has a set of data loaded into it on page load, but in order to add some extra data to it I've added this checkbox (its a longer running process, so I only want to load it on demand, not upfront). When it's checked I want to show the loading gif, postback, grab the data, and return. If the box gets unchecked I don't want to do anything, since leaving more than enough data on the page is perfectly fine (that is to say, the data displayed upfront is a subset of the data displayed when the checkbox is checked).
Is there any way to make it so the checkbox auto posts back on checked, but not on unchecked?
Edit: Using Dark Falcon's suggestion, I've modified the checkbox to look like:
<asp:CheckBox ID="myCheckbox" runat="Server" OnClick="return showLoadingScreen(this.checked);" AutoPostBack="true" Text="Include HQ Values" />
And the javascript to be:
function showLoadingScreen(checked) {
alert(checked);
if (checked)
{
document.getElementById('form1').style.display='none';
document.getElementById('img_loading').style.display='block';
document.form1.submit(); //my own addition, to get it to post back
}
else { return false; }
}
Now, it posts back on checked, but the box is not able to be unchecked anymore. As you can see I've added an alert to show the value being passed in. It's passing in the correct value when you uncheck the box (false), but then it somehow gets checked again.
It's not a huge issue, since there's really no reason to ever uncheck the box (since as I stated before, the dataset when checked is a superset of the unchecked dataset), but I'd still like to know why it's doing that. Any ideas?
Do not set AutoPostBack in this case. "AutoPostBack" means post back to the server any time the value of this control changes... which is NOT what you want.
Instead, use GetPostBackEventReference(myCheckbox,"") to get the appropriate postback script and call this from your showLoadingScreen method if the checkbox is checked.
For your onclick handler, you need to do:
return showLoadingScreen(this.checked);
Try to avoid using _doPostback as it is a hack which you will have to know what control ID is posting back and other parameters for that Javascript function from Microsoft ASP.NET. To understand what's happening behind the scene, you have to know why there is a postback and how to prevent the postback from happening.
Here's what's happening with an ASP.NET checkbox (ASP:Checkbox) when auto-postback is set:
<ASP:Checkbox runat="server" id="chkCheckbox" AutoPostback="true" onclick="return isDoPostback(this.checked);" ClientIdMode="static" ... />
generated HTML code is:
<input type="checkbox" ... id="..." onclick="return isDoPostback(this.checked);_doPostback(...);" .../>
The custom onclick event is appended to the beginning of the onclick event of the checkbox. No matter what you do, that prepended function call will execute. Worst off, if you have a return value, the _doPostback will never get executed.
This is what you really want to do (I use a mix of jQuery and native Javascript here):
var checkbox = $("#chkCheckbox");
...
checkbox .on("change", function(e)
{ if(this.checked)
{
var isConfirmedToContinue = confirm("Continue with Postback?");
if(!isConfirmedToContinue)
{ this.checked = false; //Uncheck the checkbox since the user canceled out
var onClickDelegate = this.onclick;
if(onClickDelegate)
{ var me = this;
this.removeEventListener("click", onClickDelegate); //Remove the onclick event so that auto-postback no longer happens
setTimeout(function()
{ //Add back the onclick delegate after 250ms
me.addEventListener("click", onClickDelegate);
}, 250);
this.onclick = null; //Remove the current onclick event by nulling it out
}
}
}
});
Try using a JS routine for checking whether it is checked, and if it is set to true, try doing:
_doPostBack(checkElementReference.name, "");
_doPostBack is responsible for performing posts to the server for controls that don't normally postback. You have to pass the name of the element, which on the server happens to be the UniqueID property for the server-side checkbox control.
Related
I like to add a validation on a label based on its visibility, in that a submit button will raise a validation message or error if the label is not visible.
I am used to the validation controls in the Toolbox, which wont allow this functionality!
It seems as though if an asp:Label's visibility is set to false, the asp.net engine will not even put it in the DOM. So you can check in javascript, using the onclick property of the (html) button to check if the label is in the DOM or not, and use asp.net's __doPostBack() javascript function to post back to the server if it is there:
<script type="text/javascript">
function testMe()
{
var lbl = document.getElementById('lblTest');
if(lbl == null)
document.getElementById('msg').innerHTML = "Error";
else
__doPostBack('testButton');
}
</script>
<asp:Label ID="lblTest" runat="server" Visible="false" Text="Hello"></asp:Label>
<button onclick="testMe();">test</button>
To be completely honest, I thought the lbl would be undefined if the label did not exist in the DOM, but Firebug revealed it is actually null. Anyway, a couple things to note is that in order for asp.net to define the __doPostBack() method, I believe you need some control in the form that has autopostback="true", and in the code-behind you can check what caused the postback in the Page_Load method like so:
if(Request.Form["__EVENTTARGET"] == "testButton") {}
I have a RadPanelBar as such...
<telerik:RadPanelBar
ID="ResourcesSubMenuRadPanelBar1"
Width="195px"
OnItemClick="RadPanelItemClick"
ExpandMode="MultipleExpandedItems"
OnClientItemClicked="RadPanelClientItemClicked"
OnClientLoad="RadPanelBarClientLoad"
runat="server"
AppendDataBoundItems="true"
EnableEmbeddedSkins="false"
OnClientItemCollapse="RadPanelClientItemClicked"
OnClientItemExpand="RadPanelClientItemClicked">
</telerik:RadPanelBar>
This all works as expected, except for one little thing. In the code behind, I explicitly set the NavigateUrl property to string.Empty but when an item is clicked, it adds a hash to the url. Obviously, this is because the href attribute has been set to "#" when the control renders the HTML.
I know that I can simply return false from the OnClientItemClicked event, but that will stop the ItemClick event from being fired on the server.
As I say, there is no real error with this code it's just bugging me (and, more importantly, the end users) that there is a # added to the URL.
Does anyone know how to stop this happening?
Try this in your OnClientItemClicking event:
eventArgs.set_cancel(true);
Ref: http://www.telerik.com/help/aspnet-ajax/panelbar-onclientitemclicking.html
And, if in case you want the post back to happen, I suppose there is a item.PostBack property (server-side). Set it to true. It should post you back - if the NavigateUrl is empty (or #).
Compatible in just about every browser, IE9 and up:
Javascript (no jQuery):
stripTelerikHashtag = function () {
[].forEach.call(
document.querySelectorAll(".rpLink"),
function (a) { a.removeAttribute("href") }
);
};
Javascript (with jQuery):
stripTelerikHashtag = function () { $(".rpLink").removeAttr("href"); };
In your ASP, set OnClientLoad on the RadPanelBar to stripTelerikHashtag.
I have a CheckBox on an ASP.NET Content Form like so:
<asp:CheckBox runat="server" ID="chkTest" AutoPostBack="true" OnCheckedChanged="chkTest_CheckedChanged" />
In my code behind I have the following method:
protected void chkTest_CheckedChanged(object sender, EventArgs e)
{
}
When I load the page in the browser and click the CheckBox it becomes checked, the page posts back, and I can see chkTest_CheckedChanged being called.
When I then click the CheckBox again it becomes unchecked, the page posts back, however chkTest_CheckedChanged is not called.
The process is repeatable, so once the CheckBox is unchecked, checking it will fire the event.
I have View State disabled in the Web.Config, enabling View State causes this issue to disappear. What can I do to have reliable event firing while the View State remains disabled?
Update:
If I set Checked="true" on the server tag the situation becomes reversed with the event firing when un-checking the CheckBox, but not the other way around.
Update 2:
I've overridden OnLoadComplete in my page and from within there I can confirm that Request.Form["__EVENTTARGET"] is set correctly to the ID of my CheckBox.
To fire CheckedChanged event set the following properties for CheckBox, AutoPostBack property should be true and should have a default value either checked false or true.
AutoPostBack="true" Checked="false"
Implementing a custom CheckBox that stores the Checked property in ControlState rather than ViewState will probably solve that problem, even if the check box has AutoPostBack=false
Unlike ViewState, ControlState cannot be disabled and can be used to store data that is essential to the control's behavior.
I don't have a visual studio environnement right now to test, but that should looks like this:
public class MyCheckBox : CheckBox
{
private bool _checked;
public override bool Checked { get { return _checked; } set { _checked = value; } }
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//You must tell the page that you use ControlState.
Page.RegisterRequiresControlState(this);
}
protected override object SaveControlState()
{
//You save the base's control state, and add your property.
object obj = base.SaveControlState();
return new Pair (obj, _checked);
}
protected override void LoadControlState(object state)
{
if (state != null)
{
//Take the property back.
Pair p = state as Pair;
if (p != null)
{
base.LoadControlState(p.First);
_checked = (bool)p.Second;
}
else
{
base.LoadControlState(state);
}
}
}
}
more info here.
It doesn't fire because with viewstate disabled the server code does not know that the checkbox was previously checked, therefore it doesn't know the state changed. As far as asp.net knows the checkbox control was unchecked before the postback and is still unchecked. This also explains the reverse behavior you see when setting Checked="true".
I'm not sure but I guess that my solution is working only for .NET Framework 4.0:
Use ViewStateMode = "Disabled" to disable view state insted of EnableViewState="false". This will caution the same behavior except that you can save a local view state.
So, on your checkbox, set the attribute ViewStateMode = "Enabled" and the problem is solved, without implementing a custom checkbox.
It's an old post but I had to share my simple solution in order to help others who searched for this problem.
The solution is simple: Turn on AutoPostBack.
<asp:CheckBox id="checkbox1" runat="server"
AutoPostBack="True" //<<<<------
Text="checkbox"
OnCheckedChanged="knowJobCBOX_CheckedChanged"/>
I wanted to tidy things up a bit so I've just spent a bit of time testing a solution for this.
joshb is correct with his explanation for why the CheckBox behaves the way it does.
As I don't know how I got round this last year or even if I did (I can't remember what I was working on at the time to check), I've put together a simple solution/workaround.
public class CheckBox2 : CheckBox
{
protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
bool isEventTarget = postCollection["__EVENTTARGET"] == UniqueID;
bool hasChanged = base.LoadPostData(postDataKey, postCollection);
hasChanged = hasChanged || isEventTarget;
return hasChanged;
}
}
If you now register CheckBox2 in your page and use it in place of your standard CheckBoxes, you will get the CheckedChanged event fired as you expect with ViewState disabled and AutoPostBack enabled.
The way this works is allowing the normal CheckBox to do its thing with validation and change checking, but then performs an additional check to see if it was the target of the event that caused the postback. If it was the target, it returns true to tell the framework to raise the CheckedChanged event.
Edit:
Please note that this only solves the problem for AutoPostBack on the CheckBox. If the PostBack is invoked from anything else (a button, for example), the CheckedChanged event still exhibits the observed problem.
I had the same problem. I have spent a lot of time on it and finally have solved it.
In my case the Checkbox was disabled by default:
<asp:CheckBox ID="chkActive" runat="server" Enabled="false"/>
It turns ViewState isn't loaded for disabled or invisible controls.
So remove Enabled="false" or Visible="false" and it will work as expeceted. And of course ViewState shouldn't be disabled.
Additionally: Check for any errors in the JavaScript console.
I experienced the same exact issue described by OP except that it only happened in Safari (checkbox worked fine in Chrome and Firefox). Upon inspecting the JavaScript console, I found an error that was being thrown by a malformed jQuery selector.
In my case, I had $('a[id*=lbView') which was missing a closing ]. This threw an error in Safari but, surprisingly, not in Chrome nor in Firefox.
The super easy answer is to set the ViewState on for that one control.
Just add the EnableViewState="true" to the AutoPostBack="true" property in the checkbox tag.
The default value of "Checked" Property of CheckBox is false (which means Uncheck). So, when you Check/Uncheck the CheckBox it compares with Checked Property.
If it does not match with Checked Property, ASP fires OnCheckedChanged Event.
If it matches with the Checked Property it will not fire the OnCheckedChanged Event.
So, in order to make ASP to fire OnCheckedChanged event when unchecking, it has to know Original value, so that it compares with the value from user and fires the event.
By adding data-originalValue='<%# Eval("ValueFromCodeBehind") %>' property in asp:CheckBox will be able to fire the OnCheckChanged Event as ASP can now able to know its previous value. So that when we change it, ASP fires OnCheckChanged Event even if we do Uncheck.
i m working on simple asp.net and in that i am using validators.
my situation is like that i have used reaquired field validator its working fine.
and after that if i ented data and fired insert query then data is inserted and sucessful message is displyed on the lable. but agin if i clik on submit button with empty fields then validator works but the lable of successful message does not disapper. how to hide that lable.
You need to use javascript to hide the success message, here is a sample
<script type="text/javascript">
function hide() {
document.getElementById('<%=lblSuccess.ClientID %>').style.display = 'none';
return false;
}
</script>
<asp:Label ID="lblSuccess" runat="server" Text="Success"></asp:Label>
..your form code
<asp:Button ID="btnOk" runat="server" Text="OK" OnClientClick="hide()" ValidationGroup="ValidateForm" />
Why javascript, the form doesn't get posted because validators don't let the form to be posted if the conditions aren't met, so you are left to hide the message dynamically with javascript
<script type="text/javascript">
function Hide() {
document.getElementById("Lable1").style.display = 'none';
return false;
}
</script>
<asp:Button ID="Button1" OnClientClick="Hide()" runat="server" onclick="Button1_Click" Text="Button"/>
and use
if (Page.IsValid){}
on clik event.
Show us some code of what you're up to and we can tell you more precisely where you are going wrong. In a nutshell though the visibility of that message is going to be persisted through a postback so you have to explicitly tell it to not be visible if validation has failed.
Set the label to visable=false and on save set the text value if required and change visible =true ?
On form load, do something like this:
TheValidMessageLabel.Visible = Page.IsValid;
You are probably just setting the visible state to true when it's valid and never setting it to false again.
Set your success label visibility in page load to false.
And only if operation is successfully set that label visibility to true.
cheers
ASP.NET 2.0, testing in FF3 and IE7.
When I hit the 'enter' button from a text box the corresponding "OnClick" event for the first ImageButton in the page is fired. If I remove that image button, it fires the next ImageButton OnClick event on the page.
From the FireBug console, if I use JavaScript to submit the Form, this does not happen. But for whatever reason hitting enter from the textbox triggers the unrelated ImageButton event.
I found this question which had a similar problem, however the proposed answer to that solution doesn't work since ImageButtons do not have a "UseSubmitBehavior" property on them.
I don't understand why this event is firing. If I look at Request.Form, I can see that __EVENTTARGET is empty, and it is in fact posting the entire form contents (all of my textboxes), but also includes imageButton.x and imageButton.y key/value pairs.
Why is this? I suppose I could detect "enter" key presses from these text boxes with javascript, but my experience in the past is this behavior is highly variable between browsers. Any suggestions?
here's a more elegant solution
<asp:TextBox ID="TextBox1" runat="server"
onkeydown = "return (event.keyCode!=13);" >
</asp:TextBox>
read the entire post here
You could try setting a default button in an asp panel or on your form. This will let you control what happens when a user hits the enter key.
I'm having the same issue on my project.
This issue is caused because ASP.NET always will assume that the first element that inherits from IButton interface (Button and ImageButton) is the default button from the page.
Hipoteticaly, if you use an LinkButton instead of Button or ImageButton, this issue is solved.
You can find more information here on MSDN.
You can disable the Enter key from being pressed, so the user will have to click on of your ImageButtons. Just paste this javascript block onto your page:
<script type="text/javascript">
function stopRKey(evt) {
var evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 13) && (node.type=="text")) {return false;}
}
document.onkeypress = stopRKey;
</script>
Recently, I've been doing more on the client with web services and fewer postbacks. By moving my controls outside of the form element (or eliminating it altogether), the problem goes away. It's inserted by default on aspx pages, but it didn't occur to me until recently that I don't need it for much of what I do.
Its the default behaviour for an enter button press in a non text area to post back a form. You would have to handle it in a javascript method to stop the postback.
You'd just need to check the window.event.keyCode property to see if its equal to 13. If it is, reset it to 0.
function KeyPress()
{
if (window.event.keyCode == 13)
{
window.event.keyCode = 0;
}
}
I suppose I could detect "enter" key presses from these text boxes with javascript
That's what I did to get around that behaviour and it works great in IE7 and FF3. It's just a little unnatural.
Here is a generic exemple:
function TextBox1_KeyDown(sender, e)
{
var key;
if(window.event)
key = window.event.keyCode; //IE
else
key = e.which; //firefox
if(key == 13 && $("#TextBox1").val() != "")
{
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("TextBox1", "", true, "", "", false, true));
}
return (key != 13);
}
I used WebForm_DoPostBackWithOptions because I needed validators to trigger. Otherwise, you might want to use __DoPostBack.
Here are the "prototypes":
function __doPostBack(eventTarget, eventArgument)
function WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit)
{
this.eventTarget = eventTarget;
this.eventArgument = eventArgument;
this.validation = validation;
this.validationGroup = validationGroup;
this.actionUrl = actionUrl;
this.trackFocus = trackFocus;
this.clientSubmit = clientSubmit;
}
function WebForm_DoPostBackWithOptions(options)
Hope it helps.
P.S.: I used JQuery here but $get would be the same.
Here's an elegant solution I have found, in case anybody else has this problem (in case all other solution don't work for you, as they didn't work for me):
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Panel runat="server" DefaultButton="doNothingButton">
<ul id="shopping-list-ul">
</ul>
<asp:Button CssClass="invisible" runat="server" ID="doNothingButton" OnClientClick="return false;" />
</asp:Panel>
</ContentTemplate>
The textbox iself was inside the ul (generated by javascript).
Pressing enter will trigger the "doNothingButton", which will return false on client side, causing no postback at all!