UNPKG

vuetify

Version:

Vue.js 2 Semantic Component Framework

128 lines (111 loc) 3.06 kB
import { consoleError } from '../util/console' export default { name: 'validatable', data () { return { errorBucket: [], hasFocused: false, hasInput: false, shouldValidate: false, valid: false } }, props: { error: { type: Boolean }, errorMessages: { type: [String, Array], default: () => [] }, rules: { type: Array, default: () => [] }, validateOnBlur: Boolean }, computed: { validations () { if (!Array.isArray(this.errorMessages)) { return [this.errorMessages] } else if (this.errorMessages.length > 0) { return this.errorMessages } else if (this.shouldValidate) { return this.errorBucket } else { return [] } }, hasError () { return this.validations.length > 0 || this.errorMessages.length > 0 || this.error } }, watch: { rules: { handler (newVal, oldVal) { // TODO: This handler seems to trigger when input changes, even though // rules array stays the same? Solved it like this for now if (newVal.length === oldVal.length) return this.validate() }, deep: true }, inputValue (val) { // If it's the first time we're setting input, // mark it with hasInput if (!!val && !this.hasInput) this.hasInput = true if (this.hasInput && !this.validateOnBlur) this.shouldValidate = true }, isFocused (val) { // If we're not focused, and it's the first time // we're defocusing, set shouldValidate to true if (!val && !this.hasFocused) { this.hasFocused = true this.shouldValidate = true this.$emit('update:error', this.errorBucket.length > 0) } }, hasError (val) { if (this.shouldValidate) { this.$emit('update:error', val) } }, error (val) { this.shouldValidate = !!val } }, mounted () { this.shouldValidate = !!this.error this.validate() }, methods: { reset () { // TODO: Do this another way! // This is so that we can reset all types of inputs this.$emit('input', this.isMultiple ? [] : null) this.$emit('change', null) this.$nextTick(() => { this.shouldValidate = false this.hasFocused = false this.validate() }) }, validate (force = false, value = this.inputValue) { if (force) this.shouldValidate = true this.errorBucket = [] for (let index = 0; index < this.rules.length; index++) { const rule = this.rules[index] const valid = typeof rule === 'function' ? rule(value) : rule if (valid === false || typeof valid === 'string') { this.errorBucket.push(valid) } else if (valid !== true) { consoleError(`Rules should return a string or boolean, received '${typeof valid}' instead`, this) } } this.valid = this.errorBucket.length === 0 return this.valid } } }