1
0
mirror of synced 2024-11-29 08:36:12 +03:00

Merge branch 'master' of github.com:wearebraid/vue-formulate

This commit is contained in:
Justin Schroeder 2020-03-20 15:41:15 -04:00
commit b6c600f955
7 changed files with 47 additions and 29 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -282,22 +282,22 @@ export default {
performValidation () { performValidation () {
const rules = parseRules(this.validation, this.$formulate.rules(this.parsedValidationRules)) const rules = parseRules(this.validation, this.$formulate.rules(this.parsedValidationRules))
this.pendingValidation = Promise.all( this.pendingValidation = Promise.all(
rules.map(([rule, args]) => { rules.map(([rule, args, ruleName]) => {
var res = rule({ var res = rule({
value: this.context.model, value: this.context.model,
getFormValues: this.getFormValues.bind(this), getFormValues: this.getFormValues.bind(this),
name: this.context.name name: this.context.name
}, ...args) }, ...args)
res = (res instanceof Promise) ? res : Promise.resolve(res) res = (res instanceof Promise) ? res : Promise.resolve(res)
return res.then(res => res ? false : this.getValidationMessage(rule, args)) return res.then(res => res ? false : this.getMessage(ruleName, args))
}) })
) )
.then(result => result.filter(result => result)) .then(result => result.filter(result => result))
.then(errorMessages => { this.validationErrors = errorMessages }) .then(errorMessages => { this.validationErrors = errorMessages })
return this.pendingValidation return this.pendingValidation
}, },
getValidationMessage (rule, args) { getMessage (ruleName, args) {
return this.getValidationFunction(rule)({ return this.getMessageFunc(ruleName)({
args, args,
name: this.mergedValidationName, name: this.mergedValidationName,
value: this.context.model, value: this.context.model,
@ -305,10 +305,9 @@ export default {
formValues: this.getFormValues() formValues: this.getFormValues()
}) })
}, },
getValidationFunction (rule) { getMessageFunc (ruleName) {
let ruleName = rule.name.substr(0, 1) === '_' ? rule.name.substr(1) : rule.name
ruleName = snakeToCamel(ruleName) ruleName = snakeToCamel(ruleName)
if (this.messages && typeof this.messages === 'object' && typeof this.messages[ruleName] !== 'undefined') { if (this.messages && typeof this.messages[ruleName] !== 'undefined') {
switch (typeof this.messages[ruleName]) { switch (typeof this.messages[ruleName]) {
case 'function': case 'function':
return this.messages[ruleName] return this.messages[ruleName]
@ -316,7 +315,7 @@ export default {
return () => this.messages[ruleName] return () => this.messages[ruleName]
} }
} }
return (context) => this.$formulate.validationMessage(rule.name, context, this) return (context) => this.$formulate.validationMessage(ruleName, context, this)
}, },
hasValidationErrors () { hasValidationErrors () {
return new Promise(resolve => { return new Promise(resolve => {

View File

@ -3,9 +3,23 @@
:class="`formulate-input-element formulate-input-element--${context.type}`" :class="`formulate-input-element formulate-input-element--${context.type}`"
:data-type="context.type" :data-type="context.type"
> >
<!--
This explicit break out of types is due to a Vue bug that causes IE11 to
not when using v-model + dynamic :type + :value (thanks @Christoph-Wagner)
https://github.com/vuejs/vue/issues/8379
-->
<input <input
v-if="type === 'radio'"
v-model="context.model" v-model="context.model"
:type="type" type="radio"
:value="context.value"
v-bind="attributes"
@blur="context.blurHandler"
>
<input
v-else
v-model="context.model"
type="checkbox"
:value="context.value" :value="context.value"
v-bind="attributes" v-bind="attributes"
@blur="context.blurHandler" @blur="context.blurHandler"

View File

@ -106,19 +106,19 @@ function parseRule (rule, rules) {
} }
if (Array.isArray(rule) && rule.length) { if (Array.isArray(rule) && rule.length) {
rule = rule.map(r => r) // light clone rule = rule.map(r => r) // light clone
rule[0] = snakeToCamel(rule[0]) const ruleName = snakeToCamel(rule.shift())
if (typeof rule[0] === 'string' && rules.hasOwnProperty(rule[0])) { if (typeof ruleName === 'string' && rules.hasOwnProperty(ruleName)) {
return [rules[rule.shift()], rule] return [rules[ruleName], rule, ruleName]
} }
if (typeof rule[0] === 'function') { if (typeof ruleName === 'function') {
return [rule.shift(), rule] return [ruleName, rule, ruleName]
} }
} }
if (typeof rule === 'string') { if (typeof rule === 'string') {
const segments = rule.split(':') const segments = rule.split(':')
const functionName = snakeToCamel(segments.shift()) const ruleName = snakeToCamel(segments.shift())
if (rules.hasOwnProperty(functionName)) { if (rules.hasOwnProperty(ruleName)) {
return [rules[functionName], segments.length ? segments.join(':').split(',') : []] return [rules[ruleName], segments.length ? segments.join(':').split(',') : [], ruleName]
} else { } else {
throw new Error(`Unknown validation rule ${rule}`) throw new Error(`Unknown validation rule ${rule}`)
} }

View File

@ -5,7 +5,7 @@ import FileUpload from '@/FileUpload';
describe('parseRules', () => { describe('parseRules', () => {
it('parses single string rules, returning empty arguments array', () => { it('parses single string rules, returning empty arguments array', () => {
expect(parseRules('required', rules)).toEqual([ expect(parseRules('required', rules)).toEqual([
[rules.required, []] [rules.required, [], 'required']
]) ])
}) })
@ -17,21 +17,21 @@ describe('parseRules', () => {
it('parses arguments for a rule', () => { it('parses arguments for a rule', () => {
expect(parseRules('in:foo,bar', rules)).toEqual([ expect(parseRules('in:foo,bar', rules)).toEqual([
[rules.in, ['foo', 'bar']] [rules.in, ['foo', 'bar'], 'in']
]) ])
}) })
it('parses multiple string rules and arguments', () => { it('parses multiple string rules and arguments', () => {
expect(parseRules('required|in:foo,bar', rules)).toEqual([ expect(parseRules('required|in:foo,bar', rules)).toEqual([
[rules.required, []], [rules.required, [], 'required'],
[rules.in, ['foo', 'bar']] [rules.in, ['foo', 'bar'], 'in']
]) ])
}) })
it('parses multiple array rules and arguments', () => { it('parses multiple array rules and arguments', () => {
expect(parseRules(['required', 'in:foo,bar'], rules)).toEqual([ expect(parseRules(['required', 'in:foo,bar'], rules)).toEqual([
[rules.required, []], [rules.required, [], 'required'],
[rules.in, ['foo', 'bar']] [rules.in, ['foo', 'bar'], 'in']
]) ])
}) })
@ -39,7 +39,7 @@ describe('parseRules', () => {
expect(parseRules([ expect(parseRules([
['matches', /^abc/, '1234'] ['matches', /^abc/, '1234']
], rules)).toEqual([ ], rules)).toEqual([
[rules.matches, [/^abc/, '1234']] [rules.matches, [/^abc/, '1234'], 'matches']
]) ])
}) })
}) })
@ -142,6 +142,11 @@ describe('snakeToCamel', () => {
it('has no effect hyphenated words', () => { it('has no effect hyphenated words', () => {
expect(snakeToCamel('not-a-good-name')).toBe('not-a-good-name') expect(snakeToCamel('not-a-good-name')).toBe('not-a-good-name')
}) })
it('returns the same function if passed', () => {
const fn = () => {}
expect(snakeToCamel(fn)).toBe(fn)
})
}) })