Myna. Validation

A store for validation functions that can be used to validate objects

See: validate

Summary
Myna. ValidationA store for validation functions that can be used to validate objects
Functions
Myna. ValidationConstructs a Validation Object
clonemakes a copy of this Validation object, including validators, labels, and any custom validatorFunctions
addValidatoradds a validation function to this manager
addValidatorsadd multiple validators
removeValidatorremoves all validators for a property and optionally by == validator type
genLabelgenerates a display label from a property name
getLabelreturns the display label for a property name
setLabelsets an explicit display label for a property
setLabelssets an explicit display label for multiple properties at once
toCodereturns this Validation object as Javascript source-code
validateValidates an object against this Validation.
validatorFunctions.typeValidates basic type
validatorFunctions. lengthValidates length
validatorFunctions. valueValidates min/max value
validatorFunctions. regexValidates a value against a regular expression
validatorFunctions.listValidates a value against a list of values
validatorFunctions. requiredValidates that a value be supplied

Functions

Myna. Validation

Myna.Validation = function()

Constructs a Validation Object

clone

Myna.Validation.prototype.clone=function()

makes a copy of this Validation object, including validators, labels, and any custom validatorFunctions

addValidator

Myna.Validation.prototype.addValidator=function addValidator(property,
validator,
options)

adds a validation function to this manager

Parameters

propertyproperty to validate.  If this is set to null, then this validator will be called for every property
validatorEither a String or a validation function.  If this is a string, it must match one of the standard validation functions stored in <validatorFunctions>.  This function will be called when needed to validate property See Validator Function below
optionsOptional, default undefined any options needed by the validator

Validator Function

The validator function will be called with a parameters object with these properties

objObject being validated
propertyProperty being validated
labelresult of getLabel for property
valuevalue being validated
optionsvalidator options.  Most validators define their own specific options, but all validators accept the options below

Validator Options

whenA function that will take the same parameters as a validator function and return true if the validator should be run.  This is normally used conditionally validate one of the built-in validators

Returns

this validation instance

Examples

var v = new Myna.Validation()
v.addValidator("first_name","length",{
min:3,
max:25
})

//only validate spouse_name when married is true
v.addValidator("spouse_name","required",{
when:function(params){
return params.obj.married
}
})

function isBob(params){
var vr = new Myna.ValidationResult();
if (params.value != "Bob"){
var msg = params.options.message || params.label + " is not Bob!"
vr.addError(msg,colname)
}
return vr;
}

v.addValidator("first_name",isBob,{
message:"Inferior name entered."
})

addValidators

Myna.Validation.prototype.addValidators=function addValidators(validator_config)

add multiple validators

Parameters

validator_configJS Object keyed by property name, with sub-objects keyed by validator name (or “custom” for custom validators), with values equal to validator options (or {}, if no options)

Returns

this validation instance

Example

var v = new Myna.Validation()
v.addValidators({
name:{
required:{},
type:"string",
regex:{
pattern:/^[A-Za-z ]+$/,
message:"Names must only contain Letters and spaces"
}

},
dob:{
type:"date",
value:{
min:new Date().add(Date.YEAR,-150),
max:new Date()
}
},
children:{
type:"array",
length:{
max:12
},
custom:function(params){
var vr = new Myna.ValidationResult();
params.value.forEach(function(child,index){
vr.merge(this.validate(child),"child_" + index "_")
})

return vr;
}
}
})

removeValidator

Myna.Validation.prototype.removeValidator=function removeValidator(property,
validator)

removes all validators for a property and optionally by == validator type

Parameters

propertyname of property to modify
validatorOptional, default null If defined, this can be either a string or a function reference representing the specific validator to remove

if validator is undefined, then all validators for the property are removed

Returns

this validation instance

Example

v.addValidators({
name:{
required:{},
type:"string",
regex:{
pattern:/^[A-Za-z ]+$/,
message:"Names must only contain Letters and spaces"
}

},
dob:{
type:"date",
value:{
min:new Date().add(Date.YEAR,-150),
max:new Date()
}
},
children:{
type:"array",
length:{
max:12
},
custom:function(params){
var vr = new Myna.ValidationResult();
params.value.forEach(function(child,index){
vr.merge(this.validate(child),"child_" + index "_")
})

return vr;
}
}
})
// cloning Validation for children
var cv = v.clone()
cv.removeValidator("children")//children don't have children
//add in child specific validators
cv.addValidators({
relationship:{
required:true,
type:"string",
regex:{
pattern:/^(son|daughter)$/i,
message:'Relationship must be "Son" or "Daughter"'
}
}
})
// adding a single custom validator to test the children array members
v.addValidator("children",function(params){
Myna.printDump(params)
var vr = new Myna.ValidationResult()

params.value.forEach(function(child,index){
var prefix ="child[{1}].".format(name,index)
vr.merge(cv.validate(child),prefix)
})

return vr;
})

genLabel

Myna.Validation.prototype.genLabel=function genLabel(property)

generates a display label from a property name

The default implementation either uses one of the special replacements below, or replaces all underbars with spaces, inserts spaces befor Capital letters, a nd calls String.titleCap on the result.  You can override this function in Validation instances for custom behavior.  Used internally to generate labels for validation errors

Special Replacements

idID

Example

//Let's say your properties start with "htc" but that's not really part of
//the the property name

var v = new Myna.Validation()

//let's override via a function chain
v.before("genLabel",function(property){
var chain = arguments.callee.chain
var test;
if (property && (test = property.match(/^htc(.*)$/))){
chain.args[0] =test[1]
}
})

//Or you can override via prototype callback
v.genLabel =function(property){
if (property && (test = property.match(/^htc(.*)$/))){
property =test[1]
}
Myna.Validation.prototype.genLabel.call(this,property)
}

//Or maybe you already have a label generator
v.genLabel = MyObj.genLabel.bind(MyObj)

getLabel

Myna.Validation.prototype.getLabel=function getLabel(property)

returns the display label for a property name

Parameters

colnamelowercase name of property to retrieve a label for

If an explicit label for this property has been set via setLabel, that is returned.  Otherwise, the result of genLabel is returned

setLabel

Myna.Validation.prototype.setLabel=function setLabel(property,
label)

sets an explicit display label for a property

Parameters

colnamecolumn name to map
labellabel to set

Returns

this instance

setLabels

Myna.Validation.prototype.setLabels=function setLabels(map)

sets an explicit display label for multiple properties at once

Parameters

mapJS object where the keys are column names and the values are labels Returns: this instance

toCode

Myna.Validation.prototype.toCode=function()

returns this Validation object as Javascript source-code

Detail

Myna.Validation and Myna.ValidationResult are designed to be used client-side as well as server-side.  This function returns the JS code necessary to represent this Validation object in client-side JS.

Notes

  • The Myna client-side libraries must be loaded:
<script src="<context_root>/shared/js/libOO/client.sjs"></script>
  • Any custom validators that depend on external properties will fail because those objects won’t exist in the browser.  See examples for work arounds.

Examples

// Complex validation with embedded custom validation:
var v = new Myna.Validation()

//set some label overrides:
v.setLabels({
dob:"Date of Birth",
children:"Dependents"
})

//add multiple validators at once
v.addValidators({
name:{
required:true,
type:"string",
regex:{
pattern:/^[A-Za-z ]+$/,
message:"Names must only contain Letters and spaces"
},
custom:function(params){
var v = new Myna.ValidationResult()
//don't run client side
if (typeof $server_gateway != "undefined"){
var existing new Myna.Query({
ds:ds,
sql:<ejs>
select
name
from names
where name = {value}
</ejs>,
values:params
})
if (existing.data.length) {
v. addError(
"{0} '{1}' already exists".format(params.label,params.value),
params.property
)
}
}

return v
}
},
startDate:{
value:{
min:new Date().add(Date.YEAR,-50),
max:new Date().add(Date.DAY,-1)
}
},
dob:{
type:"date",
value:{
min:new Date().add(Date.YEAR,-150),
max:new Date()
}
},
children:{
type:"array",
length:{
max:12
},
custom:function(params){
// cloning Validation for children
var cv = this.clone()
cv.removeValidator("children")//children don't have children
//add in child specific validators
cv.addValidators({
relationship:{
required:true,
type:"string",
regex:{
pattern:/^(son|daughter)$/i,
message:'Relationship must be "Son" or "Daughter"'
}
}
})

var vr = new Myna.ValidationResult()

params.value.forEach(function(child,index){
var prefix ="child[{1}].".format(name,index)
var v = cv.validate(child)
//console.log(v)
vr.merge(v,prefix)
})

return vr;
}
}
})

Myna.print(<ejs>
<script src="<%=$server.rootUrl%>shared/js/libOO/client.sjs"></script>
<script>
var v =<%=v.toCode()%>)
var vr = v.validate({
dob:"yesterday",
startDate:new Date(),
children:[{
name:"sally",
relationship:"pet"
}]
})
debug_window(vr)
</script>
</ejs>)

validate

Myna.Validation.prototype.validate=function(obj,
property)

Validates an object against this Validation.

Parameters

objobject to validate
propertyOptional, default null If defined, limits validation to a single property

Calls all of the validator functions added via addValidator against an object and returns the merged ValidationResult object

Example

var v = new Myna.Validation()


//set some label overrides:
v.setLabels({
dob:"Date of Birth",
children:"Dependents"
})

//add multiple validators at once
v.addValidators({
name:{
required:true,
type:"string",
regex:{
pattern:/^[A-Za-z ]+$/,
message:"Names must only contain Letters and spaces"
}
},
startDate:{
value:{
min:new Date().add(Date.YEAR,-50),
max:new Date().add(Date.DAY,-1)
}
},
dob:{
type:"date",
value:{
min:new Date().add(Date.YEAR,-150),
max:new Date()
}
},
children:{
type:"array",
length:{
max:12
}
}
})


// cloning Validation for children
var cv = v.clone()
//addinf child specific validators
cv.addValidators({
relationship:{
required:true,
type:"string",
regex:{
pattern:/^(son|daughter)$/i,
message:'Relationship must be "Son" or "Daughter"'
}
}
})
// adding a single custom validator to test the children array members
v.addValidator("children",function(params){
var vr = new Myna.ValidationResult()

params.value.forEach(function(child,index){
var prefix ="child[{1}].".format(name,index)
vr.merge(cv.validate(child),prefix)
})

return vr;
})

//finally, let's validate:
var vr = v.validate({
dob:"yesterday",
startDate:new Date(),
children:[{
name:"sally",
relationship:"pet"
}]
})

Myna.printDump(vr)
// Prints:
// [ Object ]
// +-[errorDetail]
// +-[errorMessage]
// +-[errors] [ Object ]
// | +-[child[0].relationship] Relationship must be "Son" or "Daughter"
// | \-[name] Name is required.
// | \-[startDate] Start Date must be less than Sat Oct 29 2011 09:27:37 GMT-0600 (MDT)
// \-[success] false

See

validatorFunctions.type

Validates basic type

Options

typeFunction or String.  One of “string”, “numeric”, “date”, “binary”, “array”, or “struct”.  “binary” means a byte array and “struct” means a non null/undefined JS object.  If this is a Function, it will be passed the validator arguments and should return one of the above types

Note

if the options to this validator are a single string, that string is assumed to be the type

Example

var v = new Myna.Validation()
//options as object, with optional message
v.addValidator("first_name","type",{
type:"string",
message:"First Name must be text"
})

//with implicit type
//options as type string
v.addValidator("children","type","array")

//with custom type generator and applied to all properties
v.addValidator(null,"type",function(params){
return Myna.Database.dbTypeToJs(params.obj.columns[params.property].data_type)
})

See:

validatorFunctions. length

Validates length

Options

minOptional minimum length, or function that returns a length.  If this is a Function, it will be passed the validator arguments and should return a min value
maxOptional maximum length, or function that returns a length.  If this is a Function, it will be passed the validator arguments and should return a max value

Examples

var v = new Myna.Validation()
//with optional message
v.addValidator("first_name","length",{
max:255,
message:"First Name must be Less that 255 characters"
})

//with custom max length generator and applied to all properties
v.addValidator(null,"length",{
max:function(params){
return params.obj.columns[params.property].column_size
}
})

See

validatorFunctions. value

Validates min/max value

Options

minOptional, default null minimum value, or function that returns a value.  If this is a Function, it will be passed the validator arguments and should return a min value
maxOptional, default null maximum value, or function that returns a value.  If this is a Function, it will be passed the validator arguments and should return a max value

Note

if min or max are null, false or undefined, then they are ignored

Examples

var v = new Myna.Validation()
//with optional message
v.addValidator("age","value",{
min:16,
max:130,
message:"Employees must be between the ages of 16 and 130"
})

//with custom min value generator for use with dates
v.addValidator("end_date","value",{
min:function(params){
return params.obj.start_date.add(Date.DAY,1)
},
message:"End Date must be at least one day after Start Date"
})

See

validatorFunctions. regex

Validates a value against a regular expression

Options

patternregular expression to apply

Notes

  • If the options to this validator are a single RegExp object, that RegExp is assumed to be the pattern
  • Value will be converted to a string for the comparison.

Examples

var v = new Myna.Validation()
//options as object, with optional message
v.addValidator("first_name","regex",{
pattern:/^[A-Za-z ]+$/,
message:"First Name must only contain letters and spaces"
})

//with implicit regex, options as RegExp
v.addValidator("zipcode","regex",/^\d{5}(-\d{4})?/)

See

validatorFunctions.list

Validates a value against a list of values

Options

oneOfOptional, default null Array, or function that returns an Array.  If defined, value must match one of these values.  If this is a Function, it will be passed the validator arguments and should return an array of values
notOneOfOptional, default null Array, or function that returns an Array.  If defined, value must NOT match one of these values.  If this is a Function, it will be passed the validator arguments and should return an array of values
caseSensitiveOptional, default false If false, the value and the list will be converted to strings and a case-insensitive comparison will be made.  This property is ignored if exact is true
exactOptional, default false If true, values are matched by both class and value, via === instead of ==.  Setting this true disables caseSensitive

Note

Just setting oneOf or notOneOf will result in a case insensitive string match.  If both oneOf and notOneOf are defined, notOneOf will be ignored.  If oneOf or notOneOf are functions, they will be called with the same parameters as the validator.  Empty arrays are ignored as if undefined, thus it is possible to define both lists and have whichever is not empty match, or have the validator pass if both are empty

Examples

var v = new Myna.Validation()
v.addValidator("color","list",{
oneOf:[
"Green",
"Yellow",
"blue"
]
})

//with custom list value generator for use with dates
v.addValidator("scheduled_date","list",{
notOneOf:function(params){
return new Myna.Query({
ds:"event_db",
sql:<ejs>
select
scheduled_date
from events
where
id != {id}
</ejs>,
values:params.obj
})
.valueArray("scheduled_date")
.map(function(date){
return date.clearTime()
})
},
exact:true,
message:"This date has already been scheduled"
})

See

validatorFunctions. required

Validates that a value be supplied

This that the value is “true” or native 0 or native false.  This means NaN, null, undefined, etc will fail

Examples

var v = new Myna.Validation()
//options as object, with optional message
v.addValidator("first_name","required",{
message:"First Name is required"
})

See

Myna.Validation = function()
Constructs a Validation Object
Myna.Validation.prototype.clone=function()
makes a copy of this Validation object, including validators, labels, and any custom validatorFunctions
Myna.Validation.prototype.addValidator=function addValidator(property,
validator,
options)
adds a validation function to this manager
Myna.Validation.prototype.addValidators=function addValidators(validator_config)
add multiple validators
Myna.Validation.prototype.removeValidator=function removeValidator(property,
validator)
removes all validators for a property and optionally by == validator type
Myna.Validation.prototype.genLabel=function genLabel(property)
generates a display label from a property name
Myna.Validation.prototype.getLabel=function getLabel(property)
returns the display label for a property name
Myna.Validation.prototype.setLabel=function setLabel(property,
label)
sets an explicit display label for a property
Myna.Validation.prototype.setLabels=function setLabels(map)
sets an explicit display label for multiple properties at once
Myna.Validation.prototype.toCode=function()
returns this Validation object as Javascript source-code
Myna.Validation.prototype.validate=function(obj,
property)
Validates an object against this Validation.
String.prototype.titleCap=function()
Capitalizes the first letter of every word in string
Stores the results of one or more validation operations
Myna.Database.dbTypeToJs = function(sourceType)
Static function that takes a column type name (“VARCHAR”) or a column type id (-5) and returns string that represents the equivalent Myna type (string, numeric, date, binary, unsupported)