free tracking

ValidateThis and Custom Rules and Conditions


This is PART THREE in my ValidateThis Series.

In my previous posts on the ValidateThis series, I introduced you to ValidateThis and its Rules (PART I) and then I showed you how you might overcome issues with multiple objects (PART II). Today’s post is an extension of those other posts. In the last post I left you wondering why I had a function in my combined object called user.cfc. Below, I am displaying function once again.


user.cfc – function isUniqueUsername.


  function isUniqueUsername(){
    var codeCheck = ormExecuteQuery("FROM users WHERE username='#username#'");
    var isResult = arraylen(codeCheck) == 0 ? 1 : 0;
    return isResult;
  }

ValidateThis allows for various rule types, but the “custom” rule is probably the most advanced – because you get to create your own rules. Now the predefined rule types are exhaustive, but there are times where you can’t complete your validations with just predefined rules. In my previous posts, I was dealing with a simple user form. This form contains elements like name, username, password, email, and more. But what if I want some data integrity on the username field? In other words, I don’t want two of the same username. After all … one askBenore user is enough. This is precisely where custom rules come in handy.

Here just a snippet of my username rule in JSON format.


  {"NAME":"username","DESC":"Username","RULES":
    [
      {
        "TYPE":"required"
      },
      {
        "TYPE":"regex",
        "FAILUREMESSAGE":"The Username can only contain alpha characters.",
        "PARAMS":
        [
          {"NAME":"regex","VALUE":"^[A-z]+$"}
        ]
      },
      {
        "TYPE":"custom",
        "CONDITION":"Add_Or_EditNotCurrentUsername",
        "FAILUREMESSAGE":"The Username already exists, please try another.",
        "PARAMS":
        [
          {"NAME":"methodName","VALUE":"isUniqueUsername"}
        ]
      }
    ]
  }

As you can see I have 3 rules defined for username. First, the username is required. That rule is simple enough as it checks to see whether or not data is entered in the username field. Second, I am using a regex rule to make sure the username is only alpha characters (you know … letters). I don’t want there to be a “askBenore2″. Third, is my custom rule. The custom rule needs to call a method within the object you pass. As you can see above you declare the object’s method in the param “methodName”. So if you are passing over a form scope to ValidateThis, that simply will not do. The ValidateThis documentation on custom rules is a bit sketchy on the second param type called “remoteURL”, so I am not going to discuss it.

The custom rule works pretty simply. The method must exist in the object you are passing over. My function, isUniqueUsername, becomes a method when the user.cfc is called as an object. Since the object also contains the username value, there is nothing I have to pass as username is already part of the object. Now I use a little ORM HQL to query the database for other usernames with the one provided in form.username. If the ORM HQL returns 0 records I view that as a true or 1+ records as a false. ValidateThis does the rest. Typically you will return a boleen statement.

Finally, I also have a CONDITION that is placed on the custom rule. Conditions can be placed on any of the rule types. If the condition is met, then the rule is used to check the form. If the condition is not met, the rule is skipped. In this case, my condition is called “Add_Or_EditNotCurrentUsername”. My naming convention is not important, but I like things to be easy to read for future developers. So in this case my condition reads like: it can either be an “add” form OR an “edit” form as long as the username you are preposing is not the current username. It would be silly to check for the existence of the current username, because it will indeed exist. So on an edit form, we only want to check the database for the existence of a username if the username is changing. The condition is written before your OBJECTPROPERTIES element and in JSON would look like this:


"CONDITIONS":
  [
    {
      "NAME":"Add_Or_EditNotCurrentUsername",
      "SERVERTEST":"(NOT isDefined('cmsUserId')) OR (isDefined('cmsUserId') AND oldUsername IS NOT username )"
    }
  ]

Custom rules and conditional based rules are just another easy, yet powerful part of the ValidateThis toolset. Special thanks to Bob Silverberg and his team for developing such a great framework.

,

  1. No comments yet.
(will not be published)