@jdlien/validator 1.4.8 → 1.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/Validator.d.ts +3 -0
- package/dist/validator.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,7 +164,11 @@ function customValidationPromise(value) {
|
|
|
164
164
|
|
|
165
165
|
## Displaying Error Messages
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
If any form validation fails on submission, Validator displays a main error message near the top of the form. By default, it looks for an element with the ID `form-error-main`. However, if the form itself has an `id` attribute (e.g., `<form id="contact-form">`), Validator will first look for a main error element with the ID `{form.id}-error-main` (e.g., `contact-form-error-main`). If that form-specific element is not found, it falls back to looking for `form-error-main`.
|
|
168
|
+
|
|
169
|
+
This allows for more targeted styling and placement of the main error message per form. You can disable the display of this main error message entirely by setting the `showMainError` option to `false`.
|
|
170
|
+
|
|
171
|
+
For individual input errors, it is recommended to create an error message element (likely a div) with a unique id and then use its id in an `aria-describedby` attribute in each associated input. This will ensure that Validator knows exactly what error element is associated with each input, and this works seamlessly for groups of inputs, like radio buttons. This will also confer improved accessibility and allow screen readers to announce the error message when the input is focused.
|
|
168
172
|
|
|
169
173
|
If you do not use `aria-describedby`, Validator will fall back to displaying error messages in the first element having the id or name of the input + `-error`. For example, if the input id is `inputid`, the error message will be displayed in the div with the id `inputid-error`.
|
|
170
174
|
|
|
@@ -229,6 +233,7 @@ messages = {
|
|
|
229
233
|
- `hiddenClasses` - A string containing one or more space-separated classes to toggle the hidden mode (e.g., `display: none` CSS property) on hidden elements. Defaults to `hidden opacity-0`.
|
|
230
234
|
- `errorMainClasses` - A string containing one or more space-separated classes to apply to the main error message.
|
|
231
235
|
- `errorInputClasses` - A string containing one or more space-separated classes to apply to invalid `inputs.
|
|
236
|
+
- `showMainError` - A boolean indicating whether or not to show the main error message. Defaults to `true`.
|
|
232
237
|
- `validationSuccessCallback` - A function to be called when validation is successful.
|
|
233
238
|
- `validationErrorCallback` - A function to be called when validation fails.
|
|
234
239
|
|
package/dist/Validator.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface ValidatorOptions {
|
|
|
8
8
|
hiddenClasses?: string;
|
|
9
9
|
errorMainClasses?: string;
|
|
10
10
|
errorInputClasses?: string;
|
|
11
|
+
showMainError?: boolean;
|
|
11
12
|
validationSuccessCallback?: (event: Event) => void;
|
|
12
13
|
validationErrorCallback?: (event: Event) => void;
|
|
13
14
|
}
|
|
@@ -61,6 +62,7 @@ export default class Validator {
|
|
|
61
62
|
autoInit: boolean;
|
|
62
63
|
preventSubmit: boolean;
|
|
63
64
|
hiddenClasses: string;
|
|
65
|
+
showMainError: boolean;
|
|
64
66
|
errorMainClasses: string;
|
|
65
67
|
errorInputClasses: string;
|
|
66
68
|
private dispatchTimeout;
|
|
@@ -80,6 +82,7 @@ export default class Validator {
|
|
|
80
82
|
init(): void;
|
|
81
83
|
private getErrorEl;
|
|
82
84
|
private addErrorMain;
|
|
85
|
+
private _getMainErrorElement;
|
|
83
86
|
private addInputError;
|
|
84
87
|
private showInputErrors;
|
|
85
88
|
private showFormErrors;
|
package/dist/validator.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(E,v){typeof exports=="object"&&typeof module<"u"?module.exports=v():typeof define=="function"&&define.amd?define(v):(E=typeof globalThis<"u"?globalThis:E||self,E.Validator=v())})(this,function(){"use strict";var ue=Object.defineProperty;var ce=(E,v,T)=>v in E?ue(E,v,{enumerable:!0,configurable:!0,writable:!0,value:T}):E[v]=T;var f=(E,v,T)=>ce(E,typeof v!="symbol"?v+"":v,T);var E={exports:{}},v=E.exports,T;function x(){return T||(T=1,function(S,t){(function(r,n){n(t)})(v,function(r){function n(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function l(e,a){typeof a=="string"&&(a=[a]);const s=e.dataset.type||"",i=e.type;return!!(a.includes(s)||a.includes(i))}function p(e){return e.replace(/YYYY/g,"Y").replace(/YY/g,"y").replace(/MMMM/g,"F").replace(/MMM/g,"{3}").replace(/MM/g,"{2}").replace(/M/g,"n").replace(/DD/g,"{5}").replace(/D/g,"j").replace(/dddd/g,"l").replace(/ddd/g,"D").replace(/dd/g,"D").replace(/d/g,"w").replace(/HH/g,"{6}").replace(/H/g,"G").replace(/hh/g,"h").replace(/mm/g,"i").replace(/m/g,"i").replace(/ss/g,"S").replace(/s/g,"s").replace(/A/gi,"K").replace(/\{3\}/g,"M").replace(/\{2\}/g,"m").replace(/\{5\}/g,"d").replace(/\{6\}/g,"H")}function y(e){const a=parseInt(e);if(typeof e=="number"||!isNaN(a))return a-1;const s=new Date(`1 ${e} 2000`).getMonth();if(!isNaN(s))return s;const i={ja:0,en:0,fe:1,fé:1,ap:3,ab:3,av:3,mai:4,juin:5,juil:6,au:7,ag:7,ao:7,se:8,o:9,n:10,d:11};for(const h in i)if(e.toLowerCase().startsWith(h))return i[h];throw new Error("Invalid month name: "+e)}function b(e){return typeof e=="string"&&(e=parseInt(e.replace(/\D/g,""))),e>99?e:e<(new Date().getFullYear()+20)%100?e+2e3:e+1900}function w(e){if(e instanceof Date)return e;e=e.trim().toLowerCase();let a=0,s=0,i=0,h=0,d=0,u=0;const m=new RegExp(/\d{1,2}\:\d\d(?:\:\d\ds?)?\s?(?:[a|p]m?)?/gi);if(m.test(e)){const R=e.match(m)[0];e=e.replace(R,"").trim();const I=M(R);if(I!==null&&({hour:h,minute:d,second:u}=I),e.length<=2){const N=new Date;return new Date(N.getFullYear(),N.getMonth(),N.getDate(),h,d,u)}}const g=/(^|\b)(mo|tu|we|th|fr|sa|su|lu|mard|mer|jeu|ve|dom)[\w]*\.?/gi;e=e.replace(g,"").trim();const c=new Date(new Date().setHours(0,0,0,0));if(/(now|today)/.test(e))return c;if(e.includes("tomorrow"))return new Date(c.setDate(c.getDate()+1));e.length===8&&(e=e.replace(/(\d\d\d\d)(\d\d)(\d\d)/,"$1-$2-$3")),e.length===6&&(e=e.replace(/(\d\d)(\d\d)(\d\d)/,b(e.slice(0,2))+"-$2-$3"));try{({year:a,month:s,day:i}=U(e))}catch{return new Date("")}return new Date(a,s-1,i,h,d,u)}function Y(e,a=[null,null,null]){const s=i=>i.filter(h=>!a.includes(h));return e===0||e>31?s(["y"]):e>12?s(["d","y"]):e>=1&&e<=12?s(["m","d","y"]):[]}function U(e){const a=e.split(/[\s-/:.,]+/).filter(d=>d!=="");if(a.length<3){if(e.match(/\d{4}/)!==null)throw new Error("Invalid Date");a.unshift(String(new Date().getFullYear()))}const s={year:0,month:0,day:0};function i(d,u){d==="year"?s.year=b(u):s[d]=u}let h=0;for(;!(s.year&&s.month&&s.day);){e:for(const d of a){if(h++,/^[a-zA-Zé]+$/.test(d)){s.month||i("month",y(d)+1);continue}if(/^'\d\d$/.test(d)||/^\d{3,5}$/.test(d)){s.year||i("year",parseInt(d.replace(/'/,"")));continue}const u=parseInt(d);if(isNaN(u))throw console.error(`not date because ${d} isNaN`),new Error("Invalid Date");const m=Y(u,[s.year?"y":null,s.month?"m":null,s.day?"d":null]);if(m.length==1){if(m[0]==="m"&&!s.month){i("month",u);continue e}if(m[0]==="d"&&!s.day){i("day",u);continue e}if(m[0]==="y"&&!s.year){i("year",u);continue e}}h>3&&(!s.month&&m.includes("m")?i("month",u):!s.day&&m.includes("d")&&i("day",u))}if(h>6)throw new Error("Invalid Date")}if(s.year&&s.month&&s.day)return s;throw new Error("Invalid Date")}function M(e){if(e=e.trim().toLowerCase(),e==="now"){const c=new Date;return{hour:c.getHours(),minute:c.getMinutes(),second:c.getSeconds()}}if(e==="noon")return{hour:12,minute:0,second:0};const a=e.match(/(\d{3,4})/);if(a){const c=a[1].length,R=a[1].slice(0,c==3?1:2),I=a[1].slice(-2);e=e.replace(a[1],R+":"+I)}const s=new RegExp(/^(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)\.?m?\.?)?$/i);if(s.test(e)){const c=e.match(s);if(c===null)return null;e=c[1]+":"+(c[2]||"00")+(c[3]||"")}const i=new RegExp(/^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(!i.test(e))return null;const h=e.match(i);if(h===null)return null;const d=parseInt(h[1]),u=parseInt(h[2]),m=h[3]?parseInt(h[3]):0,g=h[4];return isNaN(d)||isNaN(u)||isNaN(m)?null:g==="p"&&d<12?{hour:d+12,minute:u,second:m}:g==="a"&&d===12?{hour:0,minute:u,second:m}:d<0||d>23||u<0||u>59||m<0||m>59?null:{hour:d,minute:u,second:m}}function P(e,a="h:mm A"){const s=M(e);if(s){const i=new Date;return i.setHours(s.hour),i.setMinutes(s.minute),i.setSeconds(s.second),i.setMilliseconds(0),D(i,a)}return""}function A(e){if(e instanceof Date)return e;if(e.trim().length<3)return null;e=e.replace(/(\d)T(\d)/,"$1 $2");let a=e.split(/[\s,]+/).filter(g=>g!==""),s="",i="",h="";a.forEach((g,c)=>{const R=g.match(/^(\d{1,4})([apAP]\.?[mM]?\.?)/);R?i=R[0]:(g.includes(":")||g==="now"||g==="noon")&&(i=g),O(g)&&(h=g,!i&&c>0&&k(a[c-1])&&(i=a[c-1]))}),i?a=a.filter(g=>g!==i&&g!==h):[s,a]=F(a);const d=i?`${i} ${h}`:s?a.join(" "):"",u=M(d)||{hour:0,minute:0,second:0},m=w(s||a.join(" ").trim()||"today");return!m||isNaN(m.getTime())?null:new Date(m.getFullYear(),m.getMonth(),m.getDate(),u.hour,u.minute,u.second)}function F(e){for(let a=3;a>0;a--){const s=e.slice(0,a).join(" ");if(H(s))return[s,e.slice(a)]}return["",e]}function D(e,a="YYYY-MM-DD"){if(e=w(e),isNaN(e.getTime()))return"";const s={y:e.getFullYear(),M:e.getMonth(),D:e.getDate(),W:e.getDay(),H:e.getHours(),m:e.getMinutes(),s:e.getSeconds(),ms:e.getMilliseconds()},i=(c,R=2)=>(c+"").padStart(R,"0"),h=()=>s.H%12||12,d=c=>c<12?"AM":"PM",u=c=>"January|February|March|April|May|June|July|August|September|October|November|December".split("|")[c];function m(c,R=0){const I="Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|");return R?I[c].slice(0,R):I[c]}const g={YY:String(s.y).slice(-2),YYYY:s.y,M:s.M+1,MM:i(s.M+1),MMMM:u(s.M),MMM:u(s.M).slice(0,3),D:String(s.D),DD:i(s.D),d:String(s.W),dd:m(s.W,2),ddd:m(s.W,3),dddd:m(s.W),H:String(s.H),HH:i(s.H),h:h(),hh:i(h()),A:d(s.H),a:d(s.H).toLowerCase(),m:String(s.m),mm:i(s.m),s:String(s.s),ss:i(s.s),SSS:i(s.ms,3)};return a.replace(/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,(c,R)=>R||g[c])}function q(e,a){const s=w(e);return isNaN(s.getTime())?"":((!a||a.length===0)&&(a="YYYY-MMM-DD"),D(s,a))}function Z(e,a){const s=A(e);return s===null||isNaN(s.getTime())?"":((!a||a.length===0)&&(a="YYYY-MMM-DD h:mm A"),D(s,a))}function H(e){if(typeof e!="string"&&!(e instanceof Date))return!1;let a=w(e);return a==null?!1:!isNaN(a.getTime())}function z(e){if(typeof e!="string"&&!(e instanceof Date))return!1;let a=A(e);return a==null?!1:!isNaN(a.getTime())}function j(e,a){return!(a==="past"&&e>new Date||a==="future"&&e.getTime()<new Date().setHours(0,0,0,0))}function O(e){const a=e.toLowerCase().replace(/[.\s]/g,"");return["am","pm","a","p"].includes(a)}function k(e){let a=M(e);return a===null?!1:!isNaN(a.hour)&&!isNaN(a.minute)&&!isNaN(a.second)}function G(e){if(e.length>255||!new RegExp(/^.+@.+\.[a-zA-Z0-9]{2,}$/).test(e))return!1;let a="";return a+="^([a-zA-Z0-9!#$%'*+/=?^_`{|}~-]+",a+="(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*",a+="|",a+='"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*"',a+=")@(",a+="(",a+="(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+",a+="[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?",a+=")",a+=")$",new RegExp(a).test(e)}function B(e){return e=e.replace(/^[^2-90]+/g,""),e=e.replace(/(\d\d\d).*?(\d\d\d).*?(\d\d\d\d)(.*)/,"$1-$2-$3$4"),e}function K(e){return/^\d\d\d-\d\d\d-\d\d\d\d$/.test(e)}function W(e){return e.replace(/[^0-9]/g,"")}function J(e){return/^\-?\d*\.?\d*$/.test(e)}function Q(e){return e.replace(/[^\-0-9.]/g,"").replace(/(^-)|(-)/g,(a,s)=>s?"-":"").replace(/(\..*)\./g,"$1")}function X(e){return/^\-?\d*$/.test(e)}function ee(e){return e=e.trim(),new RegExp("^(?:[a-z+]+:)?//","i").test(e)?e:"https://"+e}function te(e){return new RegExp("^(?:[-a-z+]+:)?//","i").test(e)}function re(e){return e=e.replace(/[^0-9]/g,"").replace(/(.{5})(.*)/,"$1-$2").trim(),e.length===6&&(e=e.replace(/-/,"")),e}function ae(e){return new RegExp(/^\d{5}(-\d{4})?$/).test(e)}function se(e){return e=e.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/(.{3})\s*(.*)/,"$1 $2").trim(),e}function ne(e){return new RegExp(/^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$/).test(e)}function ie(e){return["transparent","currentColor"].includes(e)?!0:typeof e!="string"||!e.trim()?!1:typeof CSS=="object"&&typeof CSS.supports=="function"?CSS.supports("color",e):oe(e)}function oe(e){const a=new RegExp(/^rgba?\(\s*(\d{1,3}%?,\s*){2}\d{1,3}%?\s*(?:,\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),s=new RegExp(/^hsla?\(\s*\d+(deg|grad|rad|turn)?,\s*\d{1,3}%,\s*\s*\d{1,3}%(?:,\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),i=new RegExp(/^rgba?\(\s*(\d{1,3}%?\s+){2}\d{1,3}%?\s*(?:\s*\/\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),h=new RegExp(/^hsla?\(\s*\d+(deg|grad|rad|turn)?\s+\d{1,3}%\s+\s*\d{1,3}%(?:\s*\/\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),d=new RegExp(/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i);let u="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen";const m=new RegExp(`^(${u})$`,"i");return a.test(e)||s.test(e)||i.test(e)||h.test(e)||d.test(e)||m.test(e)}let L=null;const C=new Map;function le(e){if(e=e.trim().toLowerCase(),["transparent","currentcolor"].includes(e))return e;if(C.has(e))return C.get(e);L===null&&(L=document.createElement("canvas"),L.willReadFrequently=!0);let a=L.getContext("2d");if(!a)throw new Error("Can't get context from colorCanvas");a.fillStyle=e,a.fillRect(0,0,1,1);let s=a.getImageData(0,0,1,1).data,i="#"+("000000"+(s[0]<<16|s[1]<<8|s[2]).toString(16)).slice(-6);return C.set(e,i),i}function de(e){let a={valid:!1,error:!1,messages:[]};return typeof e=="boolean"?{valid:e,error:!1,messages:[]}:typeof e=="string"?{valid:!1,error:!1,messages:[e]}:(typeof e.valid=="boolean"&&(a.valid=e.valid),typeof e.message=="string"&&(a.messages=[e.message]),typeof e.messages=="string"&&(a.messages=[e.messages]),Array.isArray(e.messages)&&(a.messages=e.messages),e.error===!0&&(a.error=!0),a)}r.formatDateTime=D,r.isColor=ie,r.isDate=H,r.isDateInRange=j,r.isDateTime=z,r.isEmail=G,r.isFormControl=n,r.isInteger=X,r.isMeridiem=O,r.isNANPTel=K,r.isNumber=J,r.isPostalCA=ne,r.isTime=k,r.isType=l,r.isUrl=te,r.isZip=ae,r.momentToFPFormat=p,r.monthToNumber=y,r.normalizeValidationResult=de,r.parseColor=le,r.parseDate=w,r.parseDateTime=A,r.parseDateTimeToString=Z,r.parseDateToString=q,r.parseInteger=W,r.parseNANPTel=B,r.parseNumber=Q,r.parsePostalCA=se,r.parseTime=M,r.parseTimeToString=P,r.parseUrl=ee,r.parseZip=re,r.yearToFull=b,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})})}(E,E.exports)),E.exports}var o=x();class _ extends Event{constructor(r){super("validationSuccess",{cancelable:!0});f(this,"submitEvent");this.submitEvent=r}}class $ extends Event{constructor(r){super("validationError",{cancelable:!0});f(this,"submitEvent");this.submitEvent=r}}class V{constructor(t,r={}){f(this,"form");f(this,"inputs",[]);f(this,"inputErrors",{});f(this,"messages",{ERROR_MAIN:"There is a problem with your submission.",ERROR_GENERIC:"Enter a valid value.",ERROR_REQUIRED:"This field is required.",OPTION_REQUIRED:"An option must be selected.",CHECKED_REQUIRED:"This must be checked.",ERROR_MAXLENGTH:"This must be ${val} characters or fewer.",ERROR_MINLENGTH:"This must be at least ${val} characters.",ERROR_NUMBER:"This must be a number.",ERROR_INTEGER:"This must be a whole number.",ERROR_TEL:"This is not a valid telephone number.",ERROR_EMAIL:"This is not a valid email address.",ERROR_ZIP:"This is not a valid zip code.",ERROR_POSTAL:"This is not a valid postal code.",ERROR_DATE:"This is not a valid date.",ERROR_DATE_PAST:"The date must be in the past.",ERROR_DATE_FUTURE:"The date must be in the future.",ERROR_DATE_RANGE:"The date is outside the allowed range.",ERROR_DATETIME:"This is not a valid date and time.",ERROR_TIME:"This is not a valid time.",ERROR_TIME_RANGE:"The time is outside the allowed range.",ERROR_URL:"This is not a valid URL.",ERROR_COLOR:"This is not a valid CSS colour.",ERROR_CUSTOM_VALIDATION:"There was a problem validating this field."});f(this,"debug");f(this,"autoInit");f(this,"preventSubmit",!1);f(this,"hiddenClasses");f(this,"errorMainClasses");f(this,"errorInputClasses");f(this,"dispatchTimeout",0);f(this,"timeoutId",0);f(this,"debouncedInit");f(this,"originalNoValidate",!1);f(this,"validationSuccessCallback");f(this,"validationErrorCallback");f(this,"submitHandlerRef",this.submitHandler.bind(this));f(this,"inputInputHandlerRef",this.inputInputHandler.bind(this));f(this,"inputChangeHandlerRef",this.inputChangeHandler.bind(this));f(this,"inputKeydownHandlerRef",this.inputKeydownHandler.bind(this));f(this,"inputHandlers",{number:{parse:o.parseNumber,isValid:o.isNumber,error:this.messages.ERROR_NUMBER},integer:{parse:o.parseInteger,isValid:o.isInteger,error:this.messages.ERROR_INTEGER},tel:{parse:o.parseNANPTel,isValid:o.isNANPTel,error:this.messages.ERROR_TEL},email:{parse:t=>t.trim(),isValid:o.isEmail,error:this.messages.ERROR_EMAIL},zip:{parse:o.parseZip,isValid:o.isZip,error:this.messages.ERROR_ZIP},postal:{parse:o.parsePostalCA,isValid:o.isPostalCA,error:this.messages.ERROR_POSTAL},url:{parse:o.parseUrl,isValid:o.isUrl,error:this.messages.ERROR_URL},date:{parse:o.parseDateToString,isValid:o.isDate,error:this.messages.ERROR_DATE},datetime:{parse:o.parseDateTimeToString,isValid:o.isDateTime,error:this.messages.ERROR_DATETIME},time:{parse:o.parseTimeToString,isValid:o.isTime,error:this.messages.ERROR_TIME},color:{parse:t=>t.trim().toLowerCase(),isValid:o.isColor,error:this.messages.ERROR_COLOR}});f(this,"isSubmitting",!1);if(!t)throw new Error("Validator requires a form to be passed as the first argument.");if(!(t instanceof HTMLFormElement))throw new Error("form argument must be an instance of HTMLFormElement");this.form=t,(t.dataset.preventSubmit===""||t.dataset.preventSubmit)&&(this.preventSubmit=!0),Object.assign(this.messages,r.messages||{}),this.debug=r.debug||!1,this.autoInit=r.autoInit!==!1,this.preventSubmit=r.preventSubmit!==void 0?r.preventSubmit:this.preventSubmit,this.hiddenClasses=r.hiddenClasses||"hidden opacity-0",this.errorMainClasses=r.errorMainClasses||"m-2 border border-red-500 bg-red-100 p-3 dark:bg-red-900/80 text-center",this.errorInputClasses=r.errorInputClasses||"border-red-600 dark:border-red-500",this.validationSuccessCallback=r.validationSuccessCallback||(()=>{}),this.validationErrorCallback=r.validationErrorCallback||(()=>{}),this.debouncedInit=this.debounce(this.init.bind(this),45),this.autoInit&&this.init(),new MutationObserver(()=>this.autoInit&&this.debouncedInit()).observe(t,{childList:!0})}debounce(t,r){return(...n)=>{clearTimeout(this.timeoutId),this.timeoutId=window.setTimeout(()=>t(...n),r)}}addEventListeners(){this.form.addEventListener("submit",this.submitHandlerRef),this.form.addEventListener("input",this.inputInputHandlerRef),this.form.addEventListener("change",this.inputChangeHandlerRef),this.form.addEventListener("keydown",this.inputKeydownHandlerRef),this.form.addEventListener("remove",this.destroy,{once:!0})}removeEventListeners(){this.form.removeEventListener("submit",this.submitHandlerRef),this.form.removeEventListener("input",this.inputInputHandlerRef),this.form.removeEventListener("change",this.inputChangeHandlerRef),this.form.removeEventListener("keydown",this.inputKeydownHandlerRef),this.form.removeEventListener("remove",this.destroy)}init(){this.inputs=Array.from(this.form.elements).filter(t=>t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement),this.inputs.forEach(t=>{!t.name&&!t.id&&(t.id=`vl-input-${Math.random().toString(36).slice(2)}`),this.inputErrors[t.name||t.id]=[]}),this.originalNoValidate=this.form.hasAttribute("novalidate"),this.form.setAttribute("novalidate","novalidate"),this.removeEventListeners(),this.addEventListeners()}getErrorEl(t){const r=b=>{const w=b.replace(/([.#{}()\\?*[\]-])/g,"\\$1");return this.form.querySelector(`#${w}`)||document.getElementById(b)||null},n=t.closest("[data-flux-field]");if(n){const b=n.querySelector("[data-flux-error]");if(b)return b}const l=t.getAttribute("aria-describedby");if(l){const b=r(l);if(b)return b}const p=r(t.id+"-error");return p||r(t.name+"-error")||null}addErrorMain(t){const r=document.createElement("div");r.id="form-error-main",this.errorMainClasses.split(" ").forEach(n=>{r.classList.add(n)}),t?r.innerHTML=t:r.innerHTML=this.messages.ERROR_MAIN,this.form.appendChild(r)}addInputError(t,r=t.dataset.errorDefault||this.messages.ERROR_GENERIC){const n=t.name||t.id;this.debug&&console.log("Invalid value for "+n+": "+r),n in this.inputErrors||(this.inputErrors[n]=[]),this.inputErrors[n].includes(r)||this.inputErrors[n].push(r)}showInputErrors(t){if(!t||!t.name&&!t.id)return;const r=t.name||t.id,n=r in this.inputErrors?this.inputErrors[r]:[];if(!n.length)return;t.setAttribute("aria-invalid","true"),this.errorInputClasses.split(" ").forEach(p=>{t.classList.add(p)});let l=this.getErrorEl(t);l&&(l.innerHTML=n.join("<br>"),this.hiddenClasses.split(" ").forEach(p=>{l&&l.classList.remove(p)}))}showFormErrors(){if(this.inputs.forEach(t=>this.showInputErrors(t)),Object.values(this.inputErrors).some(t=>Array.isArray(t)&&t.length)){const t=this.form.querySelectorAll("#form-error-main");t.length?t.forEach(r=>{r.innerHTML||(r.innerHTML=this.messages.ERROR_MAIN),this.hiddenClasses.split(" ").forEach(n=>{r.classList.remove(n)})}):this.addErrorMain()}}clearInputErrors(t){this.inputErrors[t.name||t.id]=[],t.removeAttribute("aria-invalid");let r=this.getErrorEl(t);r&&(this.errorInputClasses.split(" ").forEach(n=>{t.classList.remove(n)}),this.hiddenClasses.split(" ").forEach(n=>{r&&r.classList.add(n)}),r.textContent="")}clearFormErrors(){this.form.querySelectorAll("#form-error-main").forEach(t=>{this.hiddenClasses.split(" ").forEach(r=>{t.classList.add(r)})}),this.inputs.forEach(t=>this.clearInputErrors(t))}validateRequired(t){let r=!0;if(t.required&&(t.value===""||t instanceof HTMLInputElement&&["checkbox","radio"].includes(t.type)&&!t.checked))if(t instanceof HTMLInputElement&&["checkbox","radio"].includes(t.type)){let n=!1,l=t.name;const p=this.form.querySelectorAll(`input[name="${l}"]`);if(p.forEach(y=>{if(y instanceof HTMLInputElement&&y.checked===!0){n=!0;return}}),n===!1){r=!1;let y=p.length>1?this.messages.OPTION_REQUIRED:this.messages.CHECKED_REQUIRED;t.dataset.errorDefault&&(y=t.dataset.errorDefault),this.addInputError(t,y)}}else o.isFormControl(t)&&(r=!1,this.addInputError(t,t.dataset.errorDefault||this.messages.ERROR_REQUIRED));return r}validateLength(t){let r=!0;if(t.disabled)return r;if((t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length){let n=t.minLength>0?t.minLength:t.dataset.minLength?parseInt(t.dataset.minLength):0,l=t.maxLength>0&&t.maxLength<5e5?t.maxLength:t.dataset.maxLength?parseInt(t.dataset.maxLength):1/0;n>0&&t.value.length<n&&(r=!1,this.addInputError(t,this.messages.ERROR_MINLENGTH.replace("${val}",n.toString()))),t.value.length>l&&(r=!1,this.addInputError(t,this.messages.ERROR_MAXLENGTH.replace("${val}",l.toString())))}return r}validateInputType(t){const r=t.dataset.type||t.type,n=this.inputHandlers[t.type]||this.inputHandlers[r];if(n){const l=t.dataset.dateFormat||t.dataset.timeFormat,p=n.parse(t.value,l),y=["date","time","datetime-local","month","week"];if(p.length&&!y.includes(t.type)&&(t.value=p),!n.isValid(t.value))return this.addInputError(t,n.error),!1}return!0}validateDateRange(t){if(t.dataset.dateRange){const r=t.dataset.dateRange,n=o.parseDate(t.value);if(!isNaN(n.getTime())&&!o.isDateInRange(n,r)){let l=t.dataset.errorDefault||this.messages.ERROR_DATE_RANGE;return r==="past"?l=this.messages.ERROR_DATE_PAST:r==="future"&&(l=this.messages.ERROR_DATE_FUTURE),this.addInputError(t,l),!1}}return!0}validatePattern(t){const r=t.dataset.pattern||t instanceof HTMLInputElement&&t.pattern||null;return r&&!new RegExp(r).test(t.value)?(this.addInputError(t),!1):!0}async validateCustom(t){if(t.disabled)return!0;const r=t.dataset.validation;if(!r||typeof r!="string")return!0;const n=window[r];if(!n||typeof n!="function")return!0;let l;try{l=await Promise.resolve(n(t.value)),l=o.normalizeValidationResult(l)}catch{return this.addInputError(t,this.messages.ERROR_CUSTOM_VALIDATION),!1}const p=l.messages.join("<br>")||this.messages.ERROR_CUSTOM_VALIDATION;return l.valid||this.addInputError(t,p),l.valid}async validateInput(t){if(!(t instanceof HTMLInputElement)||!t.value.length)return!0;let r=!0;return t.disabled||(r=this.validateInputType(t)&&r,r=this.validateDateRange(t)&&r,r=this.validatePattern(t)&&r,r=await this.validateCustom(t)&&r),r}async validate(t){let r=!0;for(const n of this.inputs)n.disabled||(r=this.validateRequired(n)&&r,r=this.validateLength(n)&&r,r=await this.validateInput(n)&&r,n.value.length||(r=await this.validateCustom(n)&&r));return r}async submitHandler(t){if(this.isSubmitting)return;t.preventDefault(),this.clearFormErrors();let r=await this.validate(t);this.showFormErrors();const n=new _(t),l=new $(t);r?(this.form.dispatchEvent(n),this.validationSuccessCallback&&this.validationSuccessCallback(t)):(this.form.dispatchEvent(l),this.validationErrorCallback&&this.validationErrorCallback(t)),r&&!this.preventSubmit&&(this.isSubmitting=!0,n.defaultPrevented||this.form.submit(),this.isSubmitting=!1)}shouldSkipValidation(t){return typeof t.dataset.novalidate>"u"?!1:t.dataset.novalidate===""?!0:t.dataset.novalidate==="true"}async inputChangeHandler(t){!(t.target instanceof HTMLInputElement)||this.shouldSkipValidation(t.target)||(this.clearInputErrors(t.target),this.validateLength(t.target),await this.validateInput(t.target),this.showInputErrors(t.target))}inputInputHandler(t){const r=t.target;this.shouldSkipValidation(r)||(o.isType(r,"integer")&&(r.value=o.parseInteger(r.value)),r.type!=="number"&&o.isType(r,["number","float","decimal"])&&(r.value=o.parseNumber(r.value)),o.isType(r,"color")&&this.syncColorInput(t))}syncColorInput(t){let r=t.target,n=r;r.type==="color"&&(n=this.form.querySelector(`#${r.id.replace(/-color/,"")}`));let l=this.form.querySelector(`#${n.id}-color-label`);if((r.dataset.type||"")==="color"){let p=this.form.querySelector(`input#${r.id}-color`);if(!p||!o.isColor(r.value))return;p.value=o.parseColor(r.value)}r.type==="color"&&(n.value=r.value),l&&(l.style.backgroundColor=r.value),clearTimeout(this.dispatchTimeout),this.dispatchTimeout=window.setTimeout(()=>{n.dispatchEvent(new Event("change",{bubbles:!0}))},200)}inputKeydownHandler(t){t.target instanceof HTMLInputElement&&o.isType(t.target,"integer")&&(t.key==="ArrowUp"?(t.preventDefault(),t.target.value===""&&(t.target.value="0"),t.target.value=(parseInt(t.target.value)+1).toString()):t.key==="ArrowDown"&&(parseInt(t.target.value)>0?t.target.value=(parseInt(t.target.value)-1).toString():t.target.value="0"))}destroy(){this.removeEventListeners(),this.originalNoValidate||this.form.removeAttribute("novalidate")}}return V});
|
|
1
|
+
(function(E,R){typeof exports=="object"&&typeof module<"u"?module.exports=R():typeof define=="function"&&define.amd?define(R):(E=typeof globalThis<"u"?globalThis:E||self,E.Validator=R())})(this,function(){"use strict";var ue=Object.defineProperty;var ce=(E,R,T)=>R in E?ue(E,R,{enumerable:!0,configurable:!0,writable:!0,value:T}):E[R]=T;var f=(E,R,T)=>ce(E,typeof R!="symbol"?R+"":R,T);var E={exports:{}},R=E.exports,T;function k(){return T||(T=1,function(L,t){(function(r,i){i(t)})(R,function(r){function i(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function l(e,a){typeof a=="string"&&(a=[a]);const s=e.dataset.type||"",n=e.type;return!!(a.includes(s)||a.includes(n))}function p(e){return e.replace(/YYYY/g,"Y").replace(/YY/g,"y").replace(/MMMM/g,"F").replace(/MMM/g,"{3}").replace(/MM/g,"{2}").replace(/M/g,"n").replace(/DD/g,"{5}").replace(/D/g,"j").replace(/dddd/g,"l").replace(/ddd/g,"D").replace(/dd/g,"D").replace(/d/g,"w").replace(/HH/g,"{6}").replace(/H/g,"G").replace(/hh/g,"h").replace(/mm/g,"i").replace(/m/g,"i").replace(/ss/g,"S").replace(/s/g,"s").replace(/A/gi,"K").replace(/\{3\}/g,"M").replace(/\{2\}/g,"m").replace(/\{5\}/g,"d").replace(/\{6\}/g,"H")}function y(e){const a=parseInt(e);if(typeof e=="number"||!isNaN(a))return a-1;const s=new Date(`1 ${e} 2000`).getMonth();if(!isNaN(s))return s;const n={ja:0,en:0,fe:1,fé:1,ap:3,ab:3,av:3,mai:4,juin:5,juil:6,au:7,ag:7,ao:7,se:8,o:9,n:10,d:11};for(const h in n)if(e.toLowerCase().startsWith(h))return n[h];throw new Error("Invalid month name: "+e)}function b(e){return typeof e=="string"&&(e=parseInt(e.replace(/\D/g,""))),e>99?e:e<(new Date().getFullYear()+20)%100?e+2e3:e+1900}function w(e){if(e instanceof Date)return e;e=e.trim().toLowerCase();let a=0,s=0,n=0,h=0,d=0,u=0;const m=new RegExp(/\d{1,2}\:\d\d(?:\:\d\ds?)?\s?(?:[a|p]m?)?/gi);if(m.test(e)){const v=e.match(m)[0];e=e.replace(v,"").trim();const I=M(v);if(I!==null&&({hour:h,minute:d,second:u}=I),e.length<=2){const A=new Date;return new Date(A.getFullYear(),A.getMonth(),A.getDate(),h,d,u)}}const g=/(^|\b)(mo|tu|we|th|fr|sa|su|lu|mard|mer|jeu|ve|dom)[\w]*\.?/gi;e=e.replace(g,"").trim();const c=new Date(new Date().setHours(0,0,0,0));if(/(now|today)/.test(e))return c;if(e.includes("tomorrow"))return new Date(c.setDate(c.getDate()+1));e.length===8&&(e=e.replace(/(\d\d\d\d)(\d\d)(\d\d)/,"$1-$2-$3")),e.length===6&&(e=e.replace(/(\d\d)(\d\d)(\d\d)/,b(e.slice(0,2))+"-$2-$3"));try{({year:a,month:s,day:n}=U(e))}catch{return new Date("")}return new Date(a,s-1,n,h,d,u)}function Y(e,a=[null,null,null]){const s=n=>n.filter(h=>!a.includes(h));return e===0||e>31?s(["y"]):e>12?s(["d","y"]):e>=1&&e<=12?s(["m","d","y"]):[]}function U(e){const a=e.split(/[\s-/:.,]+/).filter(d=>d!=="");if(a.length<3){if(e.match(/\d{4}/)!==null)throw new Error("Invalid Date");a.unshift(String(new Date().getFullYear()))}const s={year:0,month:0,day:0};function n(d,u){d==="year"?s.year=b(u):s[d]=u}let h=0;for(;!(s.year&&s.month&&s.day);){e:for(const d of a){if(h++,/^[a-zA-Zé]+$/.test(d)){s.month||n("month",y(d)+1);continue}if(/^'\d\d$/.test(d)||/^\d{3,5}$/.test(d)){s.year||n("year",parseInt(d.replace(/'/,"")));continue}const u=parseInt(d);if(isNaN(u))throw console.error(`not date because ${d} isNaN`),new Error("Invalid Date");const m=Y(u,[s.year?"y":null,s.month?"m":null,s.day?"d":null]);if(m.length==1){if(m[0]==="m"&&!s.month){n("month",u);continue e}if(m[0]==="d"&&!s.day){n("day",u);continue e}if(m[0]==="y"&&!s.year){n("year",u);continue e}}h>3&&(!s.month&&m.includes("m")?n("month",u):!s.day&&m.includes("d")&&n("day",u))}if(h>6)throw new Error("Invalid Date")}if(s.year&&s.month&&s.day)return s;throw new Error("Invalid Date")}function M(e){if(e=e.trim().toLowerCase(),e==="now"){const c=new Date;return{hour:c.getHours(),minute:c.getMinutes(),second:c.getSeconds()}}if(e==="noon")return{hour:12,minute:0,second:0};const a=e.match(/(\d{3,4})/);if(a){const c=a[1].length,v=a[1].slice(0,c==3?1:2),I=a[1].slice(-2);e=e.replace(a[1],v+":"+I)}const s=new RegExp(/^(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)\.?m?\.?)?$/i);if(s.test(e)){const c=e.match(s);if(c===null)return null;e=c[1]+":"+(c[2]||"00")+(c[3]||"")}const n=new RegExp(/^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(!n.test(e))return null;const h=e.match(n);if(h===null)return null;const d=parseInt(h[1]),u=parseInt(h[2]),m=h[3]?parseInt(h[3]):0,g=h[4];return isNaN(d)||isNaN(u)||isNaN(m)?null:g==="p"&&d<12?{hour:d+12,minute:u,second:m}:g==="a"&&d===12?{hour:0,minute:u,second:m}:d<0||d>23||u<0||u>59||m<0||m>59?null:{hour:d,minute:u,second:m}}function P(e,a="h:mm A"){const s=M(e);if(s){const n=new Date;return n.setHours(s.hour),n.setMinutes(s.minute),n.setSeconds(s.second),n.setMilliseconds(0),D(n,a)}return""}function C(e){if(e instanceof Date)return e;if(e.trim().length<3)return null;e=e.replace(/(\d)T(\d)/,"$1 $2");let a=e.split(/[\s,]+/).filter(g=>g!==""),s="",n="",h="";a.forEach((g,c)=>{const v=g.match(/^(\d{1,4})([apAP]\.?[mM]?\.?)/);v?n=v[0]:(g.includes(":")||g==="now"||g==="noon")&&(n=g),O(g)&&(h=g,!n&&c>0&&_(a[c-1])&&(n=a[c-1]))}),n?a=a.filter(g=>g!==n&&g!==h):[s,a]=F(a);const d=n?`${n} ${h}`:s?a.join(" "):"",u=M(d)||{hour:0,minute:0,second:0},m=w(s||a.join(" ").trim()||"today");return!m||isNaN(m.getTime())?null:new Date(m.getFullYear(),m.getMonth(),m.getDate(),u.hour,u.minute,u.second)}function F(e){for(let a=3;a>0;a--){const s=e.slice(0,a).join(" ");if(H(s))return[s,e.slice(a)]}return["",e]}function D(e,a="YYYY-MM-DD"){if(e=w(e),isNaN(e.getTime()))return"";const s={y:e.getFullYear(),M:e.getMonth(),D:e.getDate(),W:e.getDay(),H:e.getHours(),m:e.getMinutes(),s:e.getSeconds(),ms:e.getMilliseconds()},n=(c,v=2)=>(c+"").padStart(v,"0"),h=()=>s.H%12||12,d=c=>c<12?"AM":"PM",u=c=>"January|February|March|April|May|June|July|August|September|October|November|December".split("|")[c];function m(c,v=0){const I="Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|");return v?I[c].slice(0,v):I[c]}const g={YY:String(s.y).slice(-2),YYYY:s.y,M:s.M+1,MM:n(s.M+1),MMMM:u(s.M),MMM:u(s.M).slice(0,3),D:String(s.D),DD:n(s.D),d:String(s.W),dd:m(s.W,2),ddd:m(s.W,3),dddd:m(s.W),H:String(s.H),HH:n(s.H),h:h(),hh:n(h()),A:d(s.H),a:d(s.H).toLowerCase(),m:String(s.m),mm:n(s.m),s:String(s.s),ss:n(s.s),SSS:n(s.ms,3)};return a.replace(/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,(c,v)=>v||g[c])}function q(e,a){const s=w(e);return isNaN(s.getTime())?"":((!a||a.length===0)&&(a="YYYY-MMM-DD"),D(s,a))}function Z(e,a){const s=C(e);return s===null||isNaN(s.getTime())?"":((!a||a.length===0)&&(a="YYYY-MMM-DD h:mm A"),D(s,a))}function H(e){if(typeof e!="string"&&!(e instanceof Date))return!1;let a=w(e);return a==null?!1:!isNaN(a.getTime())}function z(e){if(typeof e!="string"&&!(e instanceof Date))return!1;let a=C(e);return a==null?!1:!isNaN(a.getTime())}function j(e,a){return!(a==="past"&&e>new Date||a==="future"&&e.getTime()<new Date().setHours(0,0,0,0))}function O(e){const a=e.toLowerCase().replace(/[.\s]/g,"");return["am","pm","a","p"].includes(a)}function _(e){let a=M(e);return a===null?!1:!isNaN(a.hour)&&!isNaN(a.minute)&&!isNaN(a.second)}function G(e){if(e.length>255||!new RegExp(/^.+@.+\.[a-zA-Z0-9]{2,}$/).test(e))return!1;let a="";return a+="^([a-zA-Z0-9!#$%'*+/=?^_`{|}~-]+",a+="(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*",a+="|",a+='"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*"',a+=")@(",a+="(",a+="(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+",a+="[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?",a+=")",a+=")$",new RegExp(a).test(e)}function B(e){return e=e.replace(/^[^2-90]+/g,""),e=e.replace(/(\d\d\d).*?(\d\d\d).*?(\d\d\d\d)(.*)/,"$1-$2-$3$4"),e}function K(e){return/^\d\d\d-\d\d\d-\d\d\d\d$/.test(e)}function W(e){return e.replace(/[^0-9]/g,"")}function J(e){return/^\-?\d*\.?\d*$/.test(e)}function Q(e){return e.replace(/[^\-0-9.]/g,"").replace(/(^-)|(-)/g,(a,s)=>s?"-":"").replace(/(\..*)\./g,"$1")}function X(e){return/^\-?\d*$/.test(e)}function ee(e){return e=e.trim(),new RegExp("^(?:[a-z+]+:)?//","i").test(e)?e:"https://"+e}function te(e){return new RegExp("^(?:[-a-z+]+:)?//","i").test(e)}function re(e){return e=e.replace(/[^0-9]/g,"").replace(/(.{5})(.*)/,"$1-$2").trim(),e.length===6&&(e=e.replace(/-/,"")),e}function ae(e){return new RegExp(/^\d{5}(-\d{4})?$/).test(e)}function se(e){return e=e.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/(.{3})\s*(.*)/,"$1 $2").trim(),e}function ie(e){return new RegExp(/^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$/).test(e)}function ne(e){return["transparent","currentColor"].includes(e)?!0:typeof e!="string"||!e.trim()?!1:typeof CSS=="object"&&typeof CSS.supports=="function"?CSS.supports("color",e):oe(e)}function oe(e){const a=new RegExp(/^rgba?\(\s*(\d{1,3}%?,\s*){2}\d{1,3}%?\s*(?:,\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),s=new RegExp(/^hsla?\(\s*\d+(deg|grad|rad|turn)?,\s*\d{1,3}%,\s*\s*\d{1,3}%(?:,\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),n=new RegExp(/^rgba?\(\s*(\d{1,3}%?\s+){2}\d{1,3}%?\s*(?:\s*\/\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),h=new RegExp(/^hsla?\(\s*\d+(deg|grad|rad|turn)?\s+\d{1,3}%\s+\s*\d{1,3}%(?:\s*\/\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),d=new RegExp(/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i);let u="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen";const m=new RegExp(`^(${u})$`,"i");return a.test(e)||s.test(e)||n.test(e)||h.test(e)||d.test(e)||m.test(e)}let S=null;const N=new Map;function le(e){if(e=e.trim().toLowerCase(),["transparent","currentcolor"].includes(e))return e;if(N.has(e))return N.get(e);S===null&&(S=document.createElement("canvas"),S.willReadFrequently=!0);let a=S.getContext("2d");if(!a)throw new Error("Can't get context from colorCanvas");a.fillStyle=e,a.fillRect(0,0,1,1);let s=a.getImageData(0,0,1,1).data,n="#"+("000000"+(s[0]<<16|s[1]<<8|s[2]).toString(16)).slice(-6);return N.set(e,n),n}function de(e){let a={valid:!1,error:!1,messages:[]};return typeof e=="boolean"?{valid:e,error:!1,messages:[]}:typeof e=="string"?{valid:!1,error:!1,messages:[e]}:(typeof e.valid=="boolean"&&(a.valid=e.valid),typeof e.message=="string"&&(a.messages=[e.message]),typeof e.messages=="string"&&(a.messages=[e.messages]),Array.isArray(e.messages)&&(a.messages=e.messages),e.error===!0&&(a.error=!0),a)}r.formatDateTime=D,r.isColor=ne,r.isDate=H,r.isDateInRange=j,r.isDateTime=z,r.isEmail=G,r.isFormControl=i,r.isInteger=X,r.isMeridiem=O,r.isNANPTel=K,r.isNumber=J,r.isPostalCA=ie,r.isTime=_,r.isType=l,r.isUrl=te,r.isZip=ae,r.momentToFPFormat=p,r.monthToNumber=y,r.normalizeValidationResult=de,r.parseColor=le,r.parseDate=w,r.parseDateTime=C,r.parseDateTimeToString=Z,r.parseDateToString=q,r.parseInteger=W,r.parseNANPTel=B,r.parseNumber=Q,r.parsePostalCA=se,r.parseTime=M,r.parseTimeToString=P,r.parseUrl=ee,r.parseZip=re,r.yearToFull=b,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})})}(E,E.exports)),E.exports}var o=k();class x extends Event{constructor(r){super("validationSuccess",{cancelable:!0});f(this,"submitEvent");this.submitEvent=r}}class $ extends Event{constructor(r){super("validationError",{cancelable:!0});f(this,"submitEvent");this.submitEvent=r}}class V{constructor(t,r={}){f(this,"form");f(this,"inputs",[]);f(this,"inputErrors",{});f(this,"messages",{ERROR_MAIN:"There is a problem with your submission.",ERROR_GENERIC:"Enter a valid value.",ERROR_REQUIRED:"This field is required.",OPTION_REQUIRED:"An option must be selected.",CHECKED_REQUIRED:"This must be checked.",ERROR_MAXLENGTH:"This must be ${val} characters or fewer.",ERROR_MINLENGTH:"This must be at least ${val} characters.",ERROR_NUMBER:"This must be a number.",ERROR_INTEGER:"This must be a whole number.",ERROR_TEL:"This is not a valid telephone number.",ERROR_EMAIL:"This is not a valid email address.",ERROR_ZIP:"This is not a valid zip code.",ERROR_POSTAL:"This is not a valid postal code.",ERROR_DATE:"This is not a valid date.",ERROR_DATE_PAST:"The date must be in the past.",ERROR_DATE_FUTURE:"The date must be in the future.",ERROR_DATE_RANGE:"The date is outside the allowed range.",ERROR_DATETIME:"This is not a valid date and time.",ERROR_TIME:"This is not a valid time.",ERROR_TIME_RANGE:"The time is outside the allowed range.",ERROR_URL:"This is not a valid URL.",ERROR_COLOR:"This is not a valid CSS colour.",ERROR_CUSTOM_VALIDATION:"There was a problem validating this field."});f(this,"debug");f(this,"autoInit");f(this,"preventSubmit",!1);f(this,"hiddenClasses");f(this,"showMainError",!0);f(this,"errorMainClasses");f(this,"errorInputClasses");f(this,"dispatchTimeout",0);f(this,"timeoutId",0);f(this,"debouncedInit");f(this,"originalNoValidate",!1);f(this,"validationSuccessCallback");f(this,"validationErrorCallback");f(this,"submitHandlerRef",this.submitHandler.bind(this));f(this,"inputInputHandlerRef",this.inputInputHandler.bind(this));f(this,"inputChangeHandlerRef",this.inputChangeHandler.bind(this));f(this,"inputKeydownHandlerRef",this.inputKeydownHandler.bind(this));f(this,"inputHandlers",{number:{parse:o.parseNumber,isValid:o.isNumber,error:this.messages.ERROR_NUMBER},integer:{parse:o.parseInteger,isValid:o.isInteger,error:this.messages.ERROR_INTEGER},tel:{parse:o.parseNANPTel,isValid:o.isNANPTel,error:this.messages.ERROR_TEL},email:{parse:t=>t.trim(),isValid:o.isEmail,error:this.messages.ERROR_EMAIL},zip:{parse:o.parseZip,isValid:o.isZip,error:this.messages.ERROR_ZIP},postal:{parse:o.parsePostalCA,isValid:o.isPostalCA,error:this.messages.ERROR_POSTAL},url:{parse:o.parseUrl,isValid:o.isUrl,error:this.messages.ERROR_URL},date:{parse:o.parseDateToString,isValid:o.isDate,error:this.messages.ERROR_DATE},datetime:{parse:o.parseDateTimeToString,isValid:o.isDateTime,error:this.messages.ERROR_DATETIME},time:{parse:o.parseTimeToString,isValid:o.isTime,error:this.messages.ERROR_TIME},color:{parse:t=>t.trim().toLowerCase(),isValid:o.isColor,error:this.messages.ERROR_COLOR}});f(this,"isSubmitting",!1);if(!t)throw new Error("Validator requires a form to be passed as the first argument.");if(!(t instanceof HTMLFormElement))throw new Error("form argument must be an instance of HTMLFormElement");this.form=t,(t.dataset.preventSubmit===""||t.dataset.preventSubmit)&&(this.preventSubmit=!0),Object.assign(this.messages,r.messages||{}),this.debug=r.debug||!1,this.autoInit=r.autoInit!==!1,this.preventSubmit=r.preventSubmit!==void 0?r.preventSubmit:this.preventSubmit,this.hiddenClasses=r.hiddenClasses||"hidden opacity-0",this.errorMainClasses=r.errorMainClasses||"m-2 border border-red-500 bg-red-100 p-3 dark:bg-red-900/80 text-center",this.errorInputClasses=r.errorInputClasses||"border-red-600 dark:border-red-500",this.showMainError=r.showMainError!==void 0?r.showMainError:!0,this.validationSuccessCallback=r.validationSuccessCallback||(()=>{}),this.validationErrorCallback=r.validationErrorCallback||(()=>{}),this.debouncedInit=this.debounce(this.init.bind(this),45),this.autoInit&&this.init(),new MutationObserver(()=>this.autoInit&&this.debouncedInit()).observe(t,{childList:!0})}debounce(t,r){return(...i)=>{clearTimeout(this.timeoutId),this.timeoutId=window.setTimeout(()=>t(...i),r)}}addEventListeners(){this.form.addEventListener("submit",this.submitHandlerRef),this.form.addEventListener("input",this.inputInputHandlerRef),this.form.addEventListener("change",this.inputChangeHandlerRef),this.form.addEventListener("keydown",this.inputKeydownHandlerRef),this.form.addEventListener("remove",this.destroy,{once:!0})}removeEventListeners(){this.form.removeEventListener("submit",this.submitHandlerRef),this.form.removeEventListener("input",this.inputInputHandlerRef),this.form.removeEventListener("change",this.inputChangeHandlerRef),this.form.removeEventListener("keydown",this.inputKeydownHandlerRef),this.form.removeEventListener("remove",this.destroy)}init(){this.inputs=Array.from(this.form.elements).filter(t=>t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement),this.inputs.forEach(t=>{!t.name&&!t.id&&(t.id=`vl-input-${Math.random().toString(36).slice(2)}`),this.inputErrors[t.name||t.id]=[]}),this.originalNoValidate=this.form.hasAttribute("novalidate"),this.form.setAttribute("novalidate","novalidate"),this.removeEventListeners(),this.addEventListeners()}getErrorEl(t){const r=b=>{const w=b.replace(/([.#{}()\\?*[\]-])/g,"\\$1");return this.form.querySelector(`#${w}`)||document.getElementById(b)||null},i=t.closest("[data-flux-field]");if(i){const b=i.querySelector("[data-flux-error]");if(b)return b}const l=t.getAttribute("aria-describedby");if(l){const b=r(l);if(b)return b}const p=r(t.id+"-error");return p||r(t.name+"-error")||null}addErrorMain(t){let r=this._getMainErrorElement();r||(r=document.createElement("div"),r.id="form-error-main",this.form.appendChild(r)),this.errorMainClasses.split(" ").forEach(i=>{r.classList.add(i)}),r.innerHTML=t||this.messages.ERROR_MAIN,this.hiddenClasses.split(" ").forEach(i=>{r.classList.remove(i)})}_getMainErrorElement(){if(this.form.id){const t=`${this.form.id}-error-main`,r=document.getElementById(t);if(r)return r}return this.form.querySelector("#form-error-main")}addInputError(t,r=t.dataset.errorDefault||this.messages.ERROR_GENERIC){const i=t.name||t.id;this.debug&&console.log("Invalid value for "+i+": "+r),i in this.inputErrors||(this.inputErrors[i]=[]),this.inputErrors[i].includes(r)||this.inputErrors[i].push(r)}showInputErrors(t){if(!t||!t.name&&!t.id)return;const r=t.name||t.id,i=r in this.inputErrors?this.inputErrors[r]:[];if(!i.length)return;t.setAttribute("aria-invalid","true"),this.errorInputClasses.split(" ").forEach(p=>{t.classList.add(p)});let l=this.getErrorEl(t);l&&(l.innerHTML=i.join("<br>"),this.hiddenClasses.split(" ").forEach(p=>{l&&l.classList.remove(p)}))}showFormErrors(){if(this.inputs.forEach(t=>this.showInputErrors(t)),this.showMainError&&Object.values(this.inputErrors).some(t=>Array.isArray(t)&&t.length)){let t=this._getMainErrorElement();t?(t.innerHTML||(t.innerHTML=this.messages.ERROR_MAIN),this.hiddenClasses.split(" ").forEach(r=>{t.classList.remove(r)})):this.addErrorMain()}}clearInputErrors(t){this.inputErrors[t.name||t.id]=[],t.removeAttribute("aria-invalid");let r=this.getErrorEl(t);r&&(this.errorInputClasses.split(" ").forEach(i=>{t.classList.remove(i)}),this.hiddenClasses.split(" ").forEach(i=>{r&&r.classList.add(i)}),r.textContent="")}clearFormErrors(){const t=this._getMainErrorElement();t&&this.hiddenClasses.split(" ").forEach(r=>{t.classList.add(r)}),this.inputs.forEach(r=>this.clearInputErrors(r))}validateRequired(t){let r=!0;if(t.required&&(t.value===""||t instanceof HTMLInputElement&&["checkbox","radio"].includes(t.type)&&!t.checked))if(t instanceof HTMLInputElement&&["checkbox","radio"].includes(t.type)){let i=!1,l=t.name;const p=this.form.querySelectorAll(`input[name="${l}"]`);if(p.forEach(y=>{if(y instanceof HTMLInputElement&&y.checked===!0){i=!0;return}}),i===!1){r=!1;let y=p.length>1?this.messages.OPTION_REQUIRED:this.messages.CHECKED_REQUIRED;t.dataset.errorDefault&&(y=t.dataset.errorDefault),this.addInputError(t,y)}}else o.isFormControl(t)&&(r=!1,this.addInputError(t,t.dataset.errorDefault||this.messages.ERROR_REQUIRED));return r}validateLength(t){let r=!0;if(t.disabled)return r;if((t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length){let i=t.minLength>0?t.minLength:t.dataset.minLength?parseInt(t.dataset.minLength):0,l=t.maxLength>0&&t.maxLength<5e5?t.maxLength:t.dataset.maxLength?parseInt(t.dataset.maxLength):1/0;i>0&&t.value.length<i&&(r=!1,this.addInputError(t,this.messages.ERROR_MINLENGTH.replace("${val}",i.toString()))),t.value.length>l&&(r=!1,this.addInputError(t,this.messages.ERROR_MAXLENGTH.replace("${val}",l.toString())))}return r}validateInputType(t){const r=t.dataset.type||t.type,i=this.inputHandlers[t.type]||this.inputHandlers[r];if(i){const l=t.dataset.dateFormat||t.dataset.timeFormat,p=i.parse(t.value,l),y=["date","time","datetime-local","month","week"];if(p.length&&!y.includes(t.type)&&(t.value=p),!i.isValid(t.value))return this.addInputError(t,i.error),!1}return!0}validateDateRange(t){if(t.dataset.dateRange){const r=t.dataset.dateRange,i=o.parseDate(t.value);if(!isNaN(i.getTime())&&!o.isDateInRange(i,r)){let l=t.dataset.errorDefault||this.messages.ERROR_DATE_RANGE;return r==="past"?l=this.messages.ERROR_DATE_PAST:r==="future"&&(l=this.messages.ERROR_DATE_FUTURE),this.addInputError(t,l),!1}}return!0}validatePattern(t){const r=t.dataset.pattern||t instanceof HTMLInputElement&&t.pattern||null;return r&&!new RegExp(r).test(t.value)?(this.addInputError(t),!1):!0}async validateCustom(t){if(t.disabled)return!0;const r=t.dataset.validation;if(!r||typeof r!="string")return!0;const i=window[r];if(!i||typeof i!="function")return!0;let l;try{l=await Promise.resolve(i(t.value)),l=o.normalizeValidationResult(l)}catch{return this.addInputError(t,this.messages.ERROR_CUSTOM_VALIDATION),!1}const p=l.messages.join("<br>")||this.messages.ERROR_CUSTOM_VALIDATION;return l.valid||this.addInputError(t,p),l.valid}async validateInput(t){if(!(t instanceof HTMLInputElement)||!t.value.length)return!0;let r=!0;return t.disabled||(r=this.validateInputType(t)&&r,r=this.validateDateRange(t)&&r,r=this.validatePattern(t)&&r,r=await this.validateCustom(t)&&r),r}async validate(t){let r=!0;for(const i of this.inputs)i.disabled||(r=this.validateRequired(i)&&r,r=this.validateLength(i)&&r,r=await this.validateInput(i)&&r,i.value.length||(r=await this.validateCustom(i)&&r));return r}async submitHandler(t){if(this.isSubmitting)return;t.preventDefault(),this.clearFormErrors();let r=await this.validate(t);this.showFormErrors();const i=new x(t),l=new $(t);r?(this.form.dispatchEvent(i),this.validationSuccessCallback&&this.validationSuccessCallback(t)):(this.form.dispatchEvent(l),this.validationErrorCallback&&this.validationErrorCallback(t)),r&&!this.preventSubmit&&(this.isSubmitting=!0,i.defaultPrevented||this.form.submit(),this.isSubmitting=!1)}shouldSkipValidation(t){return typeof t.dataset.novalidate>"u"?!1:t.dataset.novalidate===""?!0:t.dataset.novalidate==="true"}async inputChangeHandler(t){!(t.target instanceof HTMLInputElement)||this.shouldSkipValidation(t.target)||(this.clearInputErrors(t.target),this.validateLength(t.target),await this.validateInput(t.target),this.showInputErrors(t.target))}inputInputHandler(t){const r=t.target;this.shouldSkipValidation(r)||(o.isType(r,"integer")&&(r.value=o.parseInteger(r.value)),r.type!=="number"&&o.isType(r,["number","float","decimal"])&&(r.value=o.parseNumber(r.value)),o.isType(r,"color")&&this.syncColorInput(t))}syncColorInput(t){let r=t.target,i=r;r.type==="color"&&(i=this.form.querySelector(`#${r.id.replace(/-color/,"")}`));let l=this.form.querySelector(`#${i.id}-color-label`);if((r.dataset.type||"")==="color"){let p=this.form.querySelector(`input#${r.id}-color`);if(!p||!o.isColor(r.value))return;p.value=o.parseColor(r.value)}r.type==="color"&&(i.value=r.value),l&&(l.style.backgroundColor=r.value),clearTimeout(this.dispatchTimeout),this.dispatchTimeout=window.setTimeout(()=>{i.dispatchEvent(new Event("change",{bubbles:!0}))},200)}inputKeydownHandler(t){t.target instanceof HTMLInputElement&&o.isType(t.target,"integer")&&(t.key==="ArrowUp"?(t.preventDefault(),t.target.value===""&&(t.target.value="0"),t.target.value=(parseInt(t.target.value)+1).toString()):t.key==="ArrowDown"&&(parseInt(t.target.value)>0?t.target.value=(parseInt(t.target.value)-1).toString():t.target.value="0"))}destroy(){this.removeEventListeners(),this.originalNoValidate||this.form.removeAttribute("novalidate")}}return V});
|