A store for validation functions that can be used to validate objects
See: validate
| Myna. Validation | A store for validation functions that can be used to validate objects |
| Functions | |
| Myna. Validation | Constructs a Validation Object |
| clone | makes a copy of this Validation object, including validators, labels, and any custom validatorFunctions |
| addValidator | adds a validation function to this manager |
| addValidators | add multiple validators |
| removeValidator | removes all validators for a property and optionally by == validator type |
| genLabel | generates a display label from a property name |
| getLabel | returns the display label for a property name |
| setLabel | sets an explicit display label for a property |
| setLabels | sets an explicit display label for multiple properties at once |
| toCode | returns this Validation object as Javascript source-code |
| validate | Validates an object against this Validation. |
| validatorFunctions.type | Validates basic type |
| validatorFunctions. length | Validates length |
| validatorFunctions. value | Validates min/max value |
| validatorFunctions. regex | Validates a value against a regular expression |
| validatorFunctions.list | Validates a value against a list of values |
| validatorFunctions. required | Validates that a value be supplied |
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
| property | property to validate. If this is set to null, then this validator will be called for every property |
| validator | Either 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 |
| options | Optional, default undefined any options needed by the validator |
The validator function will be called with a parameters object with these properties
| obj | Object being validated |
| property | Property being validated |
| label | result of getLabel for property |
| value | value being validated |
| options | validator options. Most validators define their own specific options, but all validators accept the options below |
| when | A 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 |
this validation instance
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."
})
Myna.Validation.prototype.addValidators=function addValidators( validator_config )
add multiple validators
| validator_config | JS 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) |
this validation instance
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;
}
}
})
Myna.Validation.prototype.removeValidator=function removeValidator( property, validator )
removes all validators for a property and optionally by == validator type
| property | name of property to modify |
| validator | Optional, 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
this validation instance
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;
})
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
| id | ID |
//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)
Myna.Validation.prototype.getLabel=function getLabel( property )
returns the display label for a property name
| colname | lowercase 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
Myna.Validation.prototype.setLabel=function setLabel( property, label )
sets an explicit display label for a property
| colname | column name to map |
| label | label to set |
this instance
Myna.Validation.prototype.setLabels=function setLabels( map )
sets an explicit display label for multiple properties at once
| map | JS object where the keys are column names and the values are labels Returns: this instance |
Myna.Validation.prototype.toCode=function()
returns this Validation object as Javascript source-code
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.
<script src="<context_root>/shared/js/libOO/client.sjs"></script>
// 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>)
Myna.Validation.prototype.validate=function( obj, property )
Validates an object against this Validation.
| obj | object to validate |
| property | Optional, 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
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
Validates basic type
| type | Function 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 |
if the options to this validator are a single string, that string is assumed to be the type
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:
Validates length
| min | Optional 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 |
| max | Optional 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 |
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
}
})
Validates min/max value
| min | Optional, 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 |
| max | Optional, 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 |
if min or max are null, false or undefined, then they are ignored
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"
})
Validates a value against a regular expression
| pattern | regular expression to apply |
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})?/)
Validates a value against a list of values
| oneOf | Optional, 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 |
| notOneOf | Optional, 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 |
| caseSensitive | Optional, 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 |
| exact | Optional, default false If true, values are matched by both class and value, via === instead of ==. Setting this true disables caseSensitive |
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
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"
})
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
var v = new Myna.Validation()
//options as object, with optional message
v.addValidator("first_name","required",{
message:"First Name is required"
})
Constructs a Validation Object
Myna.Validation = function()
makes a copy of this Validation object, including validators, labels, and any custom validatorFunctions
Myna.Validation.prototype.clone=function()
adds a validation function to this manager
Myna.Validation.prototype.addValidator=function addValidator( property, validator, options )
add multiple validators
Myna.Validation.prototype.addValidators=function addValidators( validator_config )
removes all validators for a property and optionally by == validator type
Myna.Validation.prototype.removeValidator=function removeValidator( property, validator )
generates a display label from a property name
Myna.Validation.prototype.genLabel=function genLabel( property )
returns the display label for a property name
Myna.Validation.prototype.getLabel=function getLabel( property )
sets an explicit display label for a property
Myna.Validation.prototype.setLabel=function setLabel( property, label )
sets an explicit display label for multiple properties at once
Myna.Validation.prototype.setLabels=function setLabels( map )
returns this Validation object as Javascript source-code
Myna.Validation.prototype.toCode=function()
Validates an object against this Validation.
Myna.Validation.prototype.validate=function( obj, property )
Capitalizes the first letter of every word in string
String.prototype.titleCap=function()
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)
Myna.Database.dbTypeToJs = function( sourceType )