Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test/attach detach #11

Open
wants to merge 2 commits into
base: example
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { Vue, Component } from 'vue-property-decorator'

import CForm from '@/components/CForm.vue'
import formTemplate from '@/templates/SimpleForm.json'
import formTemplate from '@/templates/SimpleForm.js'

@Component({
components: { CForm },
Expand Down
35 changes: 24 additions & 11 deletions src/components/CForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@
<c-button success class="action" @click.stop="attach">
Attach
</c-button>
<c-button error class="action" @click.stop="$validator.reset()">
Reset
</c-button>
<c-button primary class="action" @click.stop="$validator.validateAll()">
Salvar
<c-button error class="action" @click.stop="detach">
Detach
</c-button>
</slot>
</div>
Expand Down Expand Up @@ -106,13 +103,17 @@ export default class CForm extends Mixins(FormValidator) {
}

this.allFields = { ...this.allFields, testField: testFieldDef }
// this.formData.testField = ''

this.$nextTick(this.$validator.attach(testField))
this.$set(this.formData, 'testField', 'imdo')
this.$nextTick(() => this.$validator.attach(testField))
}

submit () {
console.log('CForm.validator: ', this.$validator)
detach () {
const { testField, ...fields } = this.allFields
this.allFields = fields
this.$delete(this.formData, 'testField')

this.$validator.detach('testField', 'formData')
}

created () {
Expand All @@ -125,10 +126,22 @@ export default class CForm extends Mixins(FormValidator) {
: { [propName]: (entity[propName] || {})[key] })
}), {})

// This is just so we can test the new attach/detach methods
this.allFields = { ...this.fields }
const validations = reduceToValue(this.fields, 'validation', true)
console.log('validations: ', { validations })
this.formData = { ...reduceToValue(this.fields, 'value'), testField: '' }

Object.keys(this.fields).forEach(field => {
const fieldObj = this.fields[field] || {}

if (typeof fieldObj.validation === 'function') {
this.$watch('formData', (val) => {
const newRule = fieldObj.validation(val)
this.$validator.setFieldRule({ name: field, scope: 'formData' }, newRule)
}, { deep: true })
}
})

this.formData = reduceToValue(this.fields, 'value')
this.$validator.init({ formData: validations })
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/templates/SimpleForm.json → src/templates/SimpleForm.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
export default {
"fullName":
{ "type": "text"
, "label": "Nome completo"
Expand Down Expand Up @@ -104,5 +104,12 @@
, "placeholder": "Nome do pai"
, "validation": ""
, "value": ""
}
},
"dinamicValidation":
{ "type": "text"
, "label": "This field's validation changes according to the rest of the form"
, "placeholder": "Crazy field"
, "validation": (formData) => (formData.testField || '').length ? 'required' : ''
, "value": "I'm crazy"
}
}
26 changes: 14 additions & 12 deletions src/validator/core/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export default class Field {
get watch (): any {
if (!this._vm || !this._vm.$validator) return

console.log(`field ${this.name} has a watch function`)
return this._vm.$watch.bind(this._vm)
}

Expand Down Expand Up @@ -142,18 +141,8 @@ export default class Field {
}
}

console.log('listeners: ', {
scope: this.scope,
name: this.name,
this: this
})

this.el.addEventListener('focusout', onBlur.bind(this))
this.watch(
this.scope ? `${this.scope}.${this.name}` : this.name,
onInput.bind(this),
{ deep: true, immediate: true }
)
this.watch(this.scope ? `${this.scope}.${this.name}` : this.name, onInput.bind(this))
}

/**
Expand Down Expand Up @@ -206,4 +195,17 @@ export default class Field {
this.value = this.initialValue
this.initFlags()
}

/**
* Dynamically updates the field's rules and remaps them.
*
* @param {FieldValidation} rule - The new rules to be applied
* @returns {void}
*
* @author Erik Isidore
*/

setRule (rule: FieldValidation): void {
this.rules = this.mapRules(rule)
}
}
13 changes: 10 additions & 3 deletions src/validator/core/fieldBag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,15 @@ export default class FieldBag {
*/

remove (field: string, scope?: string): void {
this._items = this._items.filter((item: Field) => scope
? item.name !== field && item.scope !== scope
: item.name !== field)
this._items = this._items.filter((item: Field) => {
console.log(`remove ${field}.${scope}: `, { item })
console.log('the test: ', item.name !== field && (!scope || item.scope !== scope))

return scope && item.scope === scope
? item.name !== field
: item.name !== field
})

console.log('new items: ', this._items)
}
}
40 changes: 27 additions & 13 deletions src/validator/core/scopedValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default class ScopedValidator {
private __init (template: FormTemplate): void {
this.scopes = Object.keys(template).filter(key => isFormScope(template[key]))
this.fields.items = this.initFields(template)
this.validations = this.initValidations()
this.validations = this.mapValidations()
}

/**
Expand Down Expand Up @@ -112,7 +112,7 @@ export default class ScopedValidator {
* @author Erik Isidore
*/

initValidations (): FormValidationFlags {
mapValidations (): FormValidationFlags {
const mapFlags = (scope?: string) => this.fields.all(scope)
.reduce((acc, field: Field) => ({ ...acc, [field.name]: field.flags }), {})

Expand Down Expand Up @@ -222,7 +222,7 @@ export default class ScopedValidator {
* @author Erik Isidore
*/

attach (field: { name: string, rules: string, scope: string }): void {
attach (field: { name: string, scope: string, rules: FieldValidation }): void {
const newField: Field = new Field({
vm: this._vm,
name: field.name,
Expand All @@ -232,13 +232,9 @@ export default class ScopedValidator {
value: field.scope ? this._vm[field.scope][field.name] : this._vm[field.name]
})

console.log('attach: ', { field, validations: this.validations })

field.scope && this.scopes.length > 1
? this.validations[field.scope][field.name] = newField.flags
: this.validations[field.name] = newField.flags

this.fields.push(newField)
this.validations = this.mapValidations()
console.log('attach: ', { field, validations: this.validations })
}

/**
Expand All @@ -251,10 +247,28 @@ export default class ScopedValidator {
*/

detach (field: string, scope?: string): void {
scope
? delete this.validations[scope][field]
: delete this.validations[field]

this.fields.remove(field, scope)
this.validations = this.mapValidations()

console.log('detach: ', { field, scope, fields: this.fields, validations: this.validations })
}

/**
* Dynamically updates a field's rules and immediatelly triggers its'
* validation.
*
* @param {Object} field - The object containing name and scope of the field
* @param {FieldValidation} rules - The new rules to be applied to the field.
* @returns {void}
*
* @author Erik Isidor
*/

setFieldRule (field: { name: string, scope: string }, rules: FieldValidation): void {
const fieldInstance : Field | undefined = this.fields.get(field.name, field.scope)
if (!fieldInstance) return

fieldInstance.updateRule(rules)
fieldInstance.validate()
}
}