Implementing Inspector validation, in progress
This commit is contained in:
parent
aee247727a
commit
6095303b54
|
|
@ -29,7 +29,7 @@
|
|||
this.parentGroup = group
|
||||
this.group = null // Group created by a grouped editor, for example by the set editor
|
||||
this.childInspector = null
|
||||
this.validators = []
|
||||
this.validationSet = null
|
||||
|
||||
Base.call(this)
|
||||
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
BaseEditor.prototype.constructor = Base
|
||||
|
||||
BaseEditor.prototype.dispose = function() {
|
||||
this.disposeValidators()
|
||||
this.disposeValidation()
|
||||
|
||||
if (this.childInspector) {
|
||||
this.childInspector.dispose()
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
this.childInspector = null
|
||||
this.parentGroup = null
|
||||
this.group = null
|
||||
this.validators = null
|
||||
this.validationSet = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
BaseEditor.prototype.init = function() {
|
||||
this.build()
|
||||
this.registerHandlers()
|
||||
this.createValidators()
|
||||
this.initValidation()
|
||||
}
|
||||
|
||||
BaseEditor.prototype.build = function() {
|
||||
|
|
@ -104,77 +104,29 @@
|
|||
// Validation
|
||||
//
|
||||
|
||||
BaseEditor.prototype.createValidators = function() {
|
||||
// Handle legacy validation syntax properties:
|
||||
//
|
||||
// - required
|
||||
// - validationPattern
|
||||
// - validationMessage
|
||||
|
||||
if ((this.propertyDefinition.required !== undefined ||
|
||||
this.propertyDefinition.validationPattern !== undefined ||
|
||||
this.propertyDefinition.validationMessage !== undefined) &&
|
||||
this.propertyDefinition.validation !== undefined) {
|
||||
this.throwError('Legacy and new validation syntax should not be mixed.')
|
||||
}
|
||||
|
||||
if (this.propertyDefinition.required !== undefined) {
|
||||
var validator = new $.oc.inspector.validators.required({
|
||||
message: this.propertyDefinition.validationMessage
|
||||
})
|
||||
|
||||
this.validators.push(validator)
|
||||
}
|
||||
|
||||
if (this.propertyDefinition.validationPattern !== undefined) {
|
||||
var validator = new $.oc.inspector.validators.regex({
|
||||
message: this.propertyDefinition.validationMessage,
|
||||
pattern: this.propertyDefinition.validationPattern
|
||||
})
|
||||
|
||||
this.validators.push(validator)
|
||||
}
|
||||
|
||||
//
|
||||
// Handle new validation syntax
|
||||
//
|
||||
|
||||
if (this.propertyDefinition.validation === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
for (var validatorName in this.propertyDefinition.validation) {
|
||||
if ($.oc.inspector.validators[validatorName] == undefined) {
|
||||
this.throwError('Inspector validator "' + validatorName + '" is not found in the $.oc.inspector.validators namespace.')
|
||||
}
|
||||
|
||||
var validator = new $.oc.inspector.validators[validatorName](
|
||||
this.propertyDefinition.validation[validatorName]
|
||||
)
|
||||
|
||||
this.validators.push(validator)
|
||||
}
|
||||
BaseEditor.prototype.initValidation = function() {
|
||||
this.validationSet = new $.oc.inspector.validationSet(this.propertyDefinition, this.propertyDefinition.property)
|
||||
}
|
||||
|
||||
BaseEditor.prototype.disposeValidators = function() {
|
||||
for (var i = 0, len = this.validators.length; i < len; i++) {
|
||||
this.validators[i].dispose()
|
||||
}
|
||||
BaseEditor.prototype.disposeValidation = function() {
|
||||
this.validationSet.dispose()
|
||||
}
|
||||
|
||||
BaseEditor.prototype.getValueToValidate = function() {
|
||||
return this.inspector.getPropertyValue(this.propertyDefinition.property)
|
||||
}
|
||||
|
||||
BaseEditor.prototype.validate = function() {
|
||||
for (var i = 0, len = this.validators.length; i < len; i++) {
|
||||
var validator = this.validators[i],
|
||||
value = this.inspector.getPropertyValue(this.propertyDefinition.property)
|
||||
var value = this.getValueToValidate()
|
||||
|
||||
if (value === undefined) {
|
||||
value = this.getUndefinedValue()
|
||||
}
|
||||
if (value === undefined) {
|
||||
value = this.getUndefinedValue()
|
||||
}
|
||||
|
||||
if (!validator.isValid(value)) {
|
||||
$.oc.flashMsg({text: validator.getMessage(), 'class': 'error', 'interval': 5})
|
||||
return false
|
||||
}
|
||||
var validationResult = this.validationSet.validate(value)
|
||||
if (validationResult !== null) {
|
||||
$.oc.flashMsg({text: validationResult, 'class': 'error', 'interval': 5})
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@
|
|||
return true
|
||||
}
|
||||
|
||||
|
||||
ObjectEditor.prototype.getUndefinedValue = function() {
|
||||
var result = {}
|
||||
|
||||
|
|
@ -120,6 +119,19 @@
|
|||
return this.getValueOrRemove(result)
|
||||
}
|
||||
|
||||
ObjectEditor.prototype.validate = function() {
|
||||
var values = values = this.childInspector.getValues()
|
||||
|
||||
if (this.cleanUpValue(values) === $.oc.inspector.removedProperty) {
|
||||
// Ignore any validation rules if the object's required
|
||||
// property is empty (ignoreIfPropertyEmpty)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return this.childInspector.validate()
|
||||
}
|
||||
|
||||
//
|
||||
// Event handlers
|
||||
//
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
}
|
||||
|
||||
StringEditor.prototype.onInputKeyUp = function() {
|
||||
var value = this.getInput().value
|
||||
var value = $.trim(this.getInput().value)
|
||||
|
||||
this.inspector.setPropertyValue(this.propertyDefinition.property, value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Inspector validation set class.
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
// NAMESPACES
|
||||
// ============================
|
||||
|
||||
if ($.oc.inspector.validators === undefined)
|
||||
$.oc.inspector.validators = {}
|
||||
|
||||
// CLASS DEFINITION
|
||||
// ============================
|
||||
|
||||
var Base = $.oc.foundation.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var ValidationSet = function(options, propertyName) {
|
||||
this.validators = []
|
||||
|
||||
this.options = options
|
||||
this.propertyName = propertyName
|
||||
Base.call(this)
|
||||
|
||||
this.createValidators()
|
||||
}
|
||||
|
||||
ValidationSet.prototype = Object.create(BaseProto)
|
||||
ValidationSet.prototype.constructor = Base
|
||||
|
||||
ValidationSet.prototype.dispose = function() {
|
||||
this.disposeValidators()
|
||||
this.validators = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
ValidationSet.prototype.disposeValidators = function() {
|
||||
for (var i = 0, len = this.validators.length; i < len; i++) {
|
||||
this.validators[i].dispose()
|
||||
}
|
||||
}
|
||||
|
||||
ValidationSet.prototype.throwError = function(errorMessage) {
|
||||
throw new Error(errorMessage + ' Property: ' + this.propertyName)
|
||||
}
|
||||
|
||||
ValidationSet.prototype.createValidators = function() {
|
||||
// Handle legacy validation syntax properties:
|
||||
//
|
||||
// - required
|
||||
// - validationPattern
|
||||
// - validationMessage
|
||||
|
||||
if ((this.options.required !== undefined ||
|
||||
this.options.validationPattern !== undefined ||
|
||||
this.options.validationMessage !== undefined) &&
|
||||
this.options.validation !== undefined) {
|
||||
this.throwError('Legacy and new validation syntax should not be mixed.')
|
||||
}
|
||||
|
||||
if (this.options.required !== undefined) {
|
||||
var validator = new $.oc.inspector.validators.required({
|
||||
message: this.options.validationMessage
|
||||
})
|
||||
|
||||
this.validators.push(validator)
|
||||
}
|
||||
|
||||
if (this.options.validationPattern !== undefined) {
|
||||
var validator = new $.oc.inspector.validators.regex({
|
||||
message: this.options.validationMessage,
|
||||
pattern: this.options.validationPattern
|
||||
})
|
||||
|
||||
this.validators.push(validator)
|
||||
}
|
||||
|
||||
//
|
||||
// Handle new validation syntax
|
||||
//
|
||||
|
||||
if (this.options.validation === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
for (var validatorName in this.options.validation) {
|
||||
if ($.oc.inspector.validators[validatorName] == undefined) {
|
||||
this.throwError('Inspector validator "' + validatorName + '" is not found in the $.oc.inspector.validators namespace.')
|
||||
}
|
||||
|
||||
var validator = new $.oc.inspector.validators[validatorName](
|
||||
this.options.validation[validatorName]
|
||||
)
|
||||
|
||||
this.validators.push(validator)
|
||||
}
|
||||
}
|
||||
|
||||
ValidationSet.prototype.validate = function(value) {
|
||||
try {
|
||||
for (var i = 0, len = this.validators.length; i < len; i++) {
|
||||
var validator = this.validators[i],
|
||||
errorMessage = validator.isValid(value)
|
||||
|
||||
if (typeof errorMessage === 'string') {
|
||||
return errorMessage
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
catch (err) {
|
||||
this.throwError(err)
|
||||
}
|
||||
}
|
||||
|
||||
$.oc.inspector.validationSet = ValidationSet
|
||||
}(window.jQuery);
|
||||
|
|
@ -17,7 +17,9 @@
|
|||
|
||||
var BaseValidator = function(options) {
|
||||
this.options = options
|
||||
this.defaultMessage = 'Invalid property value'
|
||||
this.defaultMessage = 'Invalid property value.'
|
||||
|
||||
Base.call(this)
|
||||
}
|
||||
|
||||
BaseValidator.prototype = Object.create(BaseProto)
|
||||
|
|
@ -29,9 +31,14 @@
|
|||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
BaseValidator.prototype.getMessage = function() {
|
||||
if (this.options.message !== undefined)
|
||||
BaseValidator.prototype.getMessage = function(defaultMessage) {
|
||||
if (this.options.message !== undefined) {
|
||||
return this.options.message
|
||||
}
|
||||
|
||||
if (defaultMessage !== undefined) {
|
||||
return defaultMessage
|
||||
}
|
||||
|
||||
return this.defaultMessage
|
||||
}
|
||||
|
|
@ -49,7 +56,7 @@
|
|||
}
|
||||
|
||||
BaseValidator.prototype.isValid = function(value) {
|
||||
return true
|
||||
return null
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.base = BaseValidator
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Base class for Inspector numeric validators.
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
var Base = $.oc.inspector.validators.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var BaseNumber = function(options) {
|
||||
Base.call(this, options)
|
||||
}
|
||||
|
||||
BaseNumber.prototype = Object.create(BaseProto)
|
||||
BaseNumber.prototype.constructor = Base
|
||||
|
||||
BaseNumber.prototype.doCommonChecks = function(value) {
|
||||
if (this.options.min !== undefined || this.options.max !== undefined) {
|
||||
if (this.options.min !== undefined) {
|
||||
if (this.options.min.value === undefined)
|
||||
throw new Error('The min.value parameter is not defined in the Inspector validator configuration')
|
||||
|
||||
if (value < this.options.min.value) {
|
||||
return this.options.min.message !== undefined ?
|
||||
this.options.min.message :
|
||||
"The value should not be less than " + this.options.min.value
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.max !== undefined) {
|
||||
if (this.options.max.value === undefined)
|
||||
throw new Error('The max.value parameter is not defined in the table Inspector validator configuration')
|
||||
|
||||
if (value > this.options.max.value) {
|
||||
return this.options.max.message !== undefined ?
|
||||
this.options.max.message :
|
||||
"The value should not be greater than " + this.options.max.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.baseNumber = BaseNumber
|
||||
}(window.jQuery);
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Inspector float validator.
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
var Base = $.oc.inspector.validators.baseNumber,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var FloatValidator = function(options) {
|
||||
Base.call(this, options)
|
||||
}
|
||||
|
||||
FloatValidator.prototype = Object.create(BaseProto)
|
||||
FloatValidator.prototype.constructor = Base
|
||||
|
||||
FloatValidator.prototype.isValid = function(value) {
|
||||
if (!this.isScalar(value) || typeof value == 'boolean') {
|
||||
this.throwError('The Float Inspector validator can only be used with string values.')
|
||||
}
|
||||
|
||||
if (value === undefined || value === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
var string = $.trim(String(value))
|
||||
|
||||
if (string.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
var testResult = this.options.allowNegative ?
|
||||
/^[-]?([0-9]+\.[0-9]+|[0-9]+)$/.test(string) :
|
||||
/^([0-9]+\.[0-9]+|[0-9]+)$/.test(string)
|
||||
|
||||
if (!testResult) {
|
||||
var defaultMessage = this.options.allowNegative ?
|
||||
'The value should be a floating point number.' :
|
||||
'The value should be a positive floating point number.';
|
||||
|
||||
return this.getMessage(defaultMessage)
|
||||
}
|
||||
|
||||
return this.doCommonChecks(parseFloat(string))
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.float = FloatValidator
|
||||
}(window.jQuery);
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Inspector integer validator.
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
var Base = $.oc.inspector.validators.baseNumber,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var IntegerValidator = function(options) {
|
||||
Base.call(this, options)
|
||||
}
|
||||
|
||||
IntegerValidator.prototype = Object.create(BaseProto)
|
||||
IntegerValidator.prototype.constructor = Base
|
||||
|
||||
IntegerValidator.prototype.isValid = function(value) {
|
||||
if (!this.isScalar(value) || typeof value == 'boolean') {
|
||||
this.throwError('The Integer Inspector validator can only be used with string values.')
|
||||
}
|
||||
|
||||
if (value === undefined || value === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
var string = $.trim(String(value))
|
||||
|
||||
if (string.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
var testResult = this.options.allowNegative ?
|
||||
/^\-?[0-9]*$/.test(string) :
|
||||
/^[0-9]*$/.test(string)
|
||||
|
||||
if (!testResult) {
|
||||
var defaultMessage = this.options.allowNegative ?
|
||||
'The value should be an integer.' :
|
||||
'The value should be a positive integer.';
|
||||
|
||||
return this.getMessage(defaultMessage)
|
||||
}
|
||||
|
||||
return this.doCommonChecks(parseInt(string))
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.integer = IntegerValidator
|
||||
}(window.jQuery);
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Inspector length validator.
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
var Base = $.oc.inspector.validators.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var LengthValidator = function(options) {
|
||||
Base.call(this, options)
|
||||
}
|
||||
|
||||
LengthValidator.prototype = Object.create(BaseProto)
|
||||
LengthValidator.prototype.constructor = Base
|
||||
|
||||
LengthValidator.prototype.isValid = function(value) {
|
||||
if (value === undefined || value === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (typeof value == 'boolean') {
|
||||
this.throwError('The Length Inspector validator cannot work with Boolean values.')
|
||||
|
||||
}
|
||||
|
||||
var length = null
|
||||
|
||||
if(Object.prototype.toString.call(value) === '[object Array]' || typeof value === 'string') {
|
||||
length = value.length
|
||||
}
|
||||
else if (typeof value === 'object') {
|
||||
length = this.getObjectLength(value)
|
||||
}
|
||||
|
||||
if (this.options.min !== undefined || this.options.max !== undefined) {
|
||||
if (this.options.min !== undefined) {
|
||||
if (this.options.min.value === undefined)
|
||||
throw new Error('The min.value parameter is not defined in the Length Inspector validator configuration.')
|
||||
|
||||
if (length < this.options.min.value) {
|
||||
return this.options.min.message !== undefined ?
|
||||
this.options.min.message :
|
||||
"The value should not be shorter than " + this.options.min.value
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.max !== undefined) {
|
||||
if (this.options.max.value === undefined)
|
||||
throw new Error('The max.value parameter is not defined in the Length Inspector validator configuration.')
|
||||
|
||||
if (length > this.options.max.value) {
|
||||
return this.options.max.message !== undefined ?
|
||||
this.options.max.message :
|
||||
"The value should not be longer than " + this.options.max.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LengthValidator.prototype.getObjectLength = function(value) {
|
||||
var result = 0
|
||||
|
||||
for (var key in value) {
|
||||
result++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.length = LengthValidator
|
||||
}(window.jQuery);
|
||||
|
|
@ -14,26 +14,27 @@
|
|||
RegexValidator.prototype.constructor = Base
|
||||
|
||||
RegexValidator.prototype.isValid = function(value) {
|
||||
if (this.options.pattern === undefined) {
|
||||
this.throwError('The pattern parameter is not defined in the Regex Inspector validator configuration.')
|
||||
}
|
||||
|
||||
if (!this.isScalar(value)) {
|
||||
this.throwError('The Regex Inspector validator can only be used with string values.')
|
||||
}
|
||||
|
||||
if (value === undefined || value === null) {
|
||||
return true
|
||||
return null
|
||||
}
|
||||
|
||||
var string = String(value)
|
||||
var string = $.trim(String(value))
|
||||
|
||||
if (string.length == 0)
|
||||
return
|
||||
|
||||
if (this.options.pattern === undefined) {
|
||||
this.throwError('The pattern parameter is not defined in the Regex Inspector validator configuration.')
|
||||
if (string.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
var regexObj = new RegExp(this.options.pattern, this.options.modifiers)
|
||||
|
||||
return regexObj.test(string)
|
||||
return regexObj.test(string) ? null : this.getMessage()
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.regex = RegexValidator
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
var RequiredValidator = function(options) {
|
||||
Base.call(this, options)
|
||||
|
||||
this.defaultMessage = 'The property is required.'
|
||||
}
|
||||
|
||||
RequiredValidator.prototype = Object.create(BaseProto)
|
||||
|
|
@ -15,18 +17,18 @@
|
|||
|
||||
RequiredValidator.prototype.isValid = function(value) {
|
||||
if (value === undefined || value === null) {
|
||||
return false
|
||||
return this.getMessage()
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
return value
|
||||
return value ? null : this.getMessage()
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
return !$.isEmptyObject(value)
|
||||
return !$.isEmptyObject(value) ? null : this.getMessage()
|
||||
}
|
||||
|
||||
return $.trim(String(value)).length > 0
|
||||
return $.trim(String(value)).length > 0 ? null : this.getMessage()
|
||||
}
|
||||
|
||||
$.oc.inspector.validators.required = RequiredValidator
|
||||
|
|
|
|||
Loading…
Reference in New Issue