ASP Valid-o-matic
Generate the validators for standard SQLServer datatypes (MSDN SQLServer-.Net datatype translation)
Change IDs and ControlToValidate (plus errormessages if required). NB bigint is a Currency type for validation purposes; int is the same so uses compareValidator instead of a rangeValidator.
MinimumValue="1753/01/01"
MaximumValue="9999/12/31"
Type="Date"
Text="*" ErrorMessage="Must be between 1753 and 9999" ToolTip="Must be between 1753 and 9999"
Display="Dynamic" runat="server"/>
- Remember Page.Validate() is called AFTER Page.Load (and not if control.CausesValidation=false).
- Currency type doesn't work with currency symbol. Beware when binding:
Text='<%# Bind("Money", "{0:C}") %>'will not validate! (even with new CultureInvariant flag) - Default Display="Static" which hides the message (or asterisk) with visibility (vertical alignment problems)- use Dynamic or None with a ValidationSummary
- To validate user and custom controls, add ValidationPropertyAttribute("valueproperty")
- ASP 2- Putting sets of controls into ValidationGroups is useful.
- See also Business Validation class for server side "business" errors
Highlight on error
Version 1: (Very) basic. To change the control dynamically, add (clientside) onchange function pointing to the control and validation id / clientID (in the latter case, inject via ScriptManager)
function MyFieldOnChange() {
// Do nothing if client validation is not active
if (typeof(Page_Validators) == "undefined") return;
// Change the color of the label
MyField.style.color = MyFieldValidator.isvalid ? "Black" : "Red";
}
Version 2: Asp Ajax methods. The pageLoad initialization uses asp ajax methods ($addhandler == addEvent, $get == document.getElementById) but you can also use onchange="showIfError(this)".
function pageLoad() {
if($addhandler) { //or your addEvent
for (var i = 0; i < Page_Validators.length; i++) {
var v = Page_Validators[i];
var id = v.controltovalidate;
var ctl= $get(id);
//if is textbox, monitor the change event
if(obj.type && (obj.type == 'text' || obj.type == 'textarea')) {
$addhandler(ctl, "change", showIfError);
}
}
}
}
function showIfError(obj) {
if(!checkValidators(obj.id) && obj.className.indexOf(" error") == -1)
obj.className+= " error";
else
obj.className = new String(obj.className).replace(new RegExp("(?:^|\\s+)error(?:\\s+|$)", "g"), '');
}
function checkValidators(id) {
for (var i = 0; i < Page_Validators.length; i++) {
var v = Page_Validators[i];
if(v.controltovalidate == id) { //validate just this field
ValidatorValidate(v); //force a validation
if (v.isvalid == false) return false; //not valid
}
}
return true;
}
Version 3: JQuery. Here's a slightly more evolved JQuery script, which survives postbacks and sets the control with a class of "error".
$(document).ready(function() {
if (self.ValidatorUpdateDisplay) {
BaseValidatorUpdateDisplay = ValidatorUpdateDisplay;
ValidatorUpdateDisplay = function(val) {
BaseValidatorUpdateDisplay(val);
$(function() {
var errorCssClass = 'error';
var ctl = document.getElementById(val.controltovalidate);
if (ctl == null)
return;
var vals;
if (!ctl.Validators)
return;
var vals = ctl.Validators;
var showerror = false;
for (var i = 0; i < vals.length; i++) {
if (!vals[i].isvalid) {
showerror = true;
break;
}
}
if (showerror) {
$(ctl).addClass(errorCssClass);
}
else {
$(ctl).removeClass(errorCssClass);
}
});
}
}
//loop thru Page_Validators
if (self.Page_Validators)
return;
var i, val;
for (i = 0; i < Page_Validators.length; i++) {
val = Page_Validators[i];
if (!val.isvalid && val.controltovalidate.length > 0) {
var ctl = document.getElementById(val.controltovalidate);
if (ctl != null) {
$(ctl).addClass('error');
}
}
}
});