Section 5.2. Data Validation


5.2. Data Validation

In addition to providing controls for data binding, Atlas ships with its own controls for validating data the user enters, a feature that many ASP.NET developers find useful. Atlas supports the following validators:


requiredFieldValidator

Checks whether the user has entered a value into a control


regexValidator

Checks the data in a control against a regular expression to match a pattern


typeValidator

Checks the data in a control against a data type


rangeValidator

Checks the data in a control against a value range


customValidator

Checks the data in a control using a custom validation function

To implement data validation, you need:

  • A control to validate

  • A way to display an error message if the validation fails

  • Code or markup to do the validation

In the following sections you'll see how to put each of the Atlas validators to work, including how to do your own custom validation.

5.1.3. Checking a Required Field

The requiredFieldValidator class, which checks whether a control contains data, is a commonly used Atlas data validator. The following markup generates both an input field and a span to display any error messages that the validator generates:

 <input type="text"  /> <span  style="color: red;">*</span> 

As you can see, the label for the error message is not hidden by default. Atlas takes care of hiding it automatically.

In the xml-script for the page, add markup for the HTML elements taking part in the validationjust the elements, not any controls for displaying errors. In the <validators> subelement, specify the validator to use. The errorMessage property contains the text to display if validation fails. However, the Atlas validator is different than its ASP.NET counterpart. In Atlas, the value of the errorMessage property is used as a tool tip that appears when you hold the mouse pointer over the error text (that is, over the Atlas validator control). Speaking of error text, there is no equivalent for the Text property of ASP.NET validation controls. The error text appearing in the label is the text that is already there.

 <textBox >   <validators>     <requiredFieldValidator errorMessage="** TextBox1 value missing" />   </validators> </textBox> 

The second step is to use the <validationErrorLabel> element with the following attributes:


targetElement

The ID of the control to display errors


associatedControl

The ID of the element to validate

A complete page with validation is shown in Example 5-6.

Example 5-6. Using a validator for required fields

 ControlValidationRequiredField.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>     <input type="text"  />     <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">     <components>     <textBox >     <validators>     <requiredFieldValidator errorMessage="** TextBox1 value missing" />     </validators>     </textBox>     <validationErrorLabel      associatedControl="TextBox1" />     </components>     </page>   </script> </body> </html> 

Load the page, enter some data in the text field, leave the text field (which raises the change event). Then enter the field again, delete its contents, and leave the field again. For the second time the change event is raised, and this time the validation control is triggered. The error text appears; the (longer) message is displayed as a tool tip, as shown in Figure 5-4.

Figure 5-4. The error text, including more information in the tool tip


5.1.4. Checking Against a Regular Expression

Using a regular expression to check the validity of data works just like the ASP.NET requiredFieldValidation control, but the name of the XML element and its attributes are different. The regex property (or attribute, depending on whether you are using code or markup) provides the regular expression the validator uses to check the data:

 <regexValidator regex="/\d*/" errorMessage="** digits only" /> 

The code shown in Example 5-7 contains two validators: one checks whether there is anything in the text field, and the other one allows only digits. (You could also achieve this using a data type check.)

Example 5-7. Using an Atlas validator with a regular expression

 ControlValidationRegex.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>         <textBox >           <validators>             <requiredFieldValidator errorMessage="** TextBox1 value missing" />     <regexValidator regex="/\d*/" errorMessage="** digits only" />           </validators>         </textBox>         <validationErrorLabel                                associatedControl="TextBox1" />       </components>     </page>   </script> </body> </html> 

5.1.5. Checking the Data Type

The <typeValidator> element checks the data type of a value. The only data type currently supported is Number, but other types are likely in future releases. The type property of the <typeValidator> element contains the data type:

 <typeValidator type="Number" errorMessage="** numbers only" /> 

The code shown in Example 5-8 uses both a requiredFieldValidator and typeValidator to check for numeric values only.

Example 5-8. Using a validator for a data-type check

 ControlValidationType.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>         <textBox >           <validators>             <requiredFieldValidator errorMessage="** TextBox1 value missing" />     <typeValidator type="Number" errorMessage="** numbers only" />           </validators>         </textBox>         <validationErrorLabel                                associatedControl="TextBox1" />       </components>     </page>   </script> </body> </html> 

This data type check is not a real numeric check. It just calls the JavaScript function parseInt() and determines whether the conversion fails (i.e., the result is NaN). However, strings that begin with a number, such as 123xyz, can be converted into a number (123). Therefore, this approach is not bullet-proof and you may be better off using a regular expression like this one:


 0|[1-9][0-9]* 

5.1.6. Checking a Range

Sometimes a value must not only be numeric, but must also have a value that lies within in a certain range (for instance, this is true for time intervals or dates). In that case, you can use the <rangeValidator> element. You set the lower and upper bounds in the lowerBound and upperBound properties. The following markup shows how to check for a value between 1 and 6:

 <rangeValidator lowerBound="1" upperBound="6" errorMessage="** 1 to 6 only" /> 

Example 5-9 builds on the preceding example. The data is checked not only with a requiredFieldValidator and a typeValidator, but with a rangeValidator as well.

Example 5-9. Using a validator for a valid range

 ControlValidationRange.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>         <textBox >           <validators>             <requiredFieldValidator errorMessage="** TextBox1 value missing" />             <typeValidator type="Number" errorMessage="** numbers only" />     <rangeValidator lowerBound="1" upperBound="6" errorMessage="** 1 to 6 only" />           </validators>         </textBox>         <validationErrorLabel                                associatedControl="TextBox1" />       </components>     </page>   </script> </body> </html> 

5.1.7. Custom Validation

To achieve the greatest flexibility, you can write a custom function to validate user data: a custom validator. The signature for your validation function is as follows:

 function <name>(sender, args) { } 

From the second parameter, the value to validate can be retrieved using get_value(). After validation, you call the set_isValid() method. If validation succeeds, pass true as parameter; otherwise, pass false.

Let's imagine that for some inexplicable reason, only square numbers may now be entered into the text field. The following function does the validation:

 function validateSquare(sender, args) {   var value = args.get_value();   args.set_isValid(Math.sqrt(value) == Math.floor(Math.sqrt(value))); } 

In the xml-script, the <customValidator> element must include a validateValue attribute that references the custom validation function:

 <customValidator validateValue="validateSquare" errormessage="** square numbers only" /> 

The Visibility Mode of a Validation Control

One property of validation controlsor, to be exact, of <validationErrorLabel> elementshas not been covered yet: visibilityMode. Two values are possible (via the Sys.UI.VisibilityMode enumeration):

  • Collapse

  • Hide

The display style (or in JavaScript: element.style.display) is set to this mode. If no visibility mode is provided, "none" is used. This controls how the validation error Label control is hidden when the page has been loaded.


Example 5-10 shows the complete code for this custom validator.

Example 5-10. Using a custom validator

 ControlValidationCustom.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title>   <script language="JavaScript" type="text/javascript">   function validateSquare(sender, args) {     var value = args.get_value();     args.set_isValid(Math.sqrt(value) == Math.floor(Math.sqrt(value)));   }   </script> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>         <textBox >           <validators>             <requiredFieldValidator errorMessage="** TextBox1 value missing" />             <typeValidator type="Number" errorMessage="** numbers only" />             <customValidator validateValue="validateSquare" errorMessage="** square numbers only" />           </validators>         </textBox>         <validationErrorLabel                                associatedControl="TextBox1" />       </components>     </page>   </script> </body> </html> 

5.1.8. Programmatic Validation

The declarative approach fares well in practice, but there is a programmatic approach to validation as well.

You do need some declarations for it, though, like this:

 <textBox >   </textBox>   <validationErrorLabel                          associatedControl="TextBox1" /> 

You can then create the validator using JavaScript code. It is not easy to guess how it is done. Two steps are required:

  • Add the validator: element.get_validators().add(validator).

  • If you want to use a callback function (a function being called when the validation has occurred), use : element.validated.add(function).

To access the element to validate, you cannot get an instance of the control with the usual new Sys.UI.XXX approach. Instead, you must use the stranger-looking syntax that you have saw when we covered preventing form submissions:

 var textbox = $("TextBox1").control; 

So, you are accessing the client-side element using the dollar sign and then accessing its control property. Example 5-11 shows a complete page that uses a programmatic approach to validation.

Example 5-11. Programmatically using a custom validator

 ControlValidationCustomProgrammatic.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title>   <script language="JavaScript" type="text/javascript">   function pageLoad() {     var textbox = $("TextBox1").control;     validator = new Sys.UI.RequiredFieldValidator();     validator.set_errorMessage("** enter some data");     textbox.get_validators().add(validator);     textbox.validated.add(validationComplete);   }   function validationComplete(sender, args) {   }   </script> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>         <textBox >         </textBox>         <validationErrorLabel                                associatedControl="TextBox1" />       </components>     </page>   </script> </body> </html> 

This of course also works for more complex validators, including the custom validator. In this particular case, the syntax for declaring the custom validation function is the following:

 validator.validateValue.add(validation function); 

Example 5-12 demonstrates how to combine both declarative validators and programmatic validators.

Example 5-12. Using declarative and programmatic validators

 ControlValidationRequiredFieldProgrammatic.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title>   <script language="JavaScript" type="text/javascript">   function validateSquare(sender, args) {     var value = args.get_value();     args.set_isValid(Math.sqrt(value) == Math.floor(Math.sqrt(value)));   }   function pageLoad() {     var textbox = $("TextBox1").control;     validator = new Sys.UI.CustomValidator();     validator.set_errorMessage("Square numbers only");     validator.validateValue.add(validateSquare);     textbox.get_validators().add(validator);     textbox.validated.add(validationComplete);   }   function validationComplete(sender, args) {   }   </script> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>     <textBox >     <validators>     <requiredFieldValidator errorMessage="** TextBox1 value missing" />     <typeValidator type="Number" errorMessage="** numbers only" />     </validators>     </textBox>     <validationErrorLabel      associatedControl="TextBox1" />       </components>     </page>   </script> </body> </html> 

5.1.9. Validation Groups

Validation controls can also be grouped by creating a <validationGroup> element that groups the controls you want to validate as a unit. All the validators in a validation group perform their test individually, but then you can test the group as a whole: if any of the validation checks failed, then the group has failed; if all the controls validate, then the group passes. Grouping is particularly useful for being able to enable and disable sets of validators conditionally.

The validation group exposes a method isValid() to determine whether the validation failed or not. This can be used in conjunction with data binding to display a message when the validation succeeds or fails.

First of all, you must provide an element to display the message:

 <div >-no errors-</div> 

Then you can bind this element's visible property to the validation group's isValid() method. In that case, the <div> element will be visible if all the validators in the group have passed.

 <label >   <bindings>     <binding dataContext="group" dataPath="isValid" property="visible" />   </bindings> </label> 

Now, to make the <div> element visible only if the validation fails, use the Invert transformer:

 <binding dataContext="group" dataPath="isValid" property="visible" transform="Invert" /> 

So, only one thing is missing: the validation group itself. It is represented by the <validationGroup> element. It needs an ID (the preceding markup used "group"), and within the group element, all form elements that take part in the validation are referenced, like this:

 <validationGroup  >   <associatedControls>     <reference component="TextBox1" />     <reference component="TextBox2" />   </associatedControls> </validationGroup> 

Example 5-13 shows a page with a validation group. In the page, the <div> element displays -no errors- when all the text boxes have passed validation. (Because the first text box has a required field validator, the <div> element is displayed only when that text box is filled in and the second text box contains a numeric value that's a square number.)

Example 5-13. Using a validation group bound to a label

 CustomValidationGroup.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title>   <script language="JavaScript" type="text/javascript">   function validateSquare(sender, args) {     var value = args.get_value();     args.set_isValid(Math.sqrt(value) == Math.floor(Math.sqrt(value)));   }   </script> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">     </atlas:ScriptManager>     <div>       Anything: <input type="text"  />       <span  style="color: red;">*</span>       <br />       A square: <input type="text"  />       <span  style="color: red;">*</span>       <br />       <input type="submit" />     </div>     <div >-no errors-</div>   </form>   <script type="text/xml-script">     <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">       <components>         <textBox >           <validators>             <requiredFieldValidator errorMessage="** TextBox1 value missing" />           </validators>         </textBox>         <validationErrorLabel                                associatedControl="TextBox1" />         <textBox >           <validators>             <requiredFieldValidator errorMessage="** TextBox2 value missing" />             <typeValidator type="Number" errorMessage="** numbers only" />             <customValidator validateValue="validateSquare" errorMessage="** square numbers only" />           </validators>         </textBox>         <validationErrorLabel                                associatedControl="TextBox2" />         <validationGroup >           <associatedControls>             <reference component="TextBox1" />             <reference component="TextBox2" />           </associatedControls>         </validationGroup>         <label >           <bindings>             <binding dataContext="group" dataPath="isValid" property="visible" />           </bindings>         </label>       </components>     </page>   </script> </body> </html> 

Figure 5-5 shows the result.

Figure 5-5. The label appears only when all text boxes are filled correctly





Programming Atlas
Programming Atlas
ISBN: 0596526725
EAN: 2147483647
Year: 2006
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net