Client-Side validation with groups - asp.net

I have several tabs that are loaded via ajax, and each one has a set of validators. I want to allow the user to change tabs only if the tab is valid
I thought setting a validationgroup to the validators and then check for the specific group like this, would work:
function validatePage(group) {
return Page_ClientValidate(group);
}
However, when I call the function, it always returns true. Can anyone see what I'm doing wrong?
I check it like this
alert(validatePage("presentaciones"));
And I have some validators:
// (...)
<asp:TextBox ValidationGroup="presentaciones" id="txtDescription" runat="server" Text='<%# Eval("Description") %>' MaxLength="50" />
<asp:RequiredFieldValidator ID="DescriptionRequiredFieldValidator" runat="server" ControlToValidate="txtDescription" SetFocusOnError="true" ValidationGroup="presentaciones" ErrorMessage="Debe ingresar una descripciĆ³n" Display="Dynamic" />
// (...)

I have made groups work server-side with Page.Validate(group) but I wasn't aware this could be done client-side. Perhaps you need to implement a custom validation control that checks the status of each tab.

My guess is that the validation scripts are not being wired up. In your function do an alert((typeof(Page_Validators) == "undefined")) and see if it displays true. You said you are loading the tabs via ajax. You may want to see if placing a validator on the page somewhere will help wire up the validation scripts.
The other thing to watch for is Firefox and legacy rendering mode....client side just plain does not work in that scenario.

This can be done on the client side. Like this:
$('.buttonWithSameValidationGroup').bind('click', function () {
if (Page_ClientValidate($(this).attr('validationgroup'))) {
//do stuff
}
});
Sometimes you might need to add the following server side code in the Page Pre_Render method
button1.AddAttributes("validationgriup","group1");

Related

ASP.NET Webforms - Default Button using Enter Key

I've looked everywhere and read everything and nothing I do seems to work so I'll ask this question again.
I have an ASP.NET WebForms application that has a page that can collect multiple pieces of data (textboxes and dropdowns) in order to then perform a search. Once collecting all of the data from the user, the user can click the "Search" button to initiate the search. I'd like the user to also be able to simple hit the Enter button and have the search initiate. I cannot seem to do this successfully.
I've tried the DefaultButton approach at the Panel level as all of the ASP.NET controls are inside of a panel. No luck. I've tried the JavaScript function approach (defaultEnterKey) checking for event.keyCode === 13 and just trying to add an attribute to one of the text boxes (onkeydown) in the code behind just to get it to work. Nope.
I'm obviously missing something.
Well, you could first try at the form level.
so in the form tag, say try this:
<form id="form1" runat="server" defaultbutton="Button3">
Give the above a try - even with a update panel, and then a panel inside that update panel, the above should work.
So try the form level setting - that is the outer most form that wraps everything in that given page.
Edit: the whopper and Mount everest detail been noted that the page has a master, and thus of couse no form tag exists.
Thus, I suggest this:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server" DefaultButton="Button2" >
your markup here
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
You can simply cuse jQuery to bind a function on KeyPress and check if it is the Enter key. If so then do something with it.
The return false is needed to prevent the form from doing a PostBack.
<asp:TextBox ID="TextBox1" runat="server" CssClass="CaptureEnter"></asp:TextBox>
<script>
$('.CaptureEnter').keypress(function (e) {
if (e.keyCode === 13) {
alert('Enter was pressed! Start searching for: ' + $(this).val());
return false;
}
});
</script>

Why does CustomValidator fire on textbox's onblur

I am building a CustomValidator to handle my own application's logic on time fields ("09:00", "15:35", ...) but I am stumbling on a behaviour that I haven't found any explanation for online.
My focus right now is the validation logic that gets executed client-side.
The problem is, as said in the title, that, if and only if I set the ControlToValidate property in the Validator with the ID of the textbox I am validating, the validation gets fired as soon as focus leaves the textbox; it even fires before the onblur event, which is absolutely detrimental for me, since I am using the onblur event to standardize the time formats (eg "9:00" -> "09:00", "11.45" -> "11:45") and thus, the validation logic potentially receives an incorrect value. If, on the other hand, the ControlToValidate property remains blank, the ClientValidationFunction is fired only on a submit/postback.
The only related answer I've found is this https://stackoverflow.com/a/8649697/450684, but still, to me it makes no sense at all. Why should the presence of a ControlToValidate indicate that I want client-side validation to execute before onblur? I don't want it! Is there any way to supress this behaviour?
Here is an example page:
<asp:TextBox runat="server" AutoPostBack="false" ID="txtBox1" onblur="FormatText(this);" />
<asp:CustomValidator runat="server" ID="CV1" ControlToValidate="txtBox1" ClientValidationFunction="Test1" />
<asp:CustomValidator runat="server" ID="CV2" ClientValidationFunction="Test2" />
<asp:Button ID="btn1" Text="postback" runat="server" OnClick="btn1_Click" />
<asp:Label ID="lbl1" runat="server" />
<script type="text/javascript">
function FormatText(txtBox1)
{
alert('FormatText');
}
function Test1(val, args)
{
alert('Test1');
}
function Test2(val, args)
{
alert('Test2');
}</script>
What I want is both Test1 and Test2 to execute only on btn1's click; instead on txtBox1's onblur event I get Test1 and FormatText executing in this order
ASP.NET's client validation was really fun for me to write and study, don't let this ruin everything :-)
Thx
PS: .NET framework's version is 4.0. Plus, the server-side language is C#, if it matters
I think what is going on is this:
The standard behavior for ASP.NET client-side validation is to validate when the field is exited. That's an observation, not a reference to a published standard (although there may be one.) The out-of-the-box validators all behave this way. All of them require specifying a particular field to validate.
The custom validator allows you to validate a single control (by specifying it with ControlToValidate), or lets you validate a combination of controls, in which case you set ControlToValidate to an empty string. Unless things have changed, you do have to specify it; if you omit the attribute, no validation will occur.
So ... if you specify a control to validate, the custom validator behaves like every other validator and reacts to the user exiting the field. If you don't specify a control to validate, it doesn't know what controls you're interested in, and doesn't do that.
You may be able to work around this by writing a truly custom validator: inherit from BaseValidator. That can actually be a lot of fun.
How to manage events of validation for your control.
You can remove ControlToValidate property from your validator and bind validation for your textbox on textbox event as you wish. You can add some function logic before or after validation also. On button click event validation stay the same without change.
function BindValidation(){$('#txtBox1').on('blur keyup change',function(){ValidatorValidate($('#CV1').get(0));});}
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(BindValidation);
//validation function example for CV1 validator
function Test1(val, args)
{
args.IsValid=$('#txtBox1').val().length>0&&$('#txtBox1').val().match(/^\s+$/g)==null;
}

Why does a failed validation prevent postbacks from control in other validation groups?

I have an asp.net web form with several textboxes, buttons, and other controls. One of the buttons is supposed to trigger validation of content in some of the textboxes. This works fine, except that if validation fails, all subsequent postbacks of the page are prevented. Fixing the invalid values gets rid of the error messages, but postback still does not occur.
The validation is occurring within an AJAX UpdatePanel. I'm not sure if that matters or not.
I'm glad the workaround is fine for you, but for the benefit of others who land this page, disabling client side validation is far from an acceptable solution. So here goes:
Why it happened only when UpdatePanel was around, is still unclear to me, however:
As others have mentioned, the issue you were having is most likely because the unsuccessful validation attempt is preventing a further postback.
See also: Why won't my form post back after validation?
There is a variable called Page_BlockSubmit which is set to true when client side validation fails:
function Page_ClientValidate(validationGroup) {
....
Page_BlockSubmit = !Page_IsValid;
return Page_IsValid;
}
So when a __doPostBack occurs as part of, say, an OnSelectedIndexChanged of a DropDownList, there is this check:
function ValidatorCommonOnSubmit() {
....
var result = !Page_BlockSubmit; /* read the value */
....
Page_BlockSubmit = false; /* reset it */
return result;
}
Which will block the first time, but then clear the flag, so the next postback attempt should work.
The workaround, in my case, for a DropDownList's OnSelectedIndexChanged event, was to have a snippet added to its client-side onchange event:
<asp:DropDownList runat="server" ID="SomeDropDownList" OnSelectedIndexChanged="AlwaysDoSomething"
onchange="resetValidationState(this);">
....
</asp:DropDownList>
<script type="text/javascript">
function resetValidationState() {
// clear any postback blocks, which occur after validation fails:
window.Page_BlockSubmit = false;
}
</script>
You might get away with putting that snippet into the onchange itself.
except that after this button has been clicked no other button can cause a postback unless the validation errors have been corrected. So, btnDelete, which should not require validation of the textboxes, cannot postback until the textbox values are corrected
Don't see that behavior with following code..
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox1" ValidationGroup="pc">
</asp:RequiredFieldValidator>
<asp:Button runat="server" ID="btnSubmit" Text="Submit" Width="150" CausesValidation="true" ValidationGroup="pc" />
<asp:Button runat="server" ID="btnDelete" Text="Delete" CausesValidation="false" />
I could be totally off base here - but i think I see the problem. (I work mainly with devexpress controls so the rules can be a bit different). When validation fails, the whole page is set to invalid, so no postbacks can occur. Can it be since the delete button is not causing any validation, its not re validating after those editors have been changed to be valid?

how to check a particular asp.net validation control is valid?

In a web form there are different asp.net validation controls. Is it possible to check a particular validation control is valid ? For example on leaving focus of textbox, first I will check requiredFieldValidatorUserName is valid ? If it is valid then I will check on server using ajax that this user name is not booked already.
Edit:
Explaination: I want to check validity (that input was valid) of a validation control on client side.
Please guide.
All validator controls implement IValidator which contains the IsValid property.
myValidatorControl.IsValid
The best way would be to use a CustomValidator with client side code, as this will display all the error messages, block form submission and also ensure that the validation is repeated at the server side - remember, just because you have client-side validation available, doesn't mean the user's seen it: Always validate your input at the server as well.
Your CustomValidator would then be coded to call the Ajax methods, and would show the error messages correctly to the client:
<asp:Label ID="UserNameLabel" AssociatedControlID="UserName" runat="server">
UserName *:</asp:Label>
<asp:TextBox ID="UserName" runat="server" />
<asp:RequiredFieldValidator ID="UserNameRequired" runat="server"
ControlToValidate="UserName" EnableClientScript="true"
ErrorMessage="You must supply a username!" />
<asp:CustomValidator ID="UserNameCustom" runat="server"
ControlToValidate="UserName"
ClientValidationFunction="CheckExisting"
OnServerValidate="UserNameCustomValidate"
ErrorMessage="Username already taken" />
And your ClientValidationFunction should look something like:
<script type="text/javascript">
function CheckExisting(source, arguments) {
// Pass the arguments.Value to your AJAX call:
if (ajaxCallUserNameTaken(arguments.Value)) {
arguments.IsValid = false;
}
}
</script>
(Obviously, you'll need to write the ajaxCallUserNameTaken method to call your page method/web service/etc.)
Doing it this way will ensure that the validation methods happen as expected; this will get called whenever the user tabs out of the textbox leaving a value (it won't get called if the textbox is empty), and will ensure that the user can't submit the page until they supply a unique value. You'll also want to create the method referenced in OnServerValidate to ensure that the value's good once it hits the server too - this should call the same code that the AJAX endpoint uses to reduce duplication of code, etc.
I was originally going to suggest that you could use the Page_Validators object on the client-side to do some checking in the onBlur event, but I don't really think this is suitable here as it results in more pain:
It assumes that although there might be more than one validator on the page, there's only the RequiredFieldValidator on the control we're checking
The RequiredFieldValidator isn't fired during OnBlur if a user moves out of a control without setting a value - only if they set and clear the value, so even if isvalid is true, you need to check for an empty string!
You could do this by setting the ValidationGroup for the Validator control that you want to treat as separate from the others. Make sure it matches the ValidationGroup of the control it's validating (your username field).
I have just faced the same issue and I Set CausesValidation="true" to the textbox control and it worked. Just give it a try :)
I have been messing around with this around for a bit and found a rather easy (not so efficient) solution to handle this using jQuery.
Use this function to check the validity of your control:
function validateControl() {
return $('#YOUR_VALIDATOR_ID').css("visibility") == "visible"
if you're using Display="Dynamic" on your validator then the function is like so:
function validateControl() {
return return $('#YOUR_VALIDATOR_ID').css("display") == "inline"
Be sure to check the true ID of your validator if you're using a Masterpage, as it will be different than the one in your IDE. Do so by viewing the page source in your browser.
The best solution will be of course to validate your form in some other way, using JavaScript or a CustomValidator that lets you write your own code.

asp.net button use javascript return function

I have an asp:button control and am using the "CommandName" and "CommandArgument" parameters in the .aspx file. The CommandName is found with <%# Eval("Name") %>, but the CommandArgument has to be found via a javascript function. However, I'm not quite sure how to do this inline. The function returns a number (integer), which is to be used as the value of the CommandArgument. Is it possible to do this?
Thanks
EDITED TO ADD CODE
I've added an example code (don't have access to the real code atm). However, basically, the CommandArgument should be the value returned by the function CalculateLength().
function CalculateLength(a,b) {
return a*b;
}
<asp:Button ID="btnUpdate" runat="server" Text="Update" CommandName=<%# Eval("Name") %> CommandArgument= ??? //Should be result of CalculateLength(a,b).
I am not sure how you are going to get the javascript to work because the aspx code is running server side and building the output for your button. By the time the javascript runs the page code has already been built and the button's html and attached javascript as well.
Is there anyway to calculate the function server side and then just do:
CommandArgument="<%= CalculateLengthServerSide() %>"
You don't need to just use the data your binding to, you can call any server side function.
Edit: Try switching your label that stores the quantity to a textbox and making it read only so uses will not mess with it. After the button is clicked, you should be able to find the textbox control and read out the posted value.

Resources