Building a Windows 8 Required Validator Control

Coming from an ASP.NET background, I’ve been used to the way ASP.NET validates user input.  ASP.NET made validation easy; a developer simply dropped a RequiredFieldValidator onto a web form, linked it to the control to validate, supply a set of initialization parameters, and voila, validation problem solved.  Of course, you’d run into some common configuration problems, some easily solved by validation groups, while others solved by some manual method calls.  This worked from the concept of web development, and it has some practicality in a Windows world, and as such, this article is going to look at building a similar capability in WinJS.  Note that I never meant for this component to encompass all validation scenarios, so you may find some faults in my implementation (feel free to point them out in the comments).

To start, we need a class.  Classes have always varied in implementation in the JavaScript world.  The approach WinJS uses is nothing new, but may be a hybrid of existing techniques.  A class starts with a WinJS.Class.define method call.  Define has the following signature:

define(function() { /* constructor */, { /* instance methods */ }, { /* static methods */ }

In our required validator example, we need to define our class as such:

var requiredValidator = WinJS.Class.define(

function (element, options) {
this.element = element;
this.element.winControl = this;        this._errormessage = null;
this._isvalid = true;
this._mode = “text”;
this._targetID = null;
this._text = null;

WinJS.UI.setOptions(this, options || {});

this._buildVisualTree();

var list = window[“Validators”];

if (!list)
list = [];

list.push(this);

window[“Validators”] = list;

},

.

.

);

The first parameter of the define method is the constructor (which is also the only one visible here), which performs a variety of steps.  The first wo steps are common with WinJS controls; we first store the element in an instance field, followed by creating the winControl object reference common through all WinJS component in the framework.  Ever wondered how other windows controls worked when you saw this code: document.querySelector(“#idofwindowscontrol”).winControl?  The setting of the winControl property above establishes the linkage.  Our validator needs to store data in variables defined on the instance (hence the this._X references), and supply them with defaults.  These store the options of the control, and are exposed as properties (which we’ll see later on).  For instance, you probably have seen usage of the data-win-options properties on WinJS control.  Suppose our validator has a configuration of data-win-options=”{text:’$$’, targetID:’#target’}”; the control receives these values in the constructor (via the options parameter), and the values are supplied to the text and targetID values through the control’s properties.  The setOptions method is the way to make this all happen.

Note that the control adds itself to a collection in the windows object; this way, the entire page  can access all of the validators on the view, similar to how ASP.NET provides all of the validators through it’s Page.Validators property.

The next code sample begins our instance methods, or the body of the class.  Notice WinJS (and IE 10 which runs the WinJS application) has a notation for properties using “get:” and “set:”, something that was missing in previous implementations of IE.  The first set of methods are actually property definitions (which consist of getter and setter methods):

errormessage: {
get: function () {
  return this._errormessage;
},
set: function (value) {
  this._errormessage = value;
}
},isvalid: {
get: function () {
  return this._isvalid;
},set: function (value) {
  this._isvalid = value;
  this._changeVisibility();
}},

Each of these properties has a get and set method, interacting with the instance variables defined in the constructor.  Even though the define method has separate method calls, we’re constructing one class, and as such, this just works.

In the class definition, the required validator also defines instance methods.  The following method builds the UI via traditional means, and styles it appropriately.  Nothing special here; it really doesn’t have to be.

_buildVisualTree: function () {
var el = this.element;
el.innerHTML = this.text || this.errormessage;
el.style.display = “none”;WinJS.Utilities.addClass(el, “Validator”);
},

Finally, we get to the main highlight of the control, which is the process for validating the content. Our validator first checks that the input of the control has been provided, and our target element has a valid length string.

_getValue: function() {
    var el = document.getElementById(this.targetID);
    var val;

    if (typeof (el.value) !== “undefined”)
        val = el.value;
    else
        val = el.innerHTML;

    return val;
},

validate: function () {
    var val = this._getValue();
   
    this.isvalid = !!val;
    this._changeVisibility();

    this.dispatchEvent(“validated”, { value: val, isValid: this.isvalid });

    return this.isvalid;
}

We have our validator, of which we can define as many as we want on the page. In ASP.NET, a postback to the page, when the control has it’s CausesValidation property set to true, invokes the validation process. Since we don’t have that here, I added one additional class, whose responsibility it is to trigger the validation, which is something we’ll look at in the next post (including it in this post made the post too long).

Advertisements

One thought on “Building a Windows 8 Required Validator Control

  1. Pingback: Custom Validator Execution in Windows Store Apps, Part 2 | On All Things Web

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s