1
0
mirror of synced 2024-11-25 23:06:02 +03:00

Validation labels are no longer part of the validation rule string, but retrieved from props on formualte-element

This commit is contained in:
Justin Schroeder 2018-02-01 10:47:11 -05:00
parent 7a54322e57
commit ab1330f27f
7 changed files with 43 additions and 33 deletions

View File

@ -130,19 +130,20 @@ simply chain your rules with pipes `|'. Additional arguments can be passed to
validation rules by using parenthesis after the rule name: validation rules by using parenthesis after the rule name:
``` ```
validation="required(My Label)|confirmed(Password Field, confirmation_field)" validation="required|confirmed(confirmation_field)"
``` ```
By convention the first argument is an alternate label for use in error messages. The field label used in built in validation methods is the `validationLabel`
This is still a fresh project, so pull requests for more built-in rules are attribute on your `formulate-element`. If no `validationLabel` is found then
appreciated! the `label` attribute is used, and if no `label` attribute is found it will
fall back to the fields `name` attribute (which is required).
#### Custom Validation Rules #### Custom Validation Rules
Validation rules are easy to write! They're just simple functions that are Validation rules are easy to write! They're just simple functions that are
always passed at least one argument, an object containing the `field` name, always passed at least one argument, an object containing the `field` name,
`value` of the field, `error` function to generate an error message, and all the `value` of the field, validation `label`, `error` function to generate an error
`values` of the entire form. message, and an object containing all the `values` for the entire form.
Additionally, validation rules can pass an unlimited number of extra arguments. Additionally, validation rules can pass an unlimited number of extra arguments.
These arguments are passed as the 2nd-nth arguments to the validation rule. These arguments are passed as the 2nd-nth arguments to the validation rule.
@ -151,10 +152,10 @@ attribute on the `formulate-element`.
```html ```html
<formulate-element <formulate-element
type="checkbox" type="password"
name="terms" name="password"
label="Please agree to our terms of service" label="Password"
validation="required(Terms of service)" validation="confirmed(password_confirmation_field)"
/> />
``` ```
@ -167,8 +168,8 @@ of rule functions in the plugins installation call:
```js ```js
Vue.use(formulate, { Vue.use(formulate, {
rules: { rules: {
isPizza ({field, value, error, values}, label) { isPizza ({field, value, error, values, label}) {
return value === 'pizza' ? false : `That is not pizza.` return value === 'pizza' ? false : `label is not pizza.`
} }
} }
}) })

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -100,10 +100,11 @@ export default {
form: this.name form: this.name
})) }))
}, },
async validateField ({field, validation}) { async validateField ({field, validation, label}) {
let errors = await this.$formulate.validationErrors({ let errors = await this.$formulate.validationErrors({
field, field,
value: this.values[field] value: this.values[field],
label
}, validation, this.values) }, validation, this.values)
if (!equals(errors || [], (this.validationErrors[field] || []))) { if (!equals(errors || [], (this.validationErrors[field] || []))) {
this.updateFieldValidationErrors({field, errors: errors || []}) this.updateFieldValidationErrors({field, errors: errors || []})
@ -111,9 +112,13 @@ export default {
return errors return errors
}, },
updateFormValidation () { updateFormValidation () {
this.fields.map(field => {
console.log(field.validationLabel || field.label || field.name)
})
this.fields.map(async field => this.validateField({ this.fields.map(async field => this.validateField({
field: field.name, field: field.name,
validation: field.validation validation: field.validation,
label: field.validationLabel || field.label || field.name
})) }))
}, },
submit () { submit () {

View File

@ -1,6 +1,6 @@
export default { export default {
required: ({field, value}, label) => `${label || field} is required`, required: ({label, value}) => `${label} is required`,
email: ({field, value}, label) => `${label || 'Email address'} is invalid.`, email: ({label, value}) => `${label} is invalid.`,
confirmed: ({field, value}, label) => `${label || field} does not match the confirmation field.`, confirmed: ({label, value}) => `${label} does not match the confirmation field.`,
default: ({field, value}) => `The ${field} field is invalid.` default: ({label, value}) => `This field is invalid.`
} }

View File

@ -93,10 +93,10 @@ class Formulate {
* @param {string} rulesString * @param {string} rulesString
* @param {Object} values * @param {Object} values
*/ */
async validationErrors ({field, value}, rulesString, values) { async validationErrors ({field, value, label}, rulesString, values) {
return rulesString ? Promise.all( return rulesString ? Promise.all(
this.parseRules(rulesString) this.parseRules(rulesString)
.map(({rule, args}) => this.rules[rule]({field, value, error: this.errorFactory(rule), values}, ...args)) .map(({rule, args}) => this.rules[rule]({field, value, label, error: this.errorFactory(rule), values}, ...args))
).then(responses => responses.reduce((errors, error) => { ).then(responses => responses.reduce((errors, error) => {
return error ? (Array.isArray(errors) ? errors.concat(error) : [error]) : errors return error ? (Array.isArray(errors) ? errors.concat(error) : [error]) : errors
}, false)) : false }, false)) : false

View File

@ -4,7 +4,7 @@ export default {
* @param {Object} field * @param {Object} field
* @param {string} label * @param {string} label
*/ */
async required ({field, value, error}, label) { async required ({value, error}) {
return (!value || (Array.isArray(value) && !value.length)) ? error(...arguments) : false return (!value || (Array.isArray(value) && !value.length)) ? error(...arguments) : false
}, },
@ -13,7 +13,7 @@ export default {
* @param {Object} field * @param {Object} field
* @param {string} label * @param {string} label
*/ */
async email ({field, value, error}, label) { async email ({value, error}) {
// eslint-disable-next-line // eslint-disable-next-line
var re = /^(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/; var re = /^(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/;
return (value && !re.test(value.toLowerCase())) ? error(...arguments) : false return (value && !re.test(value.toLowerCase())) ? error(...arguments) : false
@ -25,7 +25,7 @@ export default {
* @param {string} label * @param {string} label
* @param {string} confirmField (uses `${field}_confirmation` by default) * @param {string} confirmField (uses `${field}_confirmation` by default)
*/ */
async confirmed ({field, value, error, values}, label, confirmField) { async confirmed ({field, value, error, values}, confirmField) {
confirmField = confirmField || `${field}_confirmation` confirmField = confirmField || `${field}_confirmation`
return (value && value !== values[confirmField]) ? error(...arguments) : false return (value && value !== values[confirmField]) ? error(...arguments) : false
} }

View File

@ -2,18 +2,18 @@ import test from 'ava'
import f from '../dist' import f from '../dist'
const rules = f.rules const rules = f.rules
const error = ({field, value}, label) => { const error = ({field, value, label}) => {
return `${field}${label}` return `${field}${label}`
} }
test('test required rule failure', async t => { test('test required rule failure', async t => {
let v = await rules.required({field: 'name', value: '', error}, 'xyz') let v = await rules.required({field: 'name', value: '', error, label: 'xyz'})
t.is('string', typeof v) t.is('string', typeof v)
t.is('namexyz', v) t.is('namexyz', v)
}) })
test('test required rule empty array failure', async t => { test('test required rule empty array failure', async t => {
let v = await rules.required({field: 'name', value: [], error}, 'xyz') let v = await rules.required({field: 'name', value: [], error, label: 'xyz'})
t.is('namexyz', v) t.is('namexyz', v)
}) })
@ -26,7 +26,7 @@ test('test email rule with valid email', async t => {
}) })
test('test email rule with invalid email', async t => { test('test email rule with invalid email', async t => {
t.is('email123', await rules.email({field: 'email', value: 'invalid@example', error}, '123')) t.is('email123', await rules.email({field: 'email', value: 'invalid@example', error, label: '123'}))
}) })
test('test email with empty email', async t => { test('test email with empty email', async t => {
@ -37,34 +37,38 @@ test('test confirmed passes', async t => {
t.is(false, await rules.confirmed({ t.is(false, await rules.confirmed({
field: 'password', field: 'password',
value: 'password', value: 'password',
label: '123',
error, error,
values: {password_confirmation: 'password'} values: {password_confirmation: 'password'}
}, '123')) }))
}) })
test('test confirmed passes custom field', async t => { test('test confirmed passes custom field', async t => {
t.is(false, await rules.confirmed({ t.is(false, await rules.confirmed({
field: 'password', field: 'password',
value: 'password', value: 'password',
label: '123',
error, error,
values: {customfield: 'password'} values: {customfield: 'password'}
}, '123', 'customfield')) }, 'customfield'))
}) })
test('test confirmed fails', async t => { test('test confirmed fails', async t => {
t.is('password123', await rules.confirmed({ t.is('password123', await rules.confirmed({
field: 'password', field: 'password',
value: 'password', value: 'password',
label: '123',
error, error,
values: {password_confirmation: 'pAssword'} values: {password_confirmation: 'pAssword'}
}, '123')) }))
}) })
test('test empty confirmed passes', async t => { test('test empty confirmed passes', async t => {
t.is(false, await rules.confirmed({ t.is(false, await rules.confirmed({
field: 'password', field: 'password',
value: '', value: '',
label: '123',
error, error,
values: {password_confirmation: ''} values: {password_confirmation: ''}
}, '123')) }))
}) })