style: Addition of the eslint rules
This commit is contained in:
parent
095f406fea
commit
acb6357433
32
.eslintrc.js
32
.eslintrc.js
@ -1,22 +1,42 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: 'babel-eslint',
|
parser: 'babel-eslint',
|
||||||
sourceType: 'module'
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
||||||
extends: [
|
extends: [
|
||||||
'standard',
|
'standard',
|
||||||
'plugin:vue/recommended'
|
'@vue/standard',
|
||||||
|
'plugin:vue/recommended',
|
||||||
],
|
],
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
},
|
},
|
||||||
// add your custom rules here
|
|
||||||
'rules': {
|
rules: {
|
||||||
// allow paren-less arrow functions
|
// allow paren-less arrow functions
|
||||||
'arrow-parens': 0,
|
'arrow-parens': 0,
|
||||||
|
'comma-dangle': ['error', 'only-multiline'],
|
||||||
|
'indent': ['error', 4],
|
||||||
|
'max-depth': ['error', 3],
|
||||||
|
'max-lines-per-function': ['error', 40],
|
||||||
|
'no-console': ['warn', {allow: ['warn', 'error']}],
|
||||||
// allow debugger during development
|
// allow debugger during development
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||||
}
|
'vue/html-closing-bracket-spacing': ['error', {
|
||||||
|
startTag: 'never',
|
||||||
|
endTag: 'never',
|
||||||
|
selfClosingTag: 'always',
|
||||||
|
}],
|
||||||
|
'vue/html-indent': ['error', 4, {
|
||||||
|
attribute: 1,
|
||||||
|
closeBracket: 0,
|
||||||
|
alignAttributesVertically: true,
|
||||||
|
ignores: [],
|
||||||
|
}],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import SpecimenSelect from './specimens/SpecimenSelect'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
SpecimenButton,
|
SpecimenButton,
|
||||||
SpecimenBox,
|
SpecimenBox,
|
||||||
@ -34,21 +35,22 @@ export default {
|
|||||||
SpecimenGroup,
|
SpecimenGroup,
|
||||||
SpecimenFile,
|
SpecimenFile,
|
||||||
SpecimenSlider,
|
SpecimenSlider,
|
||||||
SpecimenSelect
|
SpecimenSelect,
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
$formulate-font-stack: Arial, sans-serif;
|
||||||
|
$formulate-gray: gray;
|
||||||
|
$formulate-green: green;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: $formulate-font-stack;
|
font-family: $formulate-font-stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -61,6 +63,7 @@ h2 {
|
|||||||
margin: 2em 0 0 0;
|
margin: 2em 0 0 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.specimen-list {
|
.specimen-list {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
@ -68,8 +71,8 @@ h2 {
|
|||||||
@media (min-width: 756px) {
|
@media (min-width: 756px) {
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.specimens {
|
.specimens {
|
||||||
@media (min-width: 500px) {
|
@media (min-width: 500px) {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueFormulate from '../src/Formulate'
|
import VueFormulario from '../src/Formulario'
|
||||||
import FormulateSpecimens from './FormulateSpecimens.vue'
|
import FormulateSpecimens from './FormulateSpecimens.vue'
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
Vue.use(VueFormulario)
|
||||||
Vue.use(VueFormulate)
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
render: h => h(FormulateSpecimens)
|
render: h => h(FormulateSpecimens)
|
||||||
|
@ -47,9 +47,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
"@vue/cli-plugin-eslint": "^4.3.1",
|
"@vue/cli-plugin-eslint": "^4.3.1",
|
||||||
"@vue/cli-service": "^4.5.4",
|
"@vue/cli-service": "^4.5.4",
|
||||||
"@vue/component-compiler-utils": "^3.1.2",
|
"@vue/component-compiler-utils": "^3.1.2",
|
||||||
|
"@vue/eslint-config-standard": "^5.1.2",
|
||||||
"@vue/test-utils": "^1.0.2",
|
"@vue/test-utils": "^1.0.2",
|
||||||
"autoprefixer": "^9.7.6",
|
"autoprefixer": "^9.7.6",
|
||||||
"babel-core": "^7.0.0-bridge.0",
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import nanoid from 'nanoid/non-secure'
|
import nanoid from 'nanoid/non-secure'
|
||||||
|
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
/**
|
/**
|
||||||
* The file upload class holds and represents a file’s upload state durring
|
* The file upload class holds and represents a file’s upload state durring
|
||||||
* the upload flow.
|
* the upload flow.
|
||||||
@ -7,8 +8,9 @@ import nanoid from 'nanoid/non-secure'
|
|||||||
class FileUpload {
|
class FileUpload {
|
||||||
/**
|
/**
|
||||||
* Create a file upload object.
|
* Create a file upload object.
|
||||||
* @param {FileList} fileList
|
* @param {FileList} input
|
||||||
* @param {object} context
|
* @param {object} context
|
||||||
|
* @param {object} options
|
||||||
*/
|
*/
|
||||||
constructor (input, context, options = {}) {
|
constructor (input, context, options = {}) {
|
||||||
this.input = input
|
this.input = input
|
||||||
@ -27,7 +29,6 @@ class FileUpload {
|
|||||||
/**
|
/**
|
||||||
* Given a pre-existing array of files, create a faux FileList.
|
* Given a pre-existing array of files, create a faux FileList.
|
||||||
* @param {array} items expects an array of objects [{ url: '/uploads/file.pdf' }]
|
* @param {array} items expects an array of objects [{ url: '/uploads/file.pdf' }]
|
||||||
* @param {string} pathKey the object-key to access the url (defaults to "url")
|
|
||||||
*/
|
*/
|
||||||
rehydrateFileList (items) {
|
rehydrateFileList (items) {
|
||||||
const fauxFileList = items.reduce((fileList, item) => {
|
const fauxFileList = items.reduce((fileList, item) => {
|
||||||
@ -48,15 +49,12 @@ class FileUpload {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Produce an array of files and alert the callback.
|
* Produce an array of files and alert the callback.
|
||||||
* @param {FileList}
|
* @param {FileList} fileList
|
||||||
*/
|
*/
|
||||||
addFileList (fileList) {
|
addFileList (fileList) {
|
||||||
for (let i = 0; i < fileList.length; i++) {
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
const file = fileList[i]
|
const file = fileList[i]
|
||||||
const uuid = nanoid()
|
const uuid = nanoid()
|
||||||
const removeFile = function () {
|
|
||||||
this.removeFile(uuid)
|
|
||||||
}
|
|
||||||
this.files.push({
|
this.files.push({
|
||||||
progress: false,
|
progress: false,
|
||||||
error: false,
|
error: false,
|
||||||
@ -66,7 +64,7 @@ class FileUpload {
|
|||||||
file,
|
file,
|
||||||
uuid,
|
uuid,
|
||||||
path: false,
|
path: false,
|
||||||
removeFile: removeFile.bind(this),
|
removeFile: () => this.removeFile(uuid),
|
||||||
previewData: file.previewData || false
|
previewData: file.previewData || false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -86,16 +84,11 @@ class FileUpload {
|
|||||||
* https://github.com/axios/axios/issues/737
|
* https://github.com/axios/axios/issues/737
|
||||||
*/
|
*/
|
||||||
uploaderIsAxios () {
|
uploaderIsAxios () {
|
||||||
if (
|
return this.hasUploader &&
|
||||||
this.hasUploader &&
|
|
||||||
typeof this.context.uploader.request === 'function' &&
|
typeof this.context.uploader.request === 'function' &&
|
||||||
typeof this.context.uploader.get === 'function' &&
|
typeof this.context.uploader.get === 'function' &&
|
||||||
typeof this.context.uploader.delete === 'function' &&
|
typeof this.context.uploader.delete === 'function' &&
|
||||||
typeof this.context.uploader.post === 'function'
|
typeof this.context.uploader.post === 'function'
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,13 +3,15 @@ import rules from './libs/rules'
|
|||||||
import mimes from './libs/mimes'
|
import mimes from './libs/mimes'
|
||||||
import FileUpload from './FileUpload'
|
import FileUpload from './FileUpload'
|
||||||
import RuleValidationMessages from './RuleValidationMessages'
|
import RuleValidationMessages from './RuleValidationMessages'
|
||||||
import { arrayify, parseLocale, has } from './libs/utils'
|
import { arrayify } from './libs/utils'
|
||||||
import isPlainObject from 'is-plain-object'
|
import isPlainObject from 'is-plain-object'
|
||||||
import fauxUploader from './libs/faux-uploader'
|
import fauxUploader from './libs/faux-uploader'
|
||||||
|
|
||||||
import FormularioForm from './FormularioForm.vue'
|
import FormularioForm from './FormularioForm.vue'
|
||||||
import FormularioInput from './FormularioInput.vue'
|
import FormularioInput from './FormularioInput.vue'
|
||||||
import FormularioGrouping from './FormularioGrouping.vue'
|
import FormularioGrouping from './FormularioGrouping.vue'
|
||||||
|
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
/**
|
/**
|
||||||
* The base formulario library.
|
* The base formulario library.
|
||||||
*/
|
*/
|
||||||
@ -23,7 +25,7 @@ class Formulario {
|
|||||||
components: {
|
components: {
|
||||||
FormularioForm,
|
FormularioForm,
|
||||||
FormularioInput,
|
FormularioInput,
|
||||||
FormularioGrouping,
|
FormularioGrouping
|
||||||
},
|
},
|
||||||
library,
|
library,
|
||||||
rules,
|
rules,
|
||||||
@ -48,16 +50,18 @@ class Formulario {
|
|||||||
install (Vue, options) {
|
install (Vue, options) {
|
||||||
Vue.prototype.$formulario = this
|
Vue.prototype.$formulario = this
|
||||||
this.options = this.defaults
|
this.options = this.defaults
|
||||||
var plugins = this.defaults.plugins
|
let plugins = this.defaults.plugins
|
||||||
if (options && Array.isArray(options.plugins) && options.plugins.length) {
|
if (options && Array.isArray(options.plugins) && options.plugins.length) {
|
||||||
plugins = plugins.concat(options.plugins)
|
plugins = plugins.concat(options.plugins)
|
||||||
}
|
}
|
||||||
plugins.forEach(plugin => (typeof plugin === 'function') ? plugin(this) : null)
|
plugins.forEach(plugin => (typeof plugin === 'function') ? plugin(this) : null)
|
||||||
this.extend(options || {})
|
this.extend(options || {})
|
||||||
for (var componentName in this.options.components) {
|
for (const componentName in this.options.components) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(this.options.components, componentName)) {
|
||||||
Vue.component(componentName, this.options.components[componentName])
|
Vue.component(componentName, this.options.components[componentName])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produce a deterministically generated id based on the sequence by which it
|
* Produce a deterministically generated id based on the sequence by which it
|
||||||
@ -95,9 +99,10 @@ class Formulario {
|
|||||||
* @param {boolean} concatArrays
|
* @param {boolean} concatArrays
|
||||||
*/
|
*/
|
||||||
merge (base, mergeWith, concatArrays = true) {
|
merge (base, mergeWith, concatArrays = true) {
|
||||||
var merged = {}
|
const merged = {}
|
||||||
for (var key in base) {
|
|
||||||
if (mergeWith.hasOwnProperty(key)) {
|
for (const key in base) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(mergeWith, key)) {
|
||||||
if (isPlainObject(mergeWith[key]) && isPlainObject(base[key])) {
|
if (isPlainObject(mergeWith[key]) && isPlainObject(base[key])) {
|
||||||
merged[key] = this.merge(base[key], mergeWith[key], concatArrays)
|
merged[key] = this.merge(base[key], mergeWith[key], concatArrays)
|
||||||
} else if (concatArrays && Array.isArray(base[key]) && Array.isArray(mergeWith[key])) {
|
} else if (concatArrays && Array.isArray(base[key]) && Array.isArray(mergeWith[key])) {
|
||||||
@ -109,11 +114,13 @@ class Formulario {
|
|||||||
merged[key] = base[key]
|
merged[key] = base[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var prop in mergeWith) {
|
|
||||||
if (!merged.hasOwnProperty(prop)) {
|
for (const prop in mergeWith) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(merged, prop)) {
|
||||||
merged[prop] = mergeWith[prop]
|
merged[prop] = mergeWith[prop]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return merged
|
return merged
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,9 +129,10 @@ class Formulario {
|
|||||||
* @param {string} type
|
* @param {string} type
|
||||||
*/
|
*/
|
||||||
classify (type) {
|
classify (type) {
|
||||||
if (this.options.library.hasOwnProperty(type)) {
|
if (Object.prototype.hasOwnProperty.call(this.options.library, type)) {
|
||||||
return this.options.library[type].classification
|
return this.options.library[type].classification
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'unknown'
|
return 'unknown'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,9 +141,10 @@ class Formulario {
|
|||||||
* @param {string} type
|
* @param {string} type
|
||||||
*/
|
*/
|
||||||
component (type) {
|
component (type) {
|
||||||
if (this.options.library.hasOwnProperty(type)) {
|
if (Object.prototype.hasOwnProperty.call(this.options.library, type)) {
|
||||||
return this.options.library[type].component
|
return this.options.library[type].component
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,16 +160,16 @@ class Formulario {
|
|||||||
* Get the validation message for a particular error.
|
* Get the validation message for a particular error.
|
||||||
*/
|
*/
|
||||||
validationMessage (rule, validationContext, vm) {
|
validationMessage (rule, validationContext, vm) {
|
||||||
if (this.options.validationMessages.hasOwnProperty(rule)) {
|
if (Object.prototype.hasOwnProperty.call(this.options.validationMessages, rule)) {
|
||||||
return this.options.validationMessages[rule](vm, validationContext)
|
return this.options.validationMessages[rule](vm, validationContext)
|
||||||
} else {
|
} else {
|
||||||
return this.options.validationMessages['default'](vm, validationContext)
|
return this.options.validationMessages.default(vm, validationContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an instance of a FormularioForm register it.
|
* Given an instance of a FormularioForm register it.
|
||||||
* @param {vm} form
|
* @param {Vue} form
|
||||||
*/
|
*/
|
||||||
register (form) {
|
register (form) {
|
||||||
if (form.$options.name === 'FormularioForm' && form.name) {
|
if (form.$options.name === 'FormularioForm' && form.name) {
|
||||||
@ -170,7 +179,7 @@ class Formulario {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an instance of a form, remove it from the registry.
|
* Given an instance of a form, remove it from the registry.
|
||||||
* @param {vm} form
|
* @param {Vue} form
|
||||||
*/
|
*/
|
||||||
deregister (form) {
|
deregister (form) {
|
||||||
if (
|
if (
|
||||||
@ -188,7 +197,7 @@ class Formulario {
|
|||||||
*
|
*
|
||||||
* @param {error} err
|
* @param {error} err
|
||||||
* @param {string} formName
|
* @param {string} formName
|
||||||
* @param {error}
|
* @param {boolean} skip
|
||||||
*/
|
*/
|
||||||
handle (err, formName, skip = false) {
|
handle (err, formName, skip = false) {
|
||||||
const e = skip ? err : this.options.errorHandler(err, formName)
|
const e = skip ? err : this.options.errorHandler(err, formName)
|
||||||
|
@ -16,13 +16,16 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="file.previewData"
|
:src="file.previewData"
|
||||||
|
alt=""
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="formulario-file-name"
|
class="formulario-file-name"
|
||||||
:title="file.name"
|
:title="file.name"
|
||||||
v-text="file.name"
|
v-text="file.name"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="file.progress !== false"
|
v-if="file.progress !== false"
|
||||||
:data-just-finished="file.justFinished"
|
:data-just-finished="file.justFinished"
|
||||||
@ -34,12 +37,14 @@
|
|||||||
:style="{width: file.progress + '%'}"
|
:style="{width: file.progress + '%'}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="(file.complete && !file.justFinished) || file.progress === false"
|
v-if="(file.complete && !file.justFinished) || file.progress === false"
|
||||||
class="formulario-file-remove"
|
class="formulario-file-remove"
|
||||||
@click="file.removeFile"
|
@click="file.removeFile"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="file.error"
|
v-if="file.error"
|
||||||
class="formulario-file-upload-error"
|
class="formulario-file-upload-error"
|
||||||
@ -54,21 +59,25 @@ import FileUpload from './FileUpload'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormularioFiles',
|
name: 'FormularioFiles',
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
files: {
|
files: {
|
||||||
type: FileUpload,
|
type: FileUpload,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
imagePreview: {
|
imagePreview: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
fileUploads () {
|
fileUploads () {
|
||||||
return this.files.files || []
|
return this.files.files || []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
files () {
|
files () {
|
||||||
if (this.imagePreview) {
|
if (this.imagePreview) {
|
||||||
@ -76,6 +85,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.imagePreview) {
|
if (this.imagePreview) {
|
||||||
this.files.loadPreviews()
|
this.files.loadPreviews()
|
||||||
|
@ -13,6 +13,8 @@ import useRegistry, { useRegistryComputed, useRegistryMethods, useRegistryProvid
|
|||||||
import FormSubmission from './FormSubmission'
|
import FormSubmission from './FormSubmission'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'FormularioForm',
|
||||||
|
|
||||||
provide () {
|
provide () {
|
||||||
return {
|
return {
|
||||||
...useRegistryProviders(this),
|
...useRegistryProviders(this),
|
||||||
@ -22,33 +24,39 @@ export default {
|
|||||||
path: ''
|
path: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: 'FormularioForm',
|
|
||||||
model: {
|
model: {
|
||||||
prop: 'formularioValue',
|
prop: 'formularioValue',
|
||||||
event: 'input'
|
event: 'input'
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
formularioValue: {
|
formularioValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
|
||||||
values: {
|
values: {
|
||||||
type: [Object, Boolean],
|
type: [Object, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
type: [Object, Boolean],
|
type: [Object, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
formErrors: {
|
formErrors: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => ([])
|
default: () => ([])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
...useRegistry(this),
|
...useRegistry(this),
|
||||||
@ -58,51 +66,58 @@ export default {
|
|||||||
namedFieldErrors: {}
|
namedFieldErrors: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...useRegistryComputed(),
|
...useRegistryComputed(),
|
||||||
|
|
||||||
classes () {
|
classes () {
|
||||||
const classes = { 'formulario-form': true }
|
return {
|
||||||
if (this.name) {
|
'formulario-form': true,
|
||||||
classes[`formulario-form--${this.name}`] = true
|
[`formulario-form--${this.name}`]: !!this.name
|
||||||
}
|
}
|
||||||
return classes
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mergedFormErrors () {
|
mergedFormErrors () {
|
||||||
return this.formErrors.concat(this.namedErrors)
|
return this.formErrors.concat(this.namedErrors)
|
||||||
},
|
},
|
||||||
|
|
||||||
mergedFieldErrors () {
|
mergedFieldErrors () {
|
||||||
const errors = {}
|
const errors = {}
|
||||||
|
|
||||||
if (this.errors) {
|
if (this.errors) {
|
||||||
for (const fieldName in this.errors) {
|
for (const fieldName in this.errors) {
|
||||||
errors[fieldName] = arrayify(this.errors[fieldName])
|
errors[fieldName] = arrayify(this.errors[fieldName])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const fieldName in this.namedFieldErrors) {
|
for (const fieldName in this.namedFieldErrors) {
|
||||||
errors[fieldName] = arrayify(this.namedFieldErrors[fieldName])
|
errors[fieldName] = arrayify(this.namedFieldErrors[fieldName])
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
},
|
},
|
||||||
|
|
||||||
hasFormErrorObservers () {
|
hasFormErrorObservers () {
|
||||||
return !!this.errorObservers.filter(o => o.type === 'form').length
|
return !!this.errorObservers.filter(o => o.type === 'form').length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
formularioValue: {
|
formularioValue: {
|
||||||
handler (values) {
|
handler (values) {
|
||||||
if (this.isVmodeled &&
|
if (this.isVmodeled && values && typeof values === 'object') {
|
||||||
values &&
|
|
||||||
typeof values === 'object'
|
|
||||||
) {
|
|
||||||
this.setValues(values)
|
this.setValues(values)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
|
|
||||||
mergedFormErrors (errors) {
|
mergedFormErrors (errors) {
|
||||||
this.errorObservers
|
this.errorObservers
|
||||||
.filter(o => o.type === 'form')
|
.filter(o => o.type === 'form')
|
||||||
.forEach(o => o.callback(errors))
|
.forEach(o => o.callback(errors))
|
||||||
},
|
},
|
||||||
|
|
||||||
mergedFieldErrors: {
|
mergedFieldErrors: {
|
||||||
handler (errors) {
|
handler (errors) {
|
||||||
this.errorObservers
|
this.errorObservers
|
||||||
@ -112,20 +127,25 @@ export default {
|
|||||||
immediate: true
|
immediate: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created () {
|
created () {
|
||||||
this.$formulario.register(this)
|
this.$formulario.register(this)
|
||||||
this.applyInitialValues()
|
this.applyInitialValues()
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyed () {
|
destroyed () {
|
||||||
this.$formulario.deregister(this)
|
this.$formulario.deregister(this)
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
...useRegistryMethods(),
|
...useRegistryMethods(),
|
||||||
|
|
||||||
applyErrors ({ formErrors, inputErrors }) {
|
applyErrors ({ formErrors, inputErrors }) {
|
||||||
// given an object of errors, apply them to this form
|
// given an object of errors, apply them to this form
|
||||||
this.namedErrors = formErrors
|
this.namedErrors = formErrors
|
||||||
this.namedFieldErrors = inputErrors
|
this.namedFieldErrors = inputErrors
|
||||||
},
|
},
|
||||||
|
|
||||||
addErrorObserver (observer) {
|
addErrorObserver (observer) {
|
||||||
if (!this.errorObservers.find(obs => observer.callback === obs.callback)) {
|
if (!this.errorObservers.find(obs => observer.callback === obs.callback)) {
|
||||||
this.errorObservers.push(observer)
|
this.errorObservers.push(observer)
|
||||||
@ -136,14 +156,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeErrorObserver (observer) {
|
removeErrorObserver (observer) {
|
||||||
this.errorObservers = this.errorObservers.filter(obs => obs.callback !== observer)
|
this.errorObservers = this.errorObservers.filter(obs => obs.callback !== observer)
|
||||||
},
|
},
|
||||||
|
|
||||||
registerErrorComponent (component) {
|
registerErrorComponent (component) {
|
||||||
if (!this.errorComponents.includes(component)) {
|
if (!this.errorComponents.includes(component)) {
|
||||||
this.errorComponents.push(component)
|
this.errorComponents.push(component)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formSubmitted () {
|
formSubmitted () {
|
||||||
// perform validation here
|
// perform validation here
|
||||||
this.showErrors()
|
this.showErrors()
|
||||||
@ -159,6 +182,7 @@ export default {
|
|||||||
return undefined
|
return undefined
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
formularioFieldValidation (errorObject) {
|
formularioFieldValidation (errorObject) {
|
||||||
this.$emit('validation', errorObject)
|
this.$emit('validation', errorObject)
|
||||||
}
|
}
|
||||||
|
@ -10,33 +10,38 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'FormularioGrouping',
|
name: 'FormularioGrouping',
|
||||||
props: {
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
isArrayItem: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
provide () {
|
provide () {
|
||||||
return {
|
return {
|
||||||
path: this.groupPath
|
path: this.groupPath
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
inject: ['path'],
|
inject: ['path'],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
|
||||||
|
isArrayItem: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
groupPath () {
|
groupPath () {
|
||||||
if (this.isArrayItem) {
|
if (this.isArrayItem) {
|
||||||
return this.path + '[' + this.name + ']';
|
return `${this.path}[${this.name}]`
|
||||||
} else {
|
|
||||||
if (this.path === '') {
|
|
||||||
return this.name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.path + '.' + this.name;
|
if (this.path === '') {
|
||||||
|
return this.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return `${this.path}.${this.name}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,12 @@
|
|||||||
:data-is-showing-errors="hasVisibleErrors"
|
:data-is-showing-errors="hasVisibleErrors"
|
||||||
:data-type="type"
|
:data-type="type"
|
||||||
>
|
>
|
||||||
<slot :id="id" :context="context" :errors="errors" :validationErrors="validationErrors" />
|
<slot
|
||||||
|
:id="id"
|
||||||
|
:context="context"
|
||||||
|
:errors="errors"
|
||||||
|
:validationErrors="validationErrors"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -15,7 +20,9 @@ import { shallowEqualObjects, parseRules, snakeToCamel, has, arrayify, groupBail
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormularioInput',
|
name: 'FormularioInput',
|
||||||
|
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
|
||||||
provide () {
|
provide () {
|
||||||
return {
|
return {
|
||||||
// Allows sub-components of this input to register arbitrary rules.
|
// Allows sub-components of this input to register arbitrary rules.
|
||||||
@ -23,6 +30,7 @@ export default {
|
|||||||
formularioRemoveRule: this.removeRule
|
formularioRemoveRule: this.removeRule
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
inject: {
|
inject: {
|
||||||
formularioSetter: { default: undefined },
|
formularioSetter: { default: undefined },
|
||||||
formularioFieldValidation: { default: () => () => ({}) },
|
formularioFieldValidation: { default: () => () => ({}) },
|
||||||
@ -33,87 +41,107 @@ export default {
|
|||||||
removeErrorObserver: { default: undefined },
|
removeErrorObserver: { default: undefined },
|
||||||
path: { default: '' }
|
path: { default: '' }
|
||||||
},
|
},
|
||||||
|
|
||||||
model: {
|
model: {
|
||||||
prop: 'formularioValue',
|
prop: 'formularioValue',
|
||||||
event: 'input'
|
event: 'input'
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'text'
|
default: 'text'
|
||||||
},
|
},
|
||||||
|
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
formularioValue: {
|
formularioValue: {
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
value: {
|
value: {
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
id: {
|
id: {
|
||||||
type: [String, Boolean, Number],
|
type: [String, Boolean, Number],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
type: [String, Array, Boolean],
|
type: [String, Array, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
validation: {
|
validation: {
|
||||||
type: [String, Boolean, Array],
|
type: [String, Boolean, Array],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
validationName: {
|
validationName: {
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
errorBehavior: {
|
errorBehavior: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'blur',
|
default: 'blur',
|
||||||
validator: function (value) {
|
validator (value) {
|
||||||
return ['blur', 'live', 'submit'].includes(value)
|
return ['blur', 'live', 'submit'].includes(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showErrors: {
|
showErrors: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
imageBehavior: {
|
imageBehavior: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'preview'
|
default: 'preview'
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadUrl: {
|
uploadUrl: {
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
uploader: {
|
uploader: {
|
||||||
type: [Function, Object, Boolean],
|
type: [Function, Object, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadBehavior: {
|
uploadBehavior: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'live'
|
default: 'live'
|
||||||
},
|
},
|
||||||
|
|
||||||
preventWindowDrops: {
|
preventWindowDrops: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
|
||||||
validationMessages: {
|
validationMessages: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
|
||||||
validationRules: {
|
validationRules: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
|
||||||
disableErrors: {
|
disableErrors: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
defaultId: this.$formulario.nextId(this),
|
defaultId: this.$formulario.nextId(this),
|
||||||
@ -129,8 +157,10 @@ export default {
|
|||||||
messageRegistry: {}
|
messageRegistry: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...context,
|
...context,
|
||||||
|
|
||||||
parsedValidationRules () {
|
parsedValidationRules () {
|
||||||
const parsedValidationRules = {}
|
const parsedValidationRules = {}
|
||||||
Object.keys(this.validationRules).forEach(key => {
|
Object.keys(this.validationRules).forEach(key => {
|
||||||
@ -138,6 +168,7 @@ export default {
|
|||||||
})
|
})
|
||||||
return parsedValidationRules
|
return parsedValidationRules
|
||||||
},
|
},
|
||||||
|
|
||||||
messages () {
|
messages () {
|
||||||
const messages = {}
|
const messages = {}
|
||||||
Object.keys(this.validationMessages).forEach((key) => {
|
Object.keys(this.validationMessages).forEach((key) => {
|
||||||
@ -149,24 +180,28 @@ export default {
|
|||||||
return messages
|
return messages
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'$attrs': {
|
$attrs: {
|
||||||
handler (value) {
|
handler (value) {
|
||||||
this.updateLocalAttributes(value)
|
this.updateLocalAttributes(value)
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
|
|
||||||
proxy (newValue, oldValue) {
|
proxy (newValue, oldValue) {
|
||||||
this.performValidation()
|
this.performValidation()
|
||||||
if (!this.isVmodeled && !shallowEqualObjects(newValue, oldValue)) {
|
if (!this.isVmodeled && !shallowEqualObjects(newValue, oldValue)) {
|
||||||
this.context.model = newValue
|
this.context.model = newValue
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formularioValue (newValue, oldValue) {
|
formularioValue (newValue, oldValue) {
|
||||||
if (this.isVmodeled && !shallowEqualObjects(newValue, oldValue)) {
|
if (this.isVmodeled && !shallowEqualObjects(newValue, oldValue)) {
|
||||||
this.context.model = newValue
|
this.context.model = newValue
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showValidationErrors: {
|
showValidationErrors: {
|
||||||
handler (val) {
|
handler (val) {
|
||||||
this.$emit('error-visibility', val)
|
this.$emit('error-visibility', val)
|
||||||
@ -174,6 +209,7 @@ export default {
|
|||||||
immediate: true
|
immediate: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created () {
|
created () {
|
||||||
this.applyInitialValue()
|
this.applyInitialValue()
|
||||||
if (this.formularioRegister && typeof this.formularioRegister === 'function') {
|
if (this.formularioRegister && typeof this.formularioRegister === 'function') {
|
||||||
@ -187,6 +223,7 @@ export default {
|
|||||||
this.performValidation()
|
this.performValidation()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
if (!this.disableErrors && typeof this.removeErrorObserver === 'function') {
|
if (!this.disableErrors && typeof this.removeErrorObserver === 'function') {
|
||||||
this.removeErrorObserver(this.setErrors)
|
this.removeErrorObserver(this.setErrors)
|
||||||
@ -195,6 +232,7 @@ export default {
|
|||||||
this.formularioDeregister(this.nameOrFallback)
|
this.formularioDeregister(this.nameOrFallback)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getInitialValue () {
|
getInitialValue () {
|
||||||
if (has(this.$options.propsData, 'value')) {
|
if (has(this.$options.propsData, 'value')) {
|
||||||
@ -204,6 +242,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
|
|
||||||
applyInitialValue () {
|
applyInitialValue () {
|
||||||
// This should only be run immediately on created and ensures that the
|
// This should only be run immediately on created and ensures that the
|
||||||
// proxy and the model are both the same before any additional registration.
|
// proxy and the model are both the same before any additional registration.
|
||||||
@ -211,11 +250,13 @@ export default {
|
|||||||
this.context.model = this.proxy
|
this.context.model = this.proxy
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateLocalAttributes (value) {
|
updateLocalAttributes (value) {
|
||||||
if (!shallowEqualObjects(value, this.localAttributes)) {
|
if (!shallowEqualObjects(value, this.localAttributes)) {
|
||||||
this.localAttributes = value
|
this.localAttributes = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
performValidation () {
|
performValidation () {
|
||||||
let rules = parseRules(this.validation, this.$formulario.rules(this.parsedValidationRules))
|
let rules = parseRules(this.validation, this.$formulario.rules(this.parsedValidationRules))
|
||||||
// Add in ruleRegistry rules. These are added directly via injection from
|
// Add in ruleRegistry rules. These are added directly via injection from
|
||||||
@ -225,6 +266,7 @@ export default {
|
|||||||
.then(messages => this.didValidate(messages))
|
.then(messages => this.didValidate(messages))
|
||||||
return this.pendingValidation
|
return this.pendingValidation
|
||||||
},
|
},
|
||||||
|
|
||||||
runRules (rules) {
|
runRules (rules) {
|
||||||
const run = ([rule, args, ruleName, modifier]) => {
|
const run = ([rule, args, ruleName, modifier]) => {
|
||||||
var res = rule({
|
var res = rule({
|
||||||
@ -257,6 +299,7 @@ export default {
|
|||||||
resolveGroups(groupBails(rules))
|
resolveGroups(groupBails(rules))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
didValidate (messages) {
|
didValidate (messages) {
|
||||||
const validationChanged = !shallowEqualObjects(messages, this.validationErrors)
|
const validationChanged = !shallowEqualObjects(messages, this.validationErrors)
|
||||||
this.validationErrors = messages
|
this.validationErrors = messages
|
||||||
@ -268,15 +311,16 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getMessageObject (ruleName, args) {
|
getMessageObject (ruleName, args) {
|
||||||
let context = {
|
const context = {
|
||||||
args,
|
args,
|
||||||
name: this.mergedValidationName,
|
name: this.mergedValidationName,
|
||||||
value: this.context.model,
|
value: this.context.model,
|
||||||
vm: this,
|
vm: this,
|
||||||
formValues: this.getFormValues()
|
formValues: this.getFormValues()
|
||||||
};
|
}
|
||||||
let message = this.getMessageFunc(ruleName)(context);
|
const message = this.getMessageFunc(ruleName)(context)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message: message,
|
message: message,
|
||||||
@ -284,6 +328,7 @@ export default {
|
|||||||
context: context
|
context: context
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getMessageFunc (ruleName) {
|
getMessageFunc (ruleName) {
|
||||||
ruleName = snakeToCamel(ruleName)
|
ruleName = snakeToCamel(ruleName)
|
||||||
if (this.messages && typeof this.messages[ruleName] !== 'undefined') {
|
if (this.messages && typeof this.messages[ruleName] !== 'undefined') {
|
||||||
@ -297,6 +342,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return (context) => this.$formulario.validationMessage(ruleName, context, this)
|
return (context) => this.$formulario.validationMessage(ruleName, context, this)
|
||||||
},
|
},
|
||||||
|
|
||||||
hasValidationErrors () {
|
hasValidationErrors () {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@ -304,11 +350,13 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
getValidationErrors () {
|
getValidationErrors () {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.$nextTick(() => this.pendingValidation.then(() => resolve(this.getErrorObject())))
|
this.$nextTick(() => this.pendingValidation.then(() => resolve(this.getErrorObject())))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
getErrorObject () {
|
getErrorObject () {
|
||||||
return {
|
return {
|
||||||
name: this.context.nameOrFallback || this.context.name,
|
name: this.context.nameOrFallback || this.context.name,
|
||||||
@ -316,9 +364,11 @@ export default {
|
|||||||
hasErrors: !!this.validationErrors.length
|
hasErrors: !!this.validationErrors.length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setErrors (errors) {
|
setErrors (errors) {
|
||||||
this.localErrors = arrayify(errors)
|
this.localErrors = arrayify(errors)
|
||||||
},
|
},
|
||||||
|
|
||||||
registerRule (rule, args, ruleName, message = null) {
|
registerRule (rule, args, ruleName, message = null) {
|
||||||
if (!this.ruleRegistry.some(r => r[2] === ruleName)) {
|
if (!this.ruleRegistry.some(r => r[2] === ruleName)) {
|
||||||
// These are the raw rule format since they will be used directly.
|
// These are the raw rule format since they will be used directly.
|
||||||
@ -328,6 +378,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeRule (key) {
|
removeRule (key) {
|
||||||
const ruleIndex = this.ruleRegistry.findIndex(r => r[2] === key)
|
const ruleIndex = this.ruleRegistry.findIndex(r => r[2] === key)
|
||||||
if (ruleIndex >= 0) {
|
if (ruleIndex >= 0) {
|
||||||
|
@ -18,14 +18,14 @@ const validationMessages = {
|
|||||||
* The default render method for error messages.
|
* The default render method for error messages.
|
||||||
*/
|
*/
|
||||||
default: function (vm, context) {
|
default: function (vm, context) {
|
||||||
return vm.$t(`validation.default`, context)
|
return vm.$t('validation.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Valid accepted value.
|
* Valid accepted value.
|
||||||
*/
|
*/
|
||||||
accepted: function (vm, context) {
|
accepted: function (vm, context) {
|
||||||
return vm.$t(`validation.accepted`, context)
|
return vm.$t('validation.accepted', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,25 +33,25 @@ const validationMessages = {
|
|||||||
*/
|
*/
|
||||||
after: function (vm, context) {
|
after: function (vm, context) {
|
||||||
if (Array.isArray(context.args) && context.args.length) {
|
if (Array.isArray(context.args) && context.args.length) {
|
||||||
context['compare'] = context.args[0]
|
context.compare = context.args[0]
|
||||||
return vm.$t(`validation.after.compare`, context)
|
return vm.$t('validation.after.compare', context)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.$t(`validation.after.default`, context)
|
return vm.$t('validation.after.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value is not a letter.
|
* The value is not a letter.
|
||||||
*/
|
*/
|
||||||
alpha: function (vm, context) {
|
alpha: function (vm, context) {
|
||||||
return vm.$t(`validation.alpha`, context)
|
return vm.$t('validation.alpha', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rule: checks if the value is alpha numeric
|
* Rule: checks if the value is alpha numeric
|
||||||
*/
|
*/
|
||||||
alphanumeric: function (vm, context) {
|
alphanumeric: function (vm, context) {
|
||||||
return vm.$t(`validation.alphanumeric`, context)
|
return vm.$t('validation.alphanumeric', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,33 +59,33 @@ const validationMessages = {
|
|||||||
*/
|
*/
|
||||||
before: function (vm, context) {
|
before: function (vm, context) {
|
||||||
if (Array.isArray(context.args) && context.args.length) {
|
if (Array.isArray(context.args) && context.args.length) {
|
||||||
context['compare'] = context.args[0]
|
context.compare = context.args[0]
|
||||||
return vm.$t(`validation.before.compare`, context)
|
return vm.$t('validation.before.compare', context)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.$t(`validation.before.default`, context)
|
return vm.$t('validation.before.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value is not between two numbers or lengths
|
* The value is not between two numbers or lengths
|
||||||
*/
|
*/
|
||||||
between: function (vm, context) {
|
between: function (vm, context) {
|
||||||
context['from'] = context.args[0]
|
context.from = context.args[0]
|
||||||
context['to'] = context.args[1]
|
context.to = context.args[1]
|
||||||
|
|
||||||
const force = Array.isArray(context.args) && context.args[2] ? context.args[2] : false
|
const force = Array.isArray(context.args) && context.args[2] ? context.args[2] : false
|
||||||
if ((!isNaN(value) && force !== 'length') || force === 'value') {
|
if ((!isNaN(value) && force !== 'length') || force === 'value') {
|
||||||
return vm.$t(`validation.between.force`, context)
|
return vm.$t('validation.between.force', context)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.$t(`validation.between.default`, context)
|
return vm.$t('validation.between.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The confirmation field does not match
|
* The confirmation field does not match
|
||||||
*/
|
*/
|
||||||
confirm: function (vm, context) {
|
confirm: function (vm, context) {
|
||||||
return vm.$t(`validation.confirm`, context)
|
return vm.$t('validation.confirm', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,25 +93,25 @@ const validationMessages = {
|
|||||||
*/
|
*/
|
||||||
date: function (vm, context) {
|
date: function (vm, context) {
|
||||||
if (Array.isArray(context.args) && context.args.length) {
|
if (Array.isArray(context.args) && context.args.length) {
|
||||||
context['format'] = context.args[0]
|
context.format = context.args[0]
|
||||||
return vm.$t(`validation.date.format`, context)
|
return vm.$t('validation.date.format', context)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.$t(`validation.date.default`, context)
|
return vm.$t('validation.date.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is not a valid email address.
|
* Is not a valid email address.
|
||||||
*/
|
*/
|
||||||
email: function (vm, context) {
|
email: function (vm, context) {
|
||||||
return vm.$t(`validation.email.default`, context)
|
return vm.$t('validation.email.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends with specified value
|
* Ends with specified value
|
||||||
*/
|
*/
|
||||||
endsWith: function (vm, context) {
|
endsWith: function (vm, context) {
|
||||||
return vm.$t(`validation.endsWith.default`, context)
|
return vm.$t('validation.endsWith.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,44 +119,44 @@ const validationMessages = {
|
|||||||
*/
|
*/
|
||||||
in: function (vm, context) {
|
in: function (vm, context) {
|
||||||
if (typeof context.value === 'string' && context.value) {
|
if (typeof context.value === 'string' && context.value) {
|
||||||
return vm.$t(`validation.in.string`, context)
|
return vm.$t('validation.in.string', context)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.$t(`validation.in.default`, context)
|
return vm.$t('validation.in.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value is not a match.
|
* Value is not a match.
|
||||||
*/
|
*/
|
||||||
matches: function (vm, context) {
|
matches: function (vm, context) {
|
||||||
return vm.$t(`validation.matches.default`, context)
|
return vm.$t('validation.matches.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum value allowed.
|
* The maximum value allowed.
|
||||||
*/
|
*/
|
||||||
max: function (vm, context) {
|
max: function (vm, context) {
|
||||||
context['maximum'] = context.args[0]
|
context.maximum = context.args[0]
|
||||||
|
|
||||||
if (Array.isArray(context.value)) {
|
if (Array.isArray(context.value)) {
|
||||||
return vm.$tc(`validation.max.array`, context['maximum'], context)
|
return vm.$tc('validation.max.array', context.maximum, context)
|
||||||
}
|
}
|
||||||
const force = Array.isArray(context.args) && context.args[1] ? context.args[1] : false
|
const force = Array.isArray(context.args) && context.args[1] ? context.args[1] : false
|
||||||
if ((!isNaN(context.value) && force !== 'length') || force === 'value') {
|
if ((!isNaN(context.value) && force !== 'length') || force === 'value') {
|
||||||
return vm.$tc(`validation.max.force`, context['maximum'], context)
|
return vm.$tc('validation.max.force', context.maximum, context)
|
||||||
}
|
}
|
||||||
return vm.$tc(`validation.max.default`, context['maximum'], context)
|
return vm.$tc('validation.max.default', context.maximum, context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The (field-level) error message for mime errors.
|
* The (field-level) error message for mime errors.
|
||||||
*/
|
*/
|
||||||
mime: function (vm, context) {
|
mime: function (vm, context) {
|
||||||
context['types'] = context.args[0]
|
context.types = context.args[0]
|
||||||
if (context['types']) {
|
if (context.types) {
|
||||||
return vm.$t(`validation.mime.default`, context)
|
return vm.$t('validation.mime.default', context)
|
||||||
} else {
|
} else {
|
||||||
return vm.$t(`validation.mime.no_formats_allowed`, context)
|
return vm.$t('validation.mime.no_formats_allowed', context)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -164,51 +164,51 @@ const validationMessages = {
|
|||||||
* The maximum value allowed.
|
* The maximum value allowed.
|
||||||
*/
|
*/
|
||||||
min: function (vm, context) {
|
min: function (vm, context) {
|
||||||
context['minimum'] = context.args[0]
|
context.minimum = context.args[0]
|
||||||
|
|
||||||
if (Array.isArray(context.value)) {
|
if (Array.isArray(context.value)) {
|
||||||
return vm.$tc(`validation.min.array`, context['minimum'], context)
|
return vm.$tc('validation.min.array', context.minimum, context)
|
||||||
}
|
}
|
||||||
const force = Array.isArray(context.args) && context.args[1] ? context.args[1] : false
|
const force = Array.isArray(context.args) && context.args[1] ? context.args[1] : false
|
||||||
if ((!isNaN(context.value) && force !== 'length') || force === 'value') {
|
if ((!isNaN(context.value) && force !== 'length') || force === 'value') {
|
||||||
return vm.$tc(`validation.min.force`, context['minimum'], context)
|
return vm.$tc('validation.min.force', context.minimum, context)
|
||||||
}
|
}
|
||||||
return vm.$tc(`validation.min.default`, context['minimum'], context)
|
return vm.$tc('validation.min.default', context.minimum, context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The field is not an allowed value
|
* The field is not an allowed value
|
||||||
*/
|
*/
|
||||||
not: function (vm, context) {
|
not: function (vm, context) {
|
||||||
return vm.$t(`validation.not.default`, context)
|
return vm.$t('validation.not.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The field is not a number
|
* The field is not a number
|
||||||
*/
|
*/
|
||||||
number: function (vm, context) {
|
number: function (vm, context) {
|
||||||
return vm.$t(`validation.number.default`, context)
|
return vm.$t('validation.number.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required field.
|
* Required field.
|
||||||
*/
|
*/
|
||||||
required: function (vm, context) {
|
required: function (vm, context) {
|
||||||
return vm.$t(`validation.required.default`, context)
|
return vm.$t('validation.required.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts with specified value
|
* Starts with specified value
|
||||||
*/
|
*/
|
||||||
startsWith: function (vm, context) {
|
startsWith: function (vm, context) {
|
||||||
return vm.$t(`validation.startsWith.default`, context)
|
return vm.$t('validation.startsWith.default', context)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value is not a url.
|
* Value is not a url.
|
||||||
*/
|
*/
|
||||||
url: function (vm, context) {
|
url: function (vm, context) {
|
||||||
return vm.$t(`validation.url.default`, context)
|
return vm.$t('validation.url.default', context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +218,6 @@ const validationMessages = {
|
|||||||
*/
|
*/
|
||||||
export default function (instance) {
|
export default function (instance) {
|
||||||
instance.extend({
|
instance.extend({
|
||||||
validationMessages: validationMessages
|
validationMessages
|
||||||
})
|
})
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
const i = 'image/'
|
const i = 'image/'
|
||||||
export default {
|
export default {
|
||||||
'csv': 'text/csv',
|
csv: 'text/csv',
|
||||||
'gif': i + 'gif',
|
gif: i + 'gif',
|
||||||
'jpg': i + 'jpeg',
|
jpg: i + 'jpeg',
|
||||||
'jpeg': i + 'jpeg',
|
jpeg: i + 'jpeg',
|
||||||
'png': i + 'png',
|
png: i + 'png',
|
||||||
'pdf': 'application/pdf',
|
pdf: 'application/pdf',
|
||||||
'svg': i + 'svg+xml'
|
svg: i + 'svg+xml'
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Registry {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an item to the registry.
|
* Add an item to the registry.
|
||||||
* @param {string|array} key
|
* @param {string|array} name
|
||||||
* @param {vue} component
|
* @param {vue} component
|
||||||
*/
|
*/
|
||||||
add (name, component) {
|
add (name, component) {
|
||||||
@ -104,6 +104,7 @@ class Registry {
|
|||||||
/**
|
/**
|
||||||
* Reduce the registry.
|
* Reduce the registry.
|
||||||
* @param {function} callback
|
* @param {function} callback
|
||||||
|
* @param accumulator
|
||||||
*/
|
*/
|
||||||
reduce (callback, accumulator) {
|
reduce (callback, accumulator) {
|
||||||
this.registry.forEach((component, field) => {
|
this.registry.forEach((component, field) => {
|
||||||
@ -148,7 +149,7 @@ export function useRegistryComputed () {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
isVmodeled () {
|
isVmodeled () {
|
||||||
return !!(this.$options.propsData.hasOwnProperty('formularioValue') &&
|
return !!(Object.prototype.hasOwnProperty.call(this.$options.propsData, 'formularioValue') &&
|
||||||
this._events &&
|
this._events &&
|
||||||
Array.isArray(this._events.input) &&
|
Array.isArray(this._events.input) &&
|
||||||
this._events.input.length)
|
this._events.input.length)
|
||||||
@ -191,7 +192,7 @@ export function useRegistryMethods (without = []) {
|
|||||||
const { [field]: value, ...proxy } = this.proxy
|
const { [field]: value, ...proxy } = this.proxy
|
||||||
this.proxy = proxy
|
this.proxy = proxy
|
||||||
} else {
|
} else {
|
||||||
setNested(this.proxy, field, value);
|
setNested(this.proxy, field, value)
|
||||||
}
|
}
|
||||||
this.$emit('input', Object.assign({}, this.proxy))
|
this.$emit('input', Object.assign({}, this.proxy))
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import VueI18n from 'vue-i18n'
|
|
||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
import { mount, createLocalVue } from '@vue/test-utils'
|
import { mount, createLocalVue } from '@vue/test-utils'
|
||||||
|
|
||||||
import Formulario from '@/Formulario.js'
|
import Formulario from '@/Formulario.js'
|
||||||
import FormularioForm from '@/FormularioForm.vue'
|
import FormularioForm from '@/FormularioForm.vue'
|
||||||
import FormularioInput from '@/FormularioInput.vue'
|
import FormularioInput from '@/FormularioInput.vue'
|
||||||
@ -19,7 +18,9 @@ function validationMessages (instance) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.use(Formulario, {
|
const localVue = createLocalVue()
|
||||||
|
|
||||||
|
localVue.use(Formulario, {
|
||||||
plugins: [validationMessages],
|
plugins: [validationMessages],
|
||||||
rules: {
|
rules: {
|
||||||
globalRule
|
globalRule
|
||||||
@ -29,6 +30,7 @@ Vue.use(Formulario, {
|
|||||||
describe('FormularioInput', () => {
|
describe('FormularioInput', () => {
|
||||||
it('allows custom field-rule level validation strings', async () => {
|
it('allows custom field-rule level validation strings', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
validation: 'required|in:abcdef',
|
validation: 'required|in:abcdef',
|
||||||
@ -38,7 +40,7 @@ describe('FormularioInput', () => {
|
|||||||
},
|
},
|
||||||
scopedSlots: {
|
scopedSlots: {
|
||||||
default: `<div><span v-for="error in props.context.allErrors">{{ error.message }}</span></div>`
|
default: `<div><span v-for="error in props.context.allErrors">{{ error.message }}</span></div>`
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(wrapper.find('span').text()).toBe('the value was different than expected')
|
expect(wrapper.find('span').text()).toBe('the value was different than expected')
|
||||||
@ -62,6 +64,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('allows custom field-rule level validation functions', async () => {
|
it('allows custom field-rule level validation functions', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
validation: 'required|in:abcdef',
|
validation: 'required|in:abcdef',
|
||||||
@ -79,6 +82,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('uses custom async validation rules on defined on the field', async () => {
|
it('uses custom async validation rules on defined on the field', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
validation: 'required|foobar',
|
validation: 'required|foobar',
|
||||||
@ -101,6 +105,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('uses custom sync validation rules on defined on the field', async () => {
|
it('uses custom sync validation rules on defined on the field', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
validation: 'required|foobar',
|
validation: 'required|foobar',
|
||||||
@ -123,6 +128,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('uses global custom validation rules', async () => {
|
it('uses global custom validation rules', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
validation: 'required|globalRule',
|
validation: 'required|globalRule',
|
||||||
@ -135,13 +141,15 @@ describe('FormularioInput', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('emits correct validation event', async () => {
|
it('emits correct validation event', async () => {
|
||||||
const wrapper = mount(FormularioInput, { propsData: {
|
const wrapper = mount(FormularioInput, {
|
||||||
name: 'test',
|
localVue,
|
||||||
|
propsData: {
|
||||||
validation: 'required',
|
validation: 'required',
|
||||||
errorBehavior: 'live',
|
errorBehavior: 'live',
|
||||||
value: '',
|
value: '',
|
||||||
name: 'testinput',
|
name: 'testinput',
|
||||||
} })
|
}
|
||||||
|
})
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
const errorObject = wrapper.emitted('validation')[0][0]
|
const errorObject = wrapper.emitted('validation')[0][0]
|
||||||
expect(errorObject).toEqual({
|
expect(errorObject).toEqual({
|
||||||
@ -159,8 +167,8 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('emits a error-visibility event on blur', async () => {
|
it('emits a error-visibility event on blur', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
|
||||||
validation: 'required',
|
validation: 'required',
|
||||||
errorBehavior: 'blur',
|
errorBehavior: 'blur',
|
||||||
value: '',
|
value: '',
|
||||||
@ -178,21 +186,23 @@ describe('FormularioInput', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('emits error-visibility event immediately when live', async () => {
|
it('emits error-visibility event immediately when live', async () => {
|
||||||
const wrapper = mount(FormularioInput, { propsData: {
|
const wrapper = mount(FormularioInput, {
|
||||||
name: 'test',
|
localVue,
|
||||||
|
propsData: {
|
||||||
validation: 'required',
|
validation: 'required',
|
||||||
errorBehavior: 'live',
|
errorBehavior: 'live',
|
||||||
value: '',
|
value: '',
|
||||||
name: 'testinput',
|
name: 'testinput',
|
||||||
} })
|
}
|
||||||
|
})
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(wrapper.emitted('error-visibility').length).toBe(1)
|
expect(wrapper.emitted('error-visibility').length).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Does not emit an error-visibility event if visibility did not change', async () => {
|
it('Does not emit an error-visibility event if visibility did not change', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
name: 'test',
|
|
||||||
validation: 'in:xyz',
|
validation: 'in:xyz',
|
||||||
errorBehavior: 'live',
|
errorBehavior: 'live',
|
||||||
value: 'bar',
|
value: 'bar',
|
||||||
@ -211,6 +221,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('can bail on validation when encountering the bail rule', async () => {
|
it('can bail on validation when encountering the bail rule', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: { name: 'test', validation: 'bail|required|in:xyz', errorBehavior: 'live' }
|
propsData: { name: 'test', validation: 'bail|required|in:xyz', errorBehavior: 'live' }
|
||||||
})
|
})
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@ -219,6 +230,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('can show multiple validation errors if they occur before the bail rule', async () => {
|
it('can show multiple validation errors if they occur before the bail rule', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: { name: 'test', validation: 'required|in:xyz|bail', errorBehavior: 'live' }
|
propsData: { name: 'test', validation: 'required|in:xyz|bail', errorBehavior: 'live' }
|
||||||
})
|
})
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@ -227,6 +239,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('can avoid bail behavior by using modifier', async () => {
|
it('can avoid bail behavior by using modifier', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: { name: 'test', validation: '^required|in:xyz|min:10,length', errorBehavior: 'live', value: '123' }
|
propsData: { name: 'test', validation: '^required|in:xyz|min:10,length', errorBehavior: 'live', value: '123' }
|
||||||
})
|
})
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@ -235,6 +248,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('prevents later error messages when modified rule fails', async () => {
|
it('prevents later error messages when modified rule fails', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: { name: 'test', validation: '^required|in:xyz|min:10,length', errorBehavior: 'live' }
|
propsData: { name: 'test', validation: '^required|in:xyz|min:10,length', errorBehavior: 'live' }
|
||||||
})
|
})
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@ -243,6 +257,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('can bail in the middle of the rule set with a modifier', async () => {
|
it('can bail in the middle of the rule set with a modifier', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: { name: 'test', validation: 'required|^in:xyz|min:10,length', errorBehavior: 'live' }
|
propsData: { name: 'test', validation: 'required|^in:xyz|min:10,length', errorBehavior: 'live' }
|
||||||
})
|
})
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@ -251,6 +266,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('does not show errors on blur when set error-behavior is submit', async () => {
|
it('does not show errors on blur when set error-behavior is submit', async () => {
|
||||||
const wrapper = mount(FormularioInput, {
|
const wrapper = mount(FormularioInput, {
|
||||||
|
localVue,
|
||||||
propsData: {
|
propsData: {
|
||||||
validation: 'required',
|
validation: 'required',
|
||||||
errorBehavior: 'submit',
|
errorBehavior: 'submit',
|
||||||
@ -275,6 +291,7 @@ describe('FormularioInput', () => {
|
|||||||
|
|
||||||
it('displays errors when error-behavior is submit and form is submitted', async () => {
|
it('displays errors when error-behavior is submit and form is submitted', async () => {
|
||||||
const wrapper = mount(FormularioForm, {
|
const wrapper = mount(FormularioForm, {
|
||||||
|
localVue,
|
||||||
propsData: {name: 'test'},
|
propsData: {name: 'test'},
|
||||||
slots: {
|
slots: {
|
||||||
default: `
|
default: `
|
||||||
|
76
yarn.lock
76
yarn.lock
@ -1729,6 +1729,15 @@
|
|||||||
sass "^1.18.0"
|
sass "^1.18.0"
|
||||||
stylus "^0.54.5"
|
stylus "^0.54.5"
|
||||||
|
|
||||||
|
"@vue/eslint-config-standard@^5.1.2":
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/eslint-config-standard/-/eslint-config-standard-5.1.2.tgz#c5d55af894a3ae23b65b1af4a425777ac0170b42"
|
||||||
|
integrity sha512-FTz0k77dIrj9r3xskt9jsZyL/YprrLiPRf4m3k7G6dZ5PKuD6OPqYrHR9eduUmHDFpTlRgFpTVQrq+1el9k3QQ==
|
||||||
|
dependencies:
|
||||||
|
eslint-config-standard "^14.1.0"
|
||||||
|
eslint-import-resolver-node "^0.3.3"
|
||||||
|
eslint-import-resolver-webpack "^0.12.1"
|
||||||
|
|
||||||
"@vue/preload-webpack-plugin@^1.1.0":
|
"@vue/preload-webpack-plugin@^1.1.0":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.1.tgz#18723530d304f443021da2292d6ec9502826104a"
|
resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.1.tgz#18723530d304f443021da2292d6ec9502826104a"
|
||||||
@ -2158,6 +2167,11 @@ array-equal@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
|
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
|
||||||
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
|
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
|
||||||
|
|
||||||
|
array-find@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8"
|
||||||
|
integrity sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=
|
||||||
|
|
||||||
array-flatten@1.1.1:
|
array-flatten@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||||
@ -4186,6 +4200,15 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
once "^1.4.0"
|
once "^1.4.0"
|
||||||
|
|
||||||
|
enhanced-resolve@^0.9.1:
|
||||||
|
version "0.9.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e"
|
||||||
|
integrity sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=
|
||||||
|
dependencies:
|
||||||
|
graceful-fs "^4.1.2"
|
||||||
|
memory-fs "^0.2.0"
|
||||||
|
tapable "^0.1.8"
|
||||||
|
|
||||||
enhanced-resolve@^4.1.0:
|
enhanced-resolve@^4.1.0:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66"
|
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66"
|
||||||
@ -4279,6 +4302,11 @@ eslint-config-standard@^12.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9"
|
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9"
|
||||||
integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==
|
integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==
|
||||||
|
|
||||||
|
eslint-config-standard@^14.1.0:
|
||||||
|
version "14.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea"
|
||||||
|
integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==
|
||||||
|
|
||||||
eslint-import-resolver-node@^0.3.2:
|
eslint-import-resolver-node@^0.3.2:
|
||||||
version "0.3.3"
|
version "0.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404"
|
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404"
|
||||||
@ -4287,6 +4315,30 @@ eslint-import-resolver-node@^0.3.2:
|
|||||||
debug "^2.6.9"
|
debug "^2.6.9"
|
||||||
resolve "^1.13.1"
|
resolve "^1.13.1"
|
||||||
|
|
||||||
|
eslint-import-resolver-node@^0.3.3:
|
||||||
|
version "0.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717"
|
||||||
|
integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==
|
||||||
|
dependencies:
|
||||||
|
debug "^2.6.9"
|
||||||
|
resolve "^1.13.1"
|
||||||
|
|
||||||
|
eslint-import-resolver-webpack@^0.12.1:
|
||||||
|
version "0.12.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.2.tgz#769e86cd0c752a1536c19855ebd90aa14ce384ee"
|
||||||
|
integrity sha512-7Jnm4YAoNNkvqPaZkKdIHsKGmv8/uNnYC5QsXkiSodvX4XEEfH2AKOna98FK52fCDXm3q4HzuX+7pRMKkJ64EQ==
|
||||||
|
dependencies:
|
||||||
|
array-find "^1.0.0"
|
||||||
|
debug "^2.6.9"
|
||||||
|
enhanced-resolve "^0.9.1"
|
||||||
|
find-root "^1.1.0"
|
||||||
|
has "^1.0.3"
|
||||||
|
interpret "^1.2.0"
|
||||||
|
lodash "^4.17.15"
|
||||||
|
node-libs-browser "^1.0.0 || ^2.0.0"
|
||||||
|
resolve "^1.13.1"
|
||||||
|
semver "^5.7.1"
|
||||||
|
|
||||||
eslint-loader@^2.2.1:
|
eslint-loader@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337"
|
resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337"
|
||||||
@ -4881,6 +4933,11 @@ find-cache-dir@^3.0.0, find-cache-dir@^3.3.1:
|
|||||||
make-dir "^3.0.2"
|
make-dir "^3.0.2"
|
||||||
pkg-dir "^4.1.0"
|
pkg-dir "^4.1.0"
|
||||||
|
|
||||||
|
find-root@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
|
||||||
|
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
|
||||||
|
|
||||||
find-up@^1.0.0:
|
find-up@^1.0.0:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
|
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
|
||||||
@ -5691,6 +5748,11 @@ internal-ip@^4.3.0:
|
|||||||
default-gateway "^4.2.0"
|
default-gateway "^4.2.0"
|
||||||
ipaddr.js "^1.9.0"
|
ipaddr.js "^1.9.0"
|
||||||
|
|
||||||
|
interpret@^1.2.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
|
||||||
|
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
|
||||||
|
|
||||||
invariant@^2.2.2, invariant@^2.2.4:
|
invariant@^2.2.2, invariant@^2.2.4:
|
||||||
version "2.2.4"
|
version "2.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||||
@ -7006,6 +7068,11 @@ media-typer@0.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||||
|
|
||||||
|
memory-fs@^0.2.0:
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290"
|
||||||
|
integrity sha1-8rslNovBIeORwlIN6Slpyu4KApA=
|
||||||
|
|
||||||
memory-fs@^0.4.1:
|
memory-fs@^0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
||||||
@ -7357,7 +7424,7 @@ node-ipc@^9.1.1:
|
|||||||
js-message "1.0.5"
|
js-message "1.0.5"
|
||||||
js-queue "2.0.0"
|
js-queue "2.0.0"
|
||||||
|
|
||||||
node-libs-browser@^2.2.1:
|
"node-libs-browser@^1.0.0 || ^2.0.0", node-libs-browser@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
||||||
integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
|
integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
|
||||||
@ -9361,7 +9428,7 @@ selfsigned@^1.10.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
node-forge "0.9.0"
|
node-forge "0.9.0"
|
||||||
|
|
||||||
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
|
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1:
|
||||||
version "5.7.1"
|
version "5.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||||
@ -10064,6 +10131,11 @@ table@^5.2.3:
|
|||||||
slice-ansi "^2.1.0"
|
slice-ansi "^2.1.0"
|
||||||
string-width "^3.0.0"
|
string-width "^3.0.0"
|
||||||
|
|
||||||
|
tapable@^0.1.8:
|
||||||
|
version "0.1.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4"
|
||||||
|
integrity sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=
|
||||||
|
|
||||||
tapable@^1.0.0, tapable@^1.1.3:
|
tapable@^1.0.0, tapable@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||||
|
Loading…
Reference in New Issue
Block a user