UNPKG

quasar

Version:

Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time

212 lines (177 loc) 4.59 kB
import { testPattern } from '../utils/patterns.js' const lazyRulesValues = [ true, false, 'ondemand' ] export default { props: { value: {}, error: { type: Boolean, default: null }, errorMessage: String, noErrorIcon: Boolean, rules: Array, reactiveRules: Boolean, lazyRules: { type: [ Boolean, String ], validator: v => lazyRulesValues.includes(v) } }, data () { return { isDirty: null, innerError: false, innerErrorMessage: void 0 } }, watch: { value () { this.__validateIfNeeded() }, disable (val) { val === true && this.resetValidation() }, reactiveRules: { handler (val) { if (val === true) { if (this.unwatchRules === void 0) { this.unwatchRules = this.$watch('rules', () => { this.__validateIfNeeded(true) }) } } else if (this.unwatchRules !== void 0) { this.unwatchRules() this.unwatchRules = void 0 } }, immediate: true }, focused (focused) { if (this.lazyRules !== 'ondemand') { if (focused === true) { if (this.isDirty === null) { this.isDirty = false } } else if (this.isDirty === false && this.hasRules === true) { this.isDirty = true this.validate() } } } }, computed: { hasRules () { return this.rules !== void 0 && this.rules !== null && this.rules.length > 0 }, hasError () { return this.error === true || this.innerError === true }, computedErrorMessage () { return typeof this.errorMessage === 'string' && this.errorMessage.length > 0 ? this.errorMessage : this.innerErrorMessage } }, mounted () { this.validateIndex = 0 }, beforeDestroy () { this.unwatchRules !== void 0 && this.unwatchRules() }, methods: { resetValidation () { this.validateIndex++ this.innerLoading = false this.isDirty = null this.innerError = false this.innerErrorMessage = void 0 }, /* * Return value * - true (validation succeeded) * - false (validation failed) * - Promise (pending async validation) */ validate (val = this.value) { if (this.hasRules !== true) { return true } this.validateIndex++ if (this.innerLoading !== true && this.lazyRules !== true) { this.isDirty = true } const update = (err, msg) => { if (this.innerError !== err) { this.innerError = err } const m = msg || void 0 if (this.innerErrorMessage !== m) { this.innerErrorMessage = m } if (this.innerLoading !== false) { this.innerLoading = false } } const promises = [] for (let i = 0; i < this.rules.length; i++) { const rule = this.rules[i] let res if (typeof rule === 'function') { res = rule(val) } else if (typeof rule === 'string' && testPattern[rule] !== void 0) { res = testPattern[rule](val) } if (res === false || typeof res === 'string') { update(true, res) return false } else if (res !== true && res !== void 0) { promises.push(res) } } if (promises.length === 0) { update(false) return true } if (this.innerLoading !== true) { this.innerLoading = true } const index = this.validateIndex return Promise.all(promises).then( res => { if (index !== this.validateIndex) { return true } if (res === void 0 || Array.isArray(res) === false || res.length === 0) { update(false) return true } const msg = res.find(r => r === false || typeof r === 'string') update(msg !== void 0, msg) return msg === void 0 }, e => { if (index === this.validateIndex) { console.error(e) update(true) return false } return true } ) }, __validateIfNeeded (changedRules) { if ( this.hasRules === true && this.lazyRules !== 'ondemand' && (this.isDirty === true || (this.lazyRules !== true && changedRules !== true)) ) { this.validate() } } } }