Initial commit

This commit is contained in:
John Lyon-Smith
2018-02-22 17:57:27 -08:00
commit e80f5490d5
196 changed files with 38982 additions and 0 deletions

View File

@@ -0,0 +1,188 @@
import EventEmitter from 'eventemitter3'
const any = function(obj, pred) {
for (let name in obj) {
if (pred(obj[name])) {
return true
}
}
return false
}
export class Validator extends EventEmitter {
constructor(originalObj, validations, onModifiedChanged) {
super()
this.updateValue = this.updateValue.bind(this)
this._id = originalObj._id
this.onModifiedChanged = onModifiedChanged
this.fields = {}
this.nonValueFields = {}
for (let name in validations) {
let validation = validations[name]
let field = {
isDisabled: this.normalize(validation.isDisabled, false),
isReadOnly: this.normalize(validation.isReadOnly, false),
isVisible: this.normalize(validation.isVisible, true),
nonValue: validation.nonValue || false
}
if (field.nonValue) {
field.disabled = field.isDisabled(this)
field.readOnly = field.isReadOnly(this)
field.visible = field.isVisible(this)
this.nonValueFields[name] = field
} else {
field.alwaysGet = validation.alwaysGet
field.isValid = this.normalize(validation.isValid, true)
field.initValue = (validation.initValue === undefined ? '' : validation.initValue)
field.originalValue = Validator.getObjectValue(originalObj, name)
this.updateFieldValue(field, field.originalValue || field.initValue)
this.fields[name] = field
}
}
this.updateNonValueFields()
}
normalize(obj, def) {
return obj ? ((obj.constructor === Function) ? obj : () => (!!obj)) : () => (def)
}
static stateSafeField(field) {
return {
value: field.value,
modified: field.modified,
valid: field.valid,
disabled: field.disabled,
readOnly: field.readOnly,
visible: field.visible
}
}
updateValue(name, newValue) {
let lastAnyModified = this.anyModified
let field = this.fields[name]
if (field) {
this.updateFieldValue(field, newValue)
this.updateNonValueFields()
if (lastAnyModified !== this.anyModified && this.onModifiedChanged) {
this.onModifiedChanged(this.anyModified)
}
}
return Validator.stateSafeField(field)
}
updateFieldValue(field, newValue) {
field.value = newValue
field.disabled = field.isDisabled(this)
field.readOnly = field.isReadOnly(this)
field.visible = field.isVisible(this)
field.valid = field.isValid(this, newValue)
field.modified =
field.originalValue !== undefined ? (field.originalValue !== newValue) : (newValue !== field.initValue)
this.anyModified = field.modified || any(this.fields, (field) => (field.modified))
this.allValid = !field.valid ? false : !any(this.fields, (field) => (!field.valid))
}
updateNonValueFields() {
for (let name in this.nonValueFields) {
let field = this.nonValueFields[name]
let disabled = field.isDisabled(this)
let readOnly = field.isReadOnly(this)
let visible = field.isVisible(this)
let b = (disabled !== field.disabled || readOnly !== field.readOnly || visible !== field.visible)
field.disabled = disabled
field.readOnly = readOnly
field.visible = visible
if (b) {
this.emit(name, name)
}
}
}
getField(name) {
let field = this.fields[name] || this.nonValueFields[name]
if (!field) {
throw new Error(`Field '${name}' does not have a validation entry`)
}
return Validator.stateSafeField(field)
}
getValues() {
// Generate an object that has the modified and alwaysGet fields
let obj = {}
if (!this.anyModified && !this.allValid) {
return obj
}
// Will have an _id if updating
if (this._id) {
obj._id = this._id
}
for (let name in this.fields) {
let field = this.fields[name]
if (field.alwaysGet || (!field.nonValue && field.modified)) {
let value = field.value
if (value && value.constructor === 'String') {
value = value.trim()
}
Validator.setObjectValue(obj, name, value)
}
}
return obj
}
getOriginalValues() {
// Generate an object that has the original values of all fields
let obj = {}
if (this._id) {
obj._id = this._id
}
for (let name in this.fields) {
let field = this.fields[name]
if (field.originalValue !== undefined) {
Validator.setObjectValue(obj, name, field.originalValue)
}
}
return obj
}
static getObjectValue(obj, name) {
name.split('.').forEach((namePart) => {
if (obj) {
obj = obj[namePart]
}
})
return obj
}
static setObjectValue(obj, name, value) {
name.split('.').forEach((namePart, i, nameParts) => {
if (i < nameParts.length - 1) {
if (!obj[namePart]) {
obj[namePart] = {}
}
obj = obj[namePart]
} else {
obj[namePart] = value
}
})
}
}