Elegant way to combine ASP.NET validation with JQuery - asp.net

How can I best combine JQuery with ASP.NET client side validation model?
I've generally avoided implementing ASP.NET validation model because it always seems overkill for what I was doing. For the site I'm working on now I'm just collecting non critical user data and only need somewhat basic validation. I dont want messages appearing in the DOM or anything like that. I've always found it hard to get that to look right anyway.
But I need now to implement something a little more elegant. What I want to take advantage of in JQuery is clever search expressions like 'tell me if at least one of these checkboxes is checked'. I'm new to JQuery, but I think this is about 1 line of JQuery and a lot more complicated in the traditional ASP.NET model.
So I want to take full advantage of JQuery's abilities but not completely undemine ASP.NET's validation model.
My best approach so far is this (which pretty much goes behind the back of ASP.NET):
$('#<%=btnJoinMailingList.ClientID %>').bind('click', function(event) {
if (...) {
alert("You must enter a name");
return false;
}
return true;
});
What's a better approach here? Are there any recommended plugins for JQuery ?
PS. I don't want to use MVC model. I'm trying to create a very 'RAD' site and dont have time to delve into that fun new stuff yet.

ASP.NET has many validation controls, one of them is the CustomValidator.
You can give it a custom JavaScript function that uses jQuery and returns true or false via argument. You can use this control to display the error message automatically, or just run the jQuery code and handle the display manually.
Aspx:
<asp:CustomValidator ID="CustomValidator1" runat="server" Display="None"
ClientValidationFunction="checkTextareaLengths">
</asp:CustomValidator>
JavaScript:
function checkTextareaLengths(source, args){
args.IsValid = true;
$('textarea').each(function(){
if($(this).text().lenght > 400)
args.IsValid = false;
});
}

ASP.NET webforms and jQuery's validation model is very, very similar, IMHO, in that both are client-side and implementing one of them does not necessarily undermine the other. The only real difference would be that, behind the scenes, ASP.NET validators will cause the Page.Validate() method to returns false if you have an unvalidated field.
You may opt to hand-roll your own validation controls, and then cause the same behavior, but as you yourself have stated, that might be overkill.
jQuery also has its own Validator plugin which you might want to look at: http://docs.jquery.com/Plugins/Validation/Validator.

ASP.NET validator is a span with additional attributes.
With jquery you can acces all validators on the page or filter they by any criteria
supported by jquery. To force validation via javascript call ValidatorValidate function.
For example:
function validate_step(step_element) {
// find all validators on step_element and force validation
var validators = $(step_element).find("span[controltovalidate]");
var stepIsValid = true;
validators.each( function() {
ValidatorValidate(this); stepIsValid &= this.isvalid;
});
return stepIsValid;
}

Related

How to call HTML5 form.checkValidity during form.onSubmit in WebForms?

How can i override, or extend, the standard WebForms WebForm_OnSubmit JavaScript function?
I am using HTML5 input types in an ASP.net WebForms web-site. The user-agent (e.g. Chrome, IE, Firefox) already correctly handles data sanitization, alternate UI, etc.
Normally, when a user clicks an <input type="submit"> button, the User-Agent will halt the submit, and show UI to indicate to the user that their input is going to be invalid:
The problem with WebForms is that it does not use a Submit button. Instead, everything can be done through a JavaScript postback, rather than submitting the form:
<asp:LinkButton ID="bbOK" Text="Save User" runat="server" OnClick="bbOK_Click"></asp:LinkButton>
Which, when rendered into client HTML, becomes a call to the JavaScript:
WebForm_DoPostBackWithOptions(...)
With the really long form being an Anchor tag:
<a id="Really_Long_Thing_ctl00_bbOK"
href='javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$MainContent$VistaToolbar$ctl00$bbOK", "", true, "", "", false, true))'>
Save User
</a>
This means that the user-agent never gives the user a prompt that an entered element is invalid.
Even though the form is not being "submitted", it does still trigger an onsubmit event. I can manually trigger the HTML5 form validation using something like:
isValid = form.checkValidity();
Ideally i would hook that event in my ASP.NET WebForms site:
Site.master
<form runat="server" onsubmit="return CheckFormValidation(this)">
<script type="text/javascript">
function CheckFormValidation(sender)
{
//Is the html5 form validation method supported?
if (sender.checkValidity)
return sender.checkValidity();
//If the form doesn't support validation, then we just assume true
return true;
}
</script>
Except that the WebForms infrastructure deletes my onsubmit method handler, and replaces it with its own:
<form id="ctl01" onsubmit="javascript:return WebForm_OnSubmit();" action="UserProperties.aspx?userGuid=00112233-5544-4666-7777-8899aabbccdd" method="post">
So my own submit call is ignored. It appears that delving into WebForm_OnSubmit leads down a rabbit hole of ASP.NET WebForms validation infrastructure:
function WebForm_OnSubmit()
{
if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false)
return false;
return true;
}
which calls the function:
var Page_ValidationActive = false;
function ValidatorOnSubmit()
{
if (Page_ValidationActive) {
return ValidatorCommonOnSubmit();
}
else
{
return true;
}
}
which calls, which calls, which uses, which checks.
Just want HTML5 form validation with WebForms
The issue is that WebForms has a huge infrastructure for checking a form before submitting, and displaying errors to users through a standardized mechanism (and entire infrastructure that i do not use). It takes over the onsubmit event of forms, and it doesn't (necessarily) use an <input type="submit"> in the process.
What can i do to convince ASP.NET WebForms web-site to let the User-Agent validate the form?
See also
HTML validation and ASP.NET Webforms
How do I get Client-side validation of ASP.NET page to run?
Trigger standard HTML validation (form) without using submit button?
MSDN Magazine: Better Web Forms with HTML5 Forms
The web forms infrastructure deletes the handler because you attempt to add it directly on the element in the visual design environment, and web-forms is not designed to work this way.
Trapping the on-submit handler is easy, you just need to think a little creatively.
Whenever your trying to deal with anything like this in a web-forms environment, you have to learn to think about solutions that come after the web-forms page rendering pipeline. If you try to find a solution that works directly inside the web-forms engine, then web-forms will win every-time.
You can reproduce my exact test case here if you need too, or you can pick out the bits you need and re-use as required.
Step 1
Create a NEW web-forms project in C# (You can do it in VB if you want, but I'm putting my examples as C#), once your project has been created, right click on your application references, go into NuGet and install JQuery.
It is possible to do this with out JQuery, and just use native methods, but it's Sunday and I'm being lazy today :-)
Step 2
Add a new web-form to your project (using add new item) and call this 'Default.aspx', onto this form add some text, a text box a button and a label.
your code should look similar to:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="jsvalidation.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
Please enter your name :
<asp:TextBox ID="txtName" runat="server" data-jsname="username"></asp:TextBox>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
</div>
<asp:Label runat="server" ID="lblResult">...</asp:Label>
</form>
</body>
</html>
Then press F7 (or double click on the button) to go to the code behind editor for your form.
Step 3
Add your code for the button handler into your code behind. If your doing things exactly the same way as me, your code should look similar to this:
using System;
namespace jsvalidation
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{}
protected void btnSubmit_Click(object sender, EventArgs e)
{
if(Page.IsPostBack)
{
lblResult.Text = "Well hello there " + txtName.Text;
}
}
}
}
At this point you can test things work by pressing F5, and what ever you enter (or don't enter) in the text box, should appear with the message in the label below when you press the submit button.
Now we have a basic web-forms set up, we just need to intercept the form submit.
Step 4
As I said a moment ago, you need to think outside the web-forms box.
That means you need to run your intercept AFTER the page has been rendered and sent to the browser.
All of the JS that web-forms injects into the mix is usually executed before the page output is allowed to proceed, which means before the opening body tag.
In order to get your code to run after it, you need to put your script at the END of the html output so that it runs last.
add the following code just before the closing body tag, but AFTER the closing form tag
<script src="/Scripts/jquery-2.1.1.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('form').submit(function() {
var uninput = $('input[data-jsname="username"]');
var username = uninput.val();
if (username == "")
{
alert("Please supply a username!");
return false;
}
});
});
</script>
The more astute among you, will notice straight away that I'm not calling the HTML5 validation API, the reason is I'm trying to keep this example simple.
Where I check the username value is the important part.
All that matters is the anonymous function in which I perform the check returns true or false. (True is the default if you DON't return anything)
If you return a false, you'll prevent the post back taking place, thus allowing you to use whatever JS code you need to make the form fields change using the HTML5 validation API.
My personal preference is to use bootstrap (See the syncfusion free e-book range for my Bootstrap 2 book, and soon to be released Bootstrap 3 book), where you can use special markup and css classes in the framework such as "has-errors" to colour things appropriately.
As for the selection of the components using JQuery, well there's 2 things here you need to pay attention too.
1) You should NEVER have more than one form on a web-forms page, in fact if I remember correctly, your app will fail to compile if you do, or at the most it'll certainly throw an exception at run-time.
2) Beacuse you only ever have one form, then you can be very safe in making the asumption, that a generic 'form' selector in JQuery will only ever select your main form (Irrespective of the ID, name, lack or size thereof) and adding an onsubmit handler to it, will always attach this after web-forms has don'e it's thing.
3) Beacuse web-forms can (and usually does) mangle ID names, it's generally easier to use 'data attributes' to add custom bits to your tags. The actual ASP.NET js side validation does this exact same trick itself to allow JS code and .NET code to happily co-exist in the same page. There are ways to tell .NET how to name the ID's but generally you have to set lots of options in lot's of places, and it's very easy to miss one. Using 'data attributes' and the JQ attribute selector syntax is a much safer, easier to manage way of achieving the same thing.
Summary
It's not a difficult task, but I have to admit, it's not one that's immediately obvious if your not looking outside the fence that web-forms builds around you.
Web-forms is designed for rapid application development, primarily for devs used to the desktop win-forms model. While web-forms still has it's place these days, for new greenfield apps I would recommend looking at other options too, esp ones that build on the foundations that the new HTML5 specifications are trying hard to lay down and get right.

Can I assume asp.net form's ID always being the same?

I want to submit a simple asp.net form in jQuery
can I assume
$("form[0]").submit()
always works, cross browser?
You mean something like this
$("#aspnetForm").submit()
Something like above would work cross browser as you said
The code you pasted is cross browser too. It won't work on ANY browser so maybe that counts as cross browser :-) just a joke
No, you can't assume this. $("form[0]").submit() will submit the first form on the page. However, you can have more than one form on an ASP.NET page, though only one of these forms can be a server-side form (with runat="server" attribute).
If what you want is to submit the server-side form on an ASP.NET page then I think the best way would be to do it in code-behind by registering a script. It's a bit more hassle, but should always work (and when there is no server-side form it will detect it). Something like this:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (this.Form != null)
{
string js = String.Format("$('#{0}').submit()", this.Form.ClientID);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Submit", js, true);
}
}
These will:
$("#aspnetForm").submit()
or
var theForm = document.forms['aspnetForm'];
theForm.submit()
If you know that this code will be triggered by an input or button element within the ASP.NET form, or if you can select a known input or button element within the ASP.NET form, you can use input.form.submit();.
Usage examples
this.form.submit();
or
$("#some_input_or_button").get(0).form.submit();
Although reading the input.form/button.form property does not use jQuery, it is at least as cross-browser since jQuery itself does this.
Benefit: This method allows you to avoid dependence on the form ID generated by ASP.NET's internals without having to add any extra wiring server-side.

What is the recommended method to Validate an ASP.net Control with an existing method?

I am wondering what the prefered method of validating user input in asp.net using an existing method call is. I have implemented this a couple of ways now and while they all work I get the sense that there might be a better or "optimal" method?
I have an asp.net textbox
<asp:TextBox ID="myTextBox" runat="server" />
I also have a couple existing methods available to me on the objec that the form will eventually populate and save
public static bool IsNameValid()
public bool IsValid()
I'm wondering how people would wire up those items to a validation control (I'm assuming customValidator?). I'd like to avoid rewriting the validation in JavaScript (to avoid duplication of code).
Use a CustomValidator, and set the EnableClientScript property to false, forcing it to go to the server for validation. Then in the custom validator's ServerValidate method, set the args.IsValid property to the result of your methods above.
The advantage to using the validator is that when you go to your "submission" method for the form, you can wrap the final processing logic around a If Page.IsValid() block, which will make sure all validators come back as true before processing.

jQuery Validation in ASP.NET Pages

I am using jQuery and jQuery.validate plugin to validate ASP.NET pages, since I found jQuery Validation plugin better than ASP.NET validation controls.
I have used This validation code for Login and simultaneously for other pages like register and many others.
//.NET code
Dim jsValidate As String = String.Format("Validators.validateLogin('{0}','{1}');", _
txtUsername.ClientID, txtPassword.ClientID)
btnLogin.Attributes.Add("onclick", jsValidate)
//javascript code
Validators.validateLogin = function(txtUsername, txtPassword) {
$('#aspnetForm').validate();
$('#'+txtUsername).rules('add', {
required: true
});
$('#'+txtUsername).rules('add', {
required: true
});
}
Now the problem I am facing is if I have multiple controls on a page which require or not require validation. How to handle that situation. Bcoz once someone clicked on Login button it starts validation function and on pressing on some other button in some other control, it stuck with current validation. I wish if jQuery validation plugin can handle some groups like ASP.NET validationGroup, it could be a lot easier. Anyone have suggestions?
Thanks in Advance
You might try overloading CSS classes as validation groups. Basically you could filter out the controls whose class didn't match a specific pattern and only validate against those. Kind of a hack but it might just work for you.

what is the built-in javascript function to return the validator state in asp.net

This is a bit of a tough question to ask. I am using asp.net validators, but I want to tie them to a simple click event which I bind with jQuery.
I have found that I can use:
ValidatorValidate($("#<%= rfvFirst.ClientID %>")[0]);
to fire the rfvFirst validator, but I do not know how to get the actual false return somewhere to tell me that the form is not valid.
All I need is the function or variable or property that I can call on (client side) to tell me if the form is valid.
I hope that makes sense, thank you.
If your using validation groups you can do:
if (Page_ClientValidate('Group Name'))
{
//Valid
}
Page_IsValid would tell you whether the Page is valid. you can also use the isvalid property of the validator to validate the individual validator.

Resources