This small but powerful script lets you add javascript validation to your forms quickly and with very little effort. No programming experience is necessary, but it’s fully extensible to allow programmers to augment the built-in validation rules with their own.

Contents


Features

RSV comes with a number of validation rules for the more common tasks, including:

  • Checking required fields
  • Email validation
  • Checking input field lengths: exact minimum or maximum lengths
  • Date validation
  • Integers: checking ranges, in between, greater than, less than
  • Regular Expressions or “custom alpha” (layman’s regexps)
  • Alphanumeric or letters only
  • Nested conditional testing (if field A == something, then validate field B)

But also, the script is fully extensible to allow you to write your own custom validation routines to be integrated with the script.

The configuration options include:

  • The choice of displaying the errors to the user sequentially (a single alert box showing the first error, which re-appears whenever the user resubmits the form), all at once (an single alert box containing all errors) or by displaying the errors as HTML in the page, via DHTML.
  • An option to highlight (via a custom CSS class) all offending fields and auto-focus on the first field for ease of use.
  • For advanced users, there is the option of passing all error information to a custom function to manage the errors as you see fit.
  • Also for advanced users is the option to define a custom onComplete function which gets called when the form validation is successful.

To see a demonstration of various configuration patterns, take a look at the demo pages.

Getting Started

Okay, let’s get started! To my mind, the quickest way to learn how to implement this script is to take a look at the demo forms. Personally, I always learn much quicker from viewing examples. But for those of a different stripe, here’s some step by step instructions.

  1. First, download the latest compressed javascript validation file (it looks like jquery.rsv-X.Y.Z.min.js) from github and upload it to the same folder containing your webpage. Import the code in between your webpage’s …, after including the main prototype.js library, like so:

    1
    2
    <script src="prototype.js"></script>
    <script src="prototype.rsv-X.Y.Z.min.js"></script>

    Obviously you can put the file wherever you want, but be sure to point to the right location. Note: change X.Y.Z to whatever the latest version is – you’ll see it on github.

    Note: You can either use the minimized or unminimized version (prototype.rsv-X.Y.Z.js). But unless you’re planning on modifying the code, I would suggest using the compressed version since it’s smaller for browsers to download.
  2. Next, add the form-specific validation code and customizable settings. Here’s an example of a typical configuration:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Event.observe(window, "load", function() {
      new RSV({
        formID: "demo_form1",
        errorFieldClass: "errorField",
        rules: [
          "required,first_name,Please enter your first name.",
          "required,last_name,Please enter your last name.",
          "required,email,Please enter your email address.",
          "valid_email,email,Please enter a valid email address."
        ]
      });
    });

    The Event.observe() function should probably be familiar, if you’ve used Prototype before. It creates an instance of the RSV class on page load. This class defines all the settings for the validation as well as the rules that need to be checked.

    First, the formID parameter is required. This specifies the ID of the form tag in your page: you must add an id attribute to your form tag to uniquely identify it for the RSV script.

    Secondly, the (optional) errorFieldClass setting defines the name of a CSS class that determines the appearance of those fields that fail any of the validation rules. This is nice and configurable in that you can (a) call the CSS class whatever you want and (b) use whatever CSS you want.

    Thirdly, we have the rules parameter. This is an array of strings, each string being a separate validation rule. In the example above we’re checking that the first name and email fields have a value, and that the email address is valid. Each line adds a new validation rule to the list and are all of the following form:

    1
    "[if:FIELDNAME=VALUE,]REQUIREMENT,fieldname[,fieldname2[,fieldname3,date_flag]],error message"

    The square bracket [] notation indicates that the contents are optional, depending on the REQUIREMENT rule used by the line. Note: if you need to includcommas in the error messages you must escape them with two double-slashes, like so: \\,

    Available Validation Rules

    To recap, validation rules are strings of the following form:

    1
     "[if:FIELDNAME=VALUE,]REQUIREMENT,fieldname[,fieldname2[,fieldname3,date_flag]],error message"

    The square bracket [] notation indicates that the contents are optional. Note: if you need to include commas in your error messages, you must prefix them (“escape” them) with two backslashes like so: \\, otherwise your error message will appear truncated.

    if:FIELDNAME=VALUE, or
    if:FIELDNAME!=VALUE,

    This allows us to only validate a field only if a fieldname has – or doesn’t have –
    a particular value. This option allows for nesting; i.e. you can have multiple if clauses, separated by commas. They will be examined in the order in which they appear in the line.

    Valid REQUIREMENT strings are:

    required field must be filled in
    digits_only field must contain digits only
    length=X field has to be X characters long
    length=X-Y field has to be between X and Y (inclusive) characters long
    length>X field has to be greater than X characters long
    length>=X field has to be greater than or equal to X characters long
    length<X field has to be less than X characters long
    length<=X field has to be less than or equal to X characters long
    valid_email field has to be valid email address
    valid_date field has to be a valid date

    fieldname: MONTH field
    fieldname2: DAY field
    fieldname3: YEAR field
    date_flag: “later_date” / “any_date”

    same_as fieldname is the same as fieldname2 (for password comparison)
    range=X-Y field must be a number between the range of X and Y inclusive
    range>X field has to be a number greater than X
    range>=X field has to be a number greater than or equal to X
    range<X field has to be a number less than X
    range<=X field has to be a number less than or equal to X
    is_alpha field has to be an alphanumeric character (anything between 0-9, a-Z)
    custom_alpha This option is a layman’s version of the reg_exp rule and offers more control
    than the letters_only rule. It lets you check that a field is formatted in a very
    specific way. For example:
    1
    2
    // this requires the "field_name" form field be of the form: {any letter}{uc letter}{lc consonant}{lc consonant}
    rules.push("custom_alpha,field_name,DLcc,Error message");
    Here’s all the different formatting options and what each character means:

    L An uppercase letter. V An uppercase vowel.
    l A lowercase letter. v A lowercase vowel.
    D A letter (upper or lower) F A vowel (upper or lower)
    C An uppercase Consonant x Any number, 0-9
    c A lowercase consonant X Any number, 1-9
    E A consonant (upper or lower)

    Any characters included in the string that aren’t in the above list are simply required as they are. So if your rules was CVC-VCV, the user would have to enter consonant, vowel, consonant followed by a dash, followed by vowel, consonant, vowel.

    reg_exp This option is for programmers. It lets you validate a field by a regular expression. This rule comes in two forms: one with a RegExp flag (like “g” for global, “i” for case-insensitive etc.) and one without. Unless you expressly need to supply a flag, just use the first format.
    1
    2
    3
    4
    5
    // Format 1:
    rules.push("reg_exp,field_name,REGEXP,Error message");

    // Format 2
    rules.push("reg_exp,field_name,REGEXP,Flag(s),Error message");
    Note: be sure to double-escape regexp escape characters. e.g. to match whitespace,
    the \s needs to be \\s; commas also need to be double escaped: \\,
    letters_only field has to be a letter, a-Z (upper or lowercase)

    function This option is included for programmers. You may find that you need to supplement the existing functionality with your own custom validation rules. See the page on custom functions for more information about this rule.

    Notes: With the digits_only, valid_email and custom_alpha rules, if the empty string is passed in it won’t generate an error, thus allowing validation of non-required fields. So, if you want a field to be both required AND a valid email address, provide separate rules for both “required” and “valid_email” for that single form field.

    Configuration Options

    When defining your RSV class instance, you can include any of the following options. Only the formID and rules properties are required. Let’s take a look at each setting in turn.

    formID The ID of the form.
    rules An array of validation rules (strings).
    displayType This determines how the error messages should appear to the user. There are three options:

    alert-all This is the default setting. When a user submits the form containing one or more errors,
    a popup appears listing all errors. By default, offending fields are not styled. To style the offending
    fields, you need to create a CSS class and set the errorFieldClass property.
    alert-one When a user submits the form containing one or more errors, a popup appears listing the first error. After
    they fix it and re-submit, a new popup appears for the next error – and so on. This was the default
    behaviour of version 2.3 and earlier. As with the previous alert-all option, you may also customize the appearance
    of the offending fields by errorFieldClass property.
    display-html This is the coolest option. Instead of relying on the browser’s (rather unsightly) popups, you can
    instead insert the errors directly into your webpage as HTML, styled however you want.
    To do this, you need to add an element to your page, like so:

      <div id="rsvErrors"></div>

    The id parameter must have the same value as the errorTargetElementId
    setting. You may also wish to hide and style the element with CSS (when errors occur, the script automatically
    displays the element by changing the display property to “block”). Here’s an example of how to style that page element:

    1
    2
    3
    4
    5
    6
    7
    8
    <style type="text/css">
    #rsvErrors {
      display: none;
      background-color: #ffffcc;
      border: 1px solid red;
      padding: 8px;
    }
    </style>
    errorTextIntro This value determines the string that appears before the list of errors. It is only used for the alert-all
    and display-html display options. The default string is: “Please fix the following error(s) and resubmit:”
    errorJSItemBullet This is used for the alert-all display option. It determines the bullet character for each
    error that occurred. Default value: an asterix (*).
    errorTargetElementId This is used for the display-html option. It specifies the ID of the HTML element
    where the error messages will be inserted. It defaults to: “rsvErrors”.
    customErrorHandler This is for people that are comfortable with javascript and who need a little more control over how the errors are presented.
    It lets you define your own custom function that gets passed the list of errors that occur on a form submit. Here’s
    a simple example that alerts each error in turn. Note: the two function parameters MUST be set in order to be passed
    the error information properly.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
      Event.observe(window, "load", function() {
        new RSV({
          formID: "demo_form1",
          customErrorHandler: myReturnFunction,
          rules: [
            // ...
          ]
        });
      });
     
      /**
       * @param f the form node
       * @param errorInfo an array of arrays. Each sub-array has two elements: the field node and the error message.
       */

      function myReturnFunction(f, errorInfo) {
        for (var i=0; i<errorInfo.length; i++) {
          // errorInfo[i][0] contains the form field node that just failed the validation, e.g.
          errorInfo[i][0].focus();
          errorInfo[i][0].style.color = "red";
     
          // errorInfo[i][1] contains the error string to display for this failed field, e.g.
          alert(errorInfo[i][1]);
        }
        return false; // always return false! Otherwise the form will be submitted
      }
    Take a look at demo form #7 for another example of this.
    onCompleteHandler This option lets you pass off the control flow to your own function once everything validates properly. This can be handy if you need to perform extra tasks like store information in hidden fields, select values in multi-select boxes and other things prior to submitting the form. All you need to do is enter your function name:
    1
    2
    3
    4
    5
    6
    7
    8
    9
      Event.observe(window, "load", function() {
        new RSV({
          formID: "demo_form1",
          onCompleteHandler = myFinalFunction,
          rules: [
            // ...
          ]
        });
      });

    Then define your function like so:

    1
    2
    3
    4
      function myFinalFunction() {
        // ...
        return true;
      }
    To submit the form your function just needs to return true, otherwise it should return false.

    Custom Validation Rules

    Even though the built in validation rules are pretty generic, there’s always going to be a situation where you need to do some custom validation. Before version 2.2 you had to do some creative hacks to let this happen, but now you can embed your own custom functions directly within the other rules so that the sequential execution of each rule will continue to function, and you can ensure your custom validation occurs and is displayed at the appropriate spot. The format of the rule is very simple:

    1
    rules.push("function,your_function_name");

    Then, you need to define your own javascript function your_function_name. This function cannot take any arguments.

    From comparing this function rule with the other built-in validation rules, you’ll notice a few things that are different:

    1. There’s no mention of a particular field in the rule. This is deliberate. Since I really have no idea what validation you plan on adding, it may be using multiple fields so there was no point passing along a single value. You will need to directly access the field values themselves within your custom function.
    2. The function name doesn’t have a “()” following it. Don’t add it; it’s added by the code.

    In order for your function to interact properly with the RSV script, your function must have a well-defined return value. Namely:

    1. If the field passes whatever test or tests you administer, it must explicitly return true.
    2. If it fails the test(s), it has to return an array of arrays, like so:
    1
    return [[node1, "error message1"], [node2, "error message2"], [node3, "error message3"]];

    Or if your function is just throwing a single error:

    1
    return [[node, "error message"]];

    Note the double [[ and ]]. That’s not a typo!

    An example

    Here’s a simple example from one of the demo forms. It checks to see if a field is a prime number under 100 and if it fails, returns the error message which will be displayed by the RSV script according to the config options specified.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function my_custom_function() {
      var prime_nums_str = "1|2|3|5|7|11|13|17|19|23|29|31|37|41|43|47|53|59|61|67|71|73|79|83|89|97";
      var prime_numbers = prime_nums_str.split("|");
      var val = document.getElementById("prime_number").value;
     
      var is_valid_num = false;
      for (i=0; i<prime_numbers.length; i++) {
        if (prime_numbers[i] == val) {
          is_valid_num = true;
        }
      }
     
      if (!is_valid_num) {
        var field = document.getElementById("prime_number");
        return [[field, "Please enter a prime number under 100"]]; // returns a single error message
      }
     
      return true;
    }

    Demo Forms

    There’s no better way to help you better understand the script its functionality by seeing it in action. So here are a few demo forms that highlight the various configuration options, build in validation rules, custom rules and examples of how to extend the script.

    Demo forms

    Other Comments

    JS vs. PHP Validation

    This script was written to be identical to the PHP Validation sister script, so you can just copy and paste the rules from one to the other. If you’re a PHP programmer, you may want to take a look at it!

    Download

    This script is found here on github. Just go to the prototype folder and download the appropriate file, as was explained above.

    Just FYI, the compression is done using Douglas Crockford’s JSMIN script – it’s a handy tool. Check it out!