Skip to content

Commit

Permalink
feat: add pattern validation rule
Browse files Browse the repository at this point in the history
  • Loading branch information
14nrv committed Nov 17, 2018
1 parent 3eacdd3 commit c98b194
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 29 deletions.
33 changes: 14 additions & 19 deletions src/components/Fields/Control.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import Textarea from '@/components/Fields/Textarea'
import Checkbox from '@/components/Fields/Checkbox'
import Radio from '@/components/Fields/Radio'
const NOT_NORMAL_INPUT = ['textarea', 'select', 'checkbox', 'radio', 'number']
const NOT_NORMAL_INPUT = ['textarea', 'select', 'checkbox', 'radio']
export default {
name: 'Control',
Expand Down Expand Up @@ -61,30 +61,25 @@ export default {
return !NOT_NORMAL_INPUT.includes(this.item.type)
},
getComponent () {
return (this.isNormalInput || this.item.type === 'number')
? 'input'
: this.item.type
return this.isNormalInput ? 'input' : this.item.type
},
getValidation () {
const { type, minLength, maxLength, min, max } = this.item
const { type, minLength, maxLength, min, max, pattern } = this.item
const { defaultMinLength, defaultMaxLength, defaultMin, defaultMax } = this.$parent
const isNormalInputOrTextarea = this.isNormalInput || type === 'textarea'
const isInputNumber = type === 'number'
let validation = { required: this.isRequired }
if (this.isNormalInput || type === 'textarea') {
validation = {
pattern
? validation = { ...validation, regex: new RegExp(pattern) }
: isNormalInputOrTextarea && (validation = {
...validation,
min: minLength || defaultMinLength,
max: maxLength || defaultMaxLength
}
}
this.isNormalInput && (validation = { ...validation, email: type === 'email' })
type === 'number' && (validation = {
...validation,
min_value: min || defaultMin,
max_value: max || defaultMax
})
email: type === 'email',
min: !isInputNumber ? minLength || defaultMinLength : false,
max: !isInputNumber ? maxLength || defaultMaxLength : false,
min_value: isInputNumber ? min || defaultMin : false,
max_value: isInputNumber ? max || defaultMax : false
})
return validation
}
Expand Down
15 changes: 11 additions & 4 deletions src/components/Fields/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
:placeholder="item.placeholder",
:class="{ 'is-danger': !!error }",
:required="item.isRequired !== false",
:minlength="item.type !== 'number' ? item.minLength || defaultMinLength : undefined",
:maxlength="item.type !== 'number' ? item.maxLength || defaultMaxLength : undefined",
:min="item.type === 'number' ? item.min || defaultMin : undefined",
:max="item.type === 'number' ? item.max || defaultMax : undefined",
:minlength="!isInputNumber && !hasPattern ? item.minLength || defaultMinLength : undefined",
:maxlength="!isInputNumber && !hasPattern ? item.maxLength || defaultMaxLength : undefined",
:min="isInputNumber ? item.min || defaultMin : undefined",
:max="isInputNumber ? item.max || defaultMax : undefined",
:pattern="item.pattern",
v-model="value",
@input="updateValue",
@change="updateValue",
Expand All @@ -28,6 +29,12 @@ export default {
this.value = this.item.value
},
computed: {
hasPattern () {
return !!this.item.pattern
},
isInputNumber () {
return this.item.type === 'number'
},
defaultMin () {
return this.$parent.$parent.defaultMin
},
Expand Down
35 changes: 32 additions & 3 deletions src/components/Form/Form.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ const $inputSubmit = 'input[type=submit]'
const $reset = 'input[type=reset]'
const $inputFirstName = 'input[name=first-name]'
const $inputLastName = 'input[name=last-name]'
const $inputPassword = 'input[name=password]'
const $error = '.help.is-danger'

const FORM_NAME = 'testFormName'
const DEFAULT_VALUE = 'test'
const EMAIL_VALUE = `${DEFAULT_VALUE}@aol.fr`
const RADIO_VALUE = 'Radio-One'
const NUMBER_VALUE = '18'
const ZIP_VALUE = '12345'
const PASSWORD_VALUE = 'password'
const PASSWORD_VALUE = ZIP_VALUE

const getInitialValue = (label, node, attribute) =>
fields
Expand All @@ -38,9 +40,11 @@ const CHECKBOX_VALUE = getInitialValue('Checkbox', 'items', 'checked')

const allFields = flatten(fields)
const allNormalInputLabel = allFields
.filter(x => !x.type || x.type === 'password' || x.type === 'tel')
.filter(x => !x.type || x.type === 'tel')
.map(x => x.label)

const fieldWithPattern = allFields.find(({ pattern }) => pattern)

describe('Form', () => {
beforeEach(() => {
wrapper = mount(Form, {
Expand All @@ -66,7 +70,7 @@ describe('Form', () => {
)

b.type(EMAIL_VALUE, 'input[name=email]')
b.type(PASSWORD_VALUE, 'input[name=password]')
b.type(PASSWORD_VALUE, $inputPassword)
b.type(NUMBER_VALUE, 'input[name=age]')
b.type(ZIP_VALUE, 'input[name=zip]')
b.type(DEFAULT_VALUE, 'textarea[name=message]')
Expand Down Expand Up @@ -143,6 +147,7 @@ describe('Form', () => {
b.hasAttribute('min', '0', 'input[name=zip]')
b.hasAttribute('min', '18', 'input[name=age]')
b.hasAttribute('max', '99', 'input[name=age]')
b.hasAttribute('pattern', fieldWithPattern.pattern, $inputPassword)
})

it('validate on blur', async () => {
Expand All @@ -156,6 +161,30 @@ describe('Form', () => {
b.domHas(`${$inputLastName}${isDanger}`)
})

it('add pattern rule validation', async () => {
wrapper.destroy()

const passwordField = {
label: 'Password',
pattern: '^([0-9]+)$'
}
wrapper.setProps({ formFields: [passwordField] })
await wrapper.vm.$nextTick()

b.domHasNot($error)

b.type(DEFAULT_VALUE, $inputPassword)
await wrapper.vm.$nextTick()

b.see('The Password field format is invalid.', $error)
expect(wrapper.vm.isFormValid).toBeFalsy()

b.type(PASSWORD_VALUE, $inputPassword)
await wrapper.vm.$nextTick()

b.domHasNot($error)
})

describe('default value', () => {
it('set default value on radio', async () => {
const inputSubmit = b.find($inputSubmit)
Expand Down
7 changes: 4 additions & 3 deletions src/components/Form/fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
{
"label": "First Name",
"value": "fir",
"minLength": 4
"minLength": 4,
"maxLength": 20
},
{
"label": "Last Name",
Expand Down Expand Up @@ -67,8 +68,8 @@
{
"label": "Password",
"type": "password",
"minLength": 5,
"maxLength": 10
"pattern": ".[0-9]{4,}$",
"help": "(5 digits at least)"
}
],
{
Expand Down

0 comments on commit c98b194

Please sign in to comment.