121 lines
2.7 KiB
JavaScript
121 lines
2.7 KiB
JavaScript
|
// Mixins
|
||
|
import { provide as RegistrableProvide } from '../../mixins/registrable';
|
||
|
/* @vue/component */
|
||
|
|
||
|
export default RegistrableProvide('form').extend({
|
||
|
name: 'v-form',
|
||
|
inheritAttrs: false,
|
||
|
props: {
|
||
|
value: Boolean,
|
||
|
lazyValidation: Boolean
|
||
|
},
|
||
|
data: () => ({
|
||
|
inputs: [],
|
||
|
watchers: [],
|
||
|
errorBag: {}
|
||
|
}),
|
||
|
watch: {
|
||
|
errorBag: {
|
||
|
handler(val) {
|
||
|
const errors = Object.values(val).includes(true);
|
||
|
this.$emit('input', !errors);
|
||
|
},
|
||
|
|
||
|
deep: true,
|
||
|
immediate: true
|
||
|
}
|
||
|
},
|
||
|
methods: {
|
||
|
watchInput(input) {
|
||
|
const watcher = input => {
|
||
|
return input.$watch('hasError', val => {
|
||
|
this.$set(this.errorBag, input._uid, val);
|
||
|
}, {
|
||
|
immediate: true
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const watchers = {
|
||
|
_uid: input._uid,
|
||
|
valid: () => {},
|
||
|
shouldValidate: () => {}
|
||
|
};
|
||
|
|
||
|
if (this.lazyValidation) {
|
||
|
// Only start watching inputs if we need to
|
||
|
watchers.shouldValidate = input.$watch('shouldValidate', val => {
|
||
|
if (!val) return; // Only watch if we're not already doing it
|
||
|
|
||
|
if (this.errorBag.hasOwnProperty(input._uid)) return;
|
||
|
watchers.valid = watcher(input);
|
||
|
});
|
||
|
} else {
|
||
|
watchers.valid = watcher(input);
|
||
|
}
|
||
|
|
||
|
return watchers;
|
||
|
},
|
||
|
|
||
|
/** @public */
|
||
|
validate() {
|
||
|
return this.inputs.every(input => input.validate(true));
|
||
|
},
|
||
|
|
||
|
/** @public */
|
||
|
reset() {
|
||
|
this.inputs.forEach(input => input.reset());
|
||
|
this.resetErrorBag();
|
||
|
},
|
||
|
|
||
|
resetErrorBag() {
|
||
|
if (this.lazyValidation) {
|
||
|
// Account for timeout in validatable
|
||
|
setTimeout(() => {
|
||
|
this.errorBag = {};
|
||
|
}, 0);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/** @public */
|
||
|
resetValidation() {
|
||
|
this.inputs.forEach(input => input.resetValidation());
|
||
|
this.resetErrorBag();
|
||
|
},
|
||
|
|
||
|
register(input) {
|
||
|
this.inputs.push(input);
|
||
|
this.watchers.push(this.watchInput(input));
|
||
|
},
|
||
|
|
||
|
unregister(input) {
|
||
|
const found = this.inputs.find(i => i._uid === input._uid);
|
||
|
if (!found) return;
|
||
|
const unwatch = this.watchers.find(i => i._uid === found._uid);
|
||
|
|
||
|
if (unwatch) {
|
||
|
unwatch.valid();
|
||
|
unwatch.shouldValidate();
|
||
|
}
|
||
|
|
||
|
this.watchers = this.watchers.filter(i => i._uid !== found._uid);
|
||
|
this.inputs = this.inputs.filter(i => i._uid !== found._uid);
|
||
|
this.$delete(this.errorBag, found._uid);
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
render(h) {
|
||
|
return h('form', {
|
||
|
staticClass: 'v-form',
|
||
|
attrs: {
|
||
|
novalidate: true,
|
||
|
...this.$attrs
|
||
|
},
|
||
|
on: {
|
||
|
submit: e => this.$emit('submit', e)
|
||
|
}
|
||
|
}, this.$slots.default);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
//# sourceMappingURL=VForm.js.map
|