UNPKG

vue-dog-form

Version:

The simplest vue 3 form validation plugin.

336 lines (335 loc) 9.93 kB
import { defineComponent as z, provide as _, inject as h, ref as E, onBeforeMount as M, watch as b, openBlock as A, createElementBlock as w, withModifiers as k, renderSlot as R, onMounted as q, useAttrs as B, onBeforeUnmount as F, normalizeClass as S, toDisplayString as D, createCommentVNode as L } from "vue"; const C = { required: { rule(t, e) { if (t == null || t == null) return { type: "required" }; if (Array.isArray(t) || typeof t == "string" || t instanceof FileList) { if (t.length < 1) return { type: "required" }; } else if (typeof t == "number" && isNaN(t)) return { type: "required" }; }, message: "This field is required." }, minlength: { rule(t, e) { if (t.length < parseInt(e)) return { type: "minlength", value: { n: e } }; }, message: "Input must be at least {n} characters." }, maxlength: { rule(t, e) { if (t.length > parseInt(e)) return { type: "maxlength", value: { n: e } }; }, message: "Input cannot be more than {n} characters." }, equalto: { rule(t, e) { if (t != e) return { type: "equalto" }; }, message: "Input value does not match.", auto: !0 }, notequalto: { rule(t, e) { if (t == e) return { type: "notequalto" }; }, message: "Input value cannot be the same.", auto: !0 }, validemail: { rule(t, e) { const a = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/; if (!t.match(a)) return { type: "validemail" }; }, message: "Please enter a valid email." }, min: { rule(t, e) { if (t < parseFloat(e)) return { type: "min", value: { n: e } }; }, message: "Minimum value is {n}." }, max: { rule(t, e) { if (t > parseFloat(e)) return { type: "max", value: { n: e } }; }, message: "Maximum value is {n}." }, accept: { rule(t, e) { const a = e.trim().split(","); let r = [], f = []; a.forEach((l, i) => { if (l.indexOf("/") > -1) r.push(l); else { let u = l.match(/\.\w{1,}$/); u && u[0] && f.push(u[0]); } }); let n = []; const m = t; for (let l = 0; l < m.length; l++) { let i = !1, u = !1, g = m[l].name.match(/\.\w{1,}$/)[0], y = m[l].type.substr(0, m[l].type.indexOf("/")); for (let v = 0; v < r.length; v++) if (r[v].indexOf(y) > -1) { if (r[v].indexOf("/*") > -1) { i = !0; break; } else if (r[v].indexOf(m[l].type) > -1) { i = !0; break; } } i || f.indexOf(g) > -1 && (u = !0), !i && !u && n.push(l); } if (n.length > 0) return { invalidFiles: n, type: "accept" }; }, message: "File(s) extension is not accepted." }, maxfile: { rule(t, e) { if (t.length > parseInt(e)) return { type: "maxfile", value: { n: e } }; }, message: "Please select not more than {n} files." }, maxsize: { rule(t, e) { let a = []; for (let r = 0; r < t.length; r++) t[r].size > parseInt(e) && a.push(r); if (a.length > 0) { const r = parseInt(e) / 1024 / 1024; return { isValid: !1, invalidFiles: a, type: "maxsize", value: { n: r.toString() } }; } }, message: "File(s) must less than {n}Mb." } }, V = Symbol(), I = Symbol(), O = Symbol(), N = ["novalidate"], j = /* @__PURE__ */ z({ inheritAttrs: !1, __name: "DForm", props: { nativeValidate: { type: Boolean, default: void 0 }, focusError: { type: Boolean, default: !1 }, focusOffset: { default: 0 }, activate: {} }, emits: ["submit"], setup(t, { expose: e, emit: a }) { const r = t, f = a; let n = []; _(I, n); const m = () => { n.forEach((s) => { s.clear(); }); }, l = h(V), i = E(!0); _(O, i); const u = () => { let s = typeof r.activate == "string" ? r.activate : (l == null ? void 0 : l.activate) || "always"; !s || s == "first_submit" || s == "only_submit" || s == "never" ? (i.value = !1, m()) : i.value = !0; }; M(() => { u(); }), b(() => r.activate, () => { u(); }); const g = E(!1), y = () => { if (typeof r.nativeValidate == "boolean") { g.value = r.nativeValidate; return; } else typeof (l == null ? void 0 : l.nativeValidate) == "boolean" ? g.value = l.nativeValidate : g.value = !1; }; M(() => { y(); }), b(() => r.nativeValidate, () => { y(); }); const v = (s) => { if (!i.value) { if (r.activate == "never") { s.isValid = !0, f("submit", s); return; } i.value = !0; } let o = 0, c = null; if (n.forEach((p) => { let x = p.validate(); x != null && x.type && (o++, !c && x.errorElements && x.errorElements.length > 0 && (c = x.errorElements[0])); }), s.isValid = o < 1, r.focusError && c) { const p = c.getBoundingClientRect().top, x = r.focusOffset || 0; window.scrollTo({ top: p + window.scrollY - x, behavior: "smooth" }); } f("submit", s), r.activate == "only_submit" && (i.value = !1); }; return e({ clearErrors: m, hasError: () => { let s = !1; for (let o = 0; o < n.length; o++) if (n[o].errorMessage.value) { s = !0; break; } return s; } }), (s, o) => (A(), w("form", { onSubmit: k(v, ["prevent"]), class: "_dog-form", novalidate: !g.value }, [ R(s.$slots, "default") ], 40, N)); } }), K = /* @__PURE__ */ z({ __name: "DError", props: { modelValue: {}, messages: {}, target: {} }, setup(t, { expose: e }) { const a = t, r = Math.random().toString(), f = h(I); q(() => { f == null || f.push({ id: r, validate: y, clear: v, errorMessage: i }); }); const n = B(), m = () => a.modelValue == null || a.modelValue == null ? !1 : !((typeof a.modelValue == "string" || Array.isArray(a.modelValue)) && a.modelValue.length == 0), l = () => !(!("required" in n) || typeof n.required == "boolean" && !n.required), i = E(""), u = h(V), g = h(O), y = (d) => { if (!d && (!g || !g.value)) return; i.value = ""; let s = []; if (a.target && (s = document.querySelectorAll(a.target), s.forEach((c) => c.classList.remove("invalid", "valid"))), !m() && !l()) return; let o = {}; for (let c in n) { let p = n[c]; if (u != null && u.validationRules[c] && (o = u.validationRules[c].rule(a.modelValue, p), o && o.type)) { a.messages && typeof a.messages[o.type] == "string" ? i.value = a.messages[o.type] : i.value = u.message(o); break; } } return o && o.type ? (s.forEach((c) => c.classList.add("invalid")), o.errorElements = s) : s.forEach((c) => c.classList.add("valid")), o; }; b(() => a.modelValue, () => { y(); }), q(() => { u != null && u.validationRules && Object.keys(n).forEach((d) => { var s; (s = u.validationRules[d]) != null && s.auto && b(() => n[d], () => { y(); }); }); }); const v = () => { i.value = "", a.target && document.querySelectorAll(a.target).forEach((s) => s.classList.remove("invalid", "valid")); }; return F(() => { v(); const d = f == null ? void 0 : f.findIndex((s) => s.id == r); typeof d == "number" && d >= 0 && (f == null || f.splice(d, 1)); }), e({ errorMsg: i, validate: y, clear: v }), (d, s) => i.value ? (A(), w("div", { key: 0, class: S(["_df_ErrMsg", d.$props.class]) }, D(i.value), 3)) : L("", !0); } }), T = { install: (t, e) => { t.component("DForm", j), t.component("DError", K); let a = C; e != null && e.customRules && (a = { ...a, ...e.customRules }), typeof (e == null ? void 0 : e.defaultMessages) == "object" && Object.keys(e == null ? void 0 : e.defaultMessages).forEach((l) => { var i; a[l] && ((i = e.defaultMessages) != null && i[l]) && (a[l].message = e.defaultMessages[l]); }); const r = (l) => { var i; return ((i = l.value) != null && i.n ? a[l.type].message.replace(/{n}/g, l.value.n) : a[l.type].message) || l.type; }; let f = "always"; typeof (e == null ? void 0 : e.activate) == "string" && ["always", "first_submit", "only_submit", "never"].indexOf(e.activate) > -1 && (f = e.activate); let n = !1; typeof (e == null ? void 0 : e.nativeValidate) == "boolean" && (n = e.nativeValidate); const m = { message: typeof (e == null ? void 0 : e.message) == "function" ? e.message : r, validationRules: a, activate: f, nativeValidate: n }; t.provide(V, m); } }; export { K as DError, j as DForm, T as default };