@jdlien/validator 1.0.2 → 1.0.4
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 +46 -3
- package/dist/validator.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Validator
|
|
1
|
+
# Validator - HTML Form Validation Made Easy
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
@@ -162,7 +162,7 @@ You can customize the class(es) that Validator uses to hide the error messages b
|
|
|
162
162
|
|
|
163
163
|
## Color Picker Support
|
|
164
164
|
|
|
165
|
-
If you need to allow a user to pick a color, you can use data-type="color" and the input will be required to be any valid CSS color supported by the browser. This type can also work in conjunction with a native color input. If you do this, you will need to add an input with the name of the data-color input + `-color
|
|
165
|
+
If you need to allow a user to pick a color, you can use data-type="color" and the input will be required to be any valid CSS color supported by the browser. This type can also work in conjunction with a native color input. If you do this, you will need to add an input with `type="color"` and the name of the data-color input + `-color`. This should be inside a linked label which will become the color preview swatch. Such a label should have an ID of the color input's name + `-color-label` so that Validator can change the background to the specified color.
|
|
166
166
|
|
|
167
167
|
A basic example that would work:
|
|
168
168
|
|
|
@@ -241,6 +241,49 @@ const myValidator = new Validator(myForm, {
|
|
|
241
241
|
})
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
+
## Utility Functions
|
|
245
|
+
|
|
246
|
+
Validator includes several utility functions that may be useful in your own code, so they are exported as part of the module.
|
|
247
|
+
If you wish to use these, you may import the functions directly from the module as an object that contains all the functions:
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
import { validatorUtils } from '@jdlien/validator'
|
|
251
|
+
// you could assign the functions you need to more convenient variables
|
|
252
|
+
const { dateFormat, formatDateTime } = validatorUtils
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Here is a list of the utility functions:
|
|
256
|
+
|
|
257
|
+
- **isFormControl**: Determines if an element is an HTML input, select, or textarea element.
|
|
258
|
+
- **isType**: Checks if an element has a type or data-type attribute matching one of the passed values.
|
|
259
|
+
- **momentToFPFormat**: Converts a moment.js-style format string to the flatpickr format.
|
|
260
|
+
- **monthToNumber**: Converts month string or number to a zero-based month number (January == 0).
|
|
261
|
+
- **yearToFull**: Converts a year string or number to a 4-digit year.
|
|
262
|
+
- **parseDate**: Parses a date string or Date object into a Date object.
|
|
263
|
+
- **parseTime**: Parses a time string into an object with hour, minute, and second properties.
|
|
264
|
+
- **parseTimeToString**: Parses a time string into a formatted string.
|
|
265
|
+
- **formatDateTime**: Formats a date string or Date object into a string with a specified format.
|
|
266
|
+
- **parseDateToString**: Parses a date string or Date object into a formatted string with the specified moment.js-style date format.
|
|
267
|
+
- **isDate**: Determines if a value is a valid date.
|
|
268
|
+
- **isDateInRange**: Determines if a date falls within a specified range (either past or future).
|
|
269
|
+
- **isTime**: Determines if a value is a valid time.
|
|
270
|
+
- **isEmail**: Determines if a value is a valid email address.
|
|
271
|
+
- **parseNANPTel**: Parses a North American phone number string into a standardized format.
|
|
272
|
+
- **isNANPTel**: Determines if a value is a valid North American phone number.
|
|
273
|
+
- **parseInteger**: Parses an integer string into a standardized format.
|
|
274
|
+
- **isNumber**: Determines if a value is a valid number.
|
|
275
|
+
- **parseNumber**: Parses a number string into a standardized format.
|
|
276
|
+
- **isInteger**: Determines if a value is a valid integer.
|
|
277
|
+
- **parseUrl**: Parses a URL string into a standardized format.
|
|
278
|
+
- **isUrl**: Determines if a value is a valid URL.
|
|
279
|
+
- **parseZip**: Parses a zip code string into a standardized format.
|
|
280
|
+
- **isZip**: Determines if a value is a valid zip code.
|
|
281
|
+
- **parsePostalCA**: Parses a Canadian postal code string into a standardized format.
|
|
282
|
+
- **isPostalCA**: Determines if a value is a valid Canadian postal code.
|
|
283
|
+
- **isColor**: Determines if a value is a valid color.
|
|
284
|
+
- **parseColor**: Parses a color string into a standardized format.
|
|
285
|
+
- **normalizeValidationResult**: Normalizes a validation result (like a boolean or string) into an object with a valid property and a messages array of strings.
|
|
286
|
+
|
|
244
287
|
## Contributing
|
|
245
288
|
|
|
246
289
|
Install dev dependencies:
|
|
@@ -249,7 +292,7 @@ Install dev dependencies:
|
|
|
249
292
|
npm install
|
|
250
293
|
```
|
|
251
294
|
|
|
252
|
-
|
|
295
|
+
When running Vite you may get an error like
|
|
253
296
|
|
|
254
297
|
```
|
|
255
298
|
Module did not self-register: '...\node_modules\canvas\build\Release\canvas.node'
|
package/dist/validator.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(m,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(m=typeof globalThis<"u"?globalThis:m||self,c(m.Validator={}))})(this,function(m){"use strict";var Q=Object.defineProperty;var X=(m,c,f)=>c in m?Q(m,c,{enumerable:!0,configurable:!0,writable:!0,value:f}):m[c]=f;var d=(m,c,f)=>(X(m,typeof c!="symbol"?c+"":c,f),f);function c(r){return r instanceof HTMLInputElement||r instanceof HTMLSelectElement||r instanceof HTMLTextAreaElement}function f(r,e){typeof e=="string"&&(e=[e]);const t=r.dataset.type||"",s=r.type||"";return!!(e.includes(t)||e.includes(s))}function Z(r){return r.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 L(r){const e=parseInt(r);if(typeof r=="number"||!isNaN(e))return e-1;const t=new Date(`1 ${r} 2000`).getMonth();if(!isNaN(t))return t;const s={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 i in s)if(r.toLowerCase().startsWith(i))return s[i];throw new Error("Invalid month name: "+r)}function b(r){return typeof r=="string"&&(r=parseInt(r.replace(/\D/g,""))),r>99?r:r<(new Date().getFullYear()+20)%100?r+2e3:r+1900}function p(r){if(r instanceof Date)return r;r=r.trim().toLowerCase();let e=0,t=0,s=0,i=0,a=0,n=0;const l=new RegExp(/\d{1,2}\:\d\d(?:\:\d\ds?)?\s?(?:[a|p]m?)?/gi);if(l.test(r)){const h=r.match(l)[0];r=r.replace(h,"").trim();const g=E(h);if(g!==null&&({hour:i,minute:a,second:n}=g),r.length<=2){const M=new Date;return new Date(M.getFullYear(),M.getMonth(),M.getDate(),i,a,n)}}const u=/(^|\b)(mo|tu|we|th|fr|sa|su|lu|mard|mer|jeu|ve|dom)[\w]*\.?/gi;r=r.replace(u,"").trim();const o=new Date(new Date().setHours(0,0,0,0));if(/(now|today)/.test(r))return o;if(r.includes("tomorrow"))return new Date(o.setDate(o.getDate()+1));r.length===8&&(r=r.replace(/(\d\d\d\d)(\d\d)(\d\d)/,"$1-$2-$3")),r.length===6&&(r=r.replace(/(\d\d)(\d\d)(\d\d)/,b(r.slice(0,2))+"-$2-$3"));try{({year:e,month:t,day:s}=j(r))}catch{return new Date("")}return new Date(e,t-1,s,i,a,n)}function j(r){function e(n,l=[null,null,null]){const u=o=>o.filter(h=>!l.includes(h));return n===0||n>31?u(["y"]):n>12?u(["d","y"]):n>=1||n<=12?u(["m","d","y"]):[]}const t=r.split(/[\s-/:.,]+/).filter(n=>n!=="");if(t.length<3){if(r.match(/\d{4}/)!==null)throw new Error("Invalid Date");t.unshift(String(new Date().getFullYear()))}const s={year:0,month:0,day:0};function i(n,l){n==="year"?s.year=b(l):s[n]=l}let a=0;for(;!(s.year&&s.month&&s.day);){e:for(const n of t){if(a++,/^[a-zA-Zé]+$/.test(n)){s.month||i("month",L(n)+1);continue}if(/^'\d\d$/.test(n)||/^\d{3,5}$/.test(n)){s.year||i("year",parseInt(n.replace(/'/,"")));continue}const l=parseInt(n);if(isNaN(l))throw console.error(`not date because ${n} isNaN`),new Error("Invalid Date");const u=e(l,[s.year?"y":null,s.month?"m":null,s.day?"d":null]);if(u.length==1)for(let o=0;o<u.length;o++){if(u[o]==="m"&&!s.month){i("month",l);continue e}if(u[o]==="d"&&!s.day){i("day",l);continue e}if(u[o]==="y"&&!s.year){i("year",l);continue e}}a>3&&(!s.month&&u.includes("m")?i("month",l):!s.day&&u.includes("d")?i("day",l):!s.year&&u.includes("y")&&i("year",l))}if(a>6)throw new Error("Invalid Date")}if(s.year&&s.month&&s.day)return s;throw new Error("Invalid Date")}function E(r){if(r=r.trim().toLowerCase(),r==="now"){const o=new Date;return{hour:o.getHours(),minute:o.getMinutes(),second:o.getSeconds()}}const e=r.match(/(\d{3,4})/);if(e){const o=e[1].length,h=e[1].slice(0,o==3?1:2),g=e[1].slice(-2);r=r.replace(e[1],h+":"+g)}const t=new RegExp(/^(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(t.test(r)){const o=r.match(t);if(o===null)return null;r=o[1]+":"+(o[2]||"00")+(o[3]||"")}const s=new RegExp(/^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(!s.test(r))return null;const i=r.match(s);if(i===null)return null;const a=parseInt(i[1]),n=parseInt(i[2]),l=i[3]?parseInt(i[3]):0,u=i[4];return isNaN(a)||isNaN(n)||isNaN(l)?null:u==="p"&&a<12?{hour:a+12,minute:n,second:l}:u==="a"&&a===12?{hour:0,minute:n,second:l}:a<0||a>23||n<0||n>59||l<0||l>59?null:{hour:a,minute:n,second:l}}function S(r,e="h:mm A"){const t=E(r);if(t){const s=new Date;return s.setHours(t.hour),s.setMinutes(t.minute),s.setSeconds(t.second),s.setMilliseconds(0),y(s,e)}return""}function y(r,e="YYYY-MM-DD"){if(r=p(r),isNaN(r.getTime()))return"";const t={y:r.getFullYear(),M:r.getMonth(),D:r.getDate(),W:r.getDay(),H:r.getHours(),m:r.getMinutes(),s:r.getSeconds(),ms:r.getMilliseconds()},s=(o,h=2)=>(o+"").padStart(h,"0"),i=()=>t.H%12||12,a=o=>o<12?"AM":"PM",n=o=>"January|February|March|April|May|June|July|August|September|October|November|December".split("|")[o];function l(o,h=0){const g="Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|");return h?g[o].slice(0,h):g[o]}const u={YY:String(t.y).slice(-2),YYYY:t.y,M:t.M+1,MM:s(t.M+1),MMMM:n(t.M),MMM:n(t.M).slice(0,3),D:String(t.D),DD:s(t.D),d:String(t.W),dd:l(t.W,2),ddd:l(t.W,3),dddd:l(t.W),H:String(t.H),HH:s(t.H),h:i(),hh:s(i()),A:a(t.H),a:a(t.H).toLowerCase(),m:String(t.m),mm:s(t.m),s:String(t.s),ss:s(t.s),SSS:s(t.ms,3)};return e.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,(o,h)=>h||u[o])}function D(r,e){const t=p(r);return isNaN(t.getTime())?"":((!e||e.length===0)&&(e="YYYY-MMM-DD"),y(t,e))}function C(r){let e=p(r);return e==null?!1:!isNaN(e.getTime())}function x(r,e){return!(e==="past"&&r>new Date||e==="future"&&r.getTime()<new Date().setHours(0,0,0,0))}function H(r){let e=E(r);return e===null?!1:!isNaN(e.hour)&&!isNaN(e.minute)&&!isNaN(e.second)}function A(r){if(r.length>255||!new RegExp(/^.+@.+\.[a-zA-Z0-9]{2,}$/).test(r))return!1;let t="";return t+="^([a-zA-Z0-9!#$%'*+/=?^_`{|}~-]+",t+="(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*",t+="|",t+='"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*"',t+=")@(",t+="(",t+="(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+",t+="[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?",t+=")",t+=")$",new RegExp(t).test(r)}function N(r){return r=r.replace(/^[^2-90]+/g,""),r=r.replace(/(\d\d\d).*?(\d\d\d).*?(\d\d\d\d)(.*)/,"$1-$2-$3$4"),r}function O(r){return/^\d\d\d-\d\d\d-\d\d\d\d$/.test(r)}function v(r){return r.replace(/[^0-9]/g,"")}function _(r){return/^\-?\d*\.?\d*$/.test(r)}function w(r){return r.replace(/[^\-0-9.]/g,"").replace(/(^-)|(-)/g,(e,t)=>t?"-":"").replace(/(\..*)\./g,"$1")}function k(r){return/^\-?\d*$/.test(r)}function $(r){return r=r.trim(),new RegExp("^(?:[a-z+]+:)?//","i").test(r)?r:"https://"+r}function P(r){return new RegExp("^(?:[-a-z+]+:)?//","i").test(r)}function Y(r){return r=r.replace(/[^0-9]/g,"").replace(/(.{5})(.*)/,"$1-$2").trim(),r.length===6&&(r=r.replace(/-/,"")),r}function V(r){return new RegExp(/^\d{5}(-\d{4})?$/).test(r)}function F(r){return r=r.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/(.{3})\s*(.*)/,"$1 $2").trim(),r}function U(r){return new RegExp(/^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$/).test(r)}function T(r){return["transparent","currentColor"].includes(r)?!0:typeof r!="string"||!r.trim()?!1:typeof CSS=="object"&&typeof CSS.supports=="function"?CSS.supports("color",r):G(r)}function G(r){const e=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*\)$/),t=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*\)$/),s=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*\)$/),i=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*\)$/),a=new RegExp(/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i);let n="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 l=new RegExp(`^(${n})$`,"i");return e.test(r)||t.test(r)||s.test(r)||i.test(r)||a.test(r)||l.test(r)}let R=null;const I=new Map;function q(r){if(r=r.trim().toLowerCase(),r==="transparent")return"transparent";if(I.has(r))return I.get(r);R===null&&(R=document.createElement("canvas"),R.willReadFrequently=!0);let e=R.getContext("2d");if(!e)throw new Error("Can't get context from colorCanvas");e.fillStyle=r,e.fillRect(0,0,1,1);let t=e.getImageData(0,0,1,1).data,s="#"+("000000"+(t[0]<<16|t[1]<<8|t[2]).toString(16)).slice(-6);return I.set(r,s),s}function z(r){let e={valid:!1,error:!1,messages:[]};return typeof r=="boolean"?{valid:r,error:!1,messages:[]}:typeof r=="string"?{valid:!1,error:!1,messages:[r]}:(typeof r.valid=="boolean"&&(e.valid=r.valid),typeof r.message=="string"&&(e.messages=[r.message]),typeof r.messages=="string"&&(e.messages=[r.messages]),Array.isArray(r.messages)&&(e.messages=r.messages),r.error===!0&&(e.error=!0),e)}const K=Object.freeze(Object.defineProperty({__proto__:null,formatDateTime:y,isColor:T,isDate:C,isDateInRange:x,isEmail:A,isFormControl:c,isInteger:k,isNANPTel:O,isNumber:_,isPostalCA:U,isTime:H,isType:f,isUrl:P,isZip:V,momentToFPFormat:Z,monthToNumber:L,normalizeValidationResult:z,parseColor:q,parseDate:p,parseDateToString:D,parseInteger:v,parseNANPTel:N,parseNumber:w,parsePostalCA:F,parseTime:E,parseTimeToString:S,parseUrl:$,parseZip:Y,yearToFull:b},Symbol.toStringTag,{value:"Module"}));class W extends Event{constructor(t){super("validationSuccess",{cancelable:!0});d(this,"submitEvent");this.submitEvent=t}}class B extends Event{constructor(t){super("validationError",{cancelable:!0});d(this,"submitEvent");this.submitEvent=t}}class J{constructor(e,t={}){d(this,"form");d(this,"inputs",[]);d(this,"inputErrors",{});d(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_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."});d(this,"debug");d(this,"autoInit");d(this,"preventSubmit",!1);d(this,"hiddenClasses");d(this,"errorMainClasses");d(this,"errorInputClasses");d(this,"dispatchTimeout",0);d(this,"originalNoValidate",!1);d(this,"validationSuccessCallback");d(this,"validationErrorCallback");d(this,"submitHandlerRef",this.submitHandler.bind(this));d(this,"inputInputHandlerRef",this.inputInputHandler.bind(this));d(this,"inputChangeHandlerRef",this.inputChangeHandler.bind(this));d(this,"inputKeydownHandlerRef",this.inputKeydownHandler.bind(this));d(this,"inputHandlers",{number:{parse:w,isValid:_,error:this.messages.ERROR_NUMBER},integer:{parse:v,isValid:k,error:this.messages.ERROR_INTEGER},tel:{parse:N,isValid:O,error:this.messages.ERROR_TEL},email:{parse:e=>e.trim(),isValid:A,error:this.messages.ERROR_EMAIL},zip:{parse:Y,isValid:V,error:this.messages.ERROR_ZIP},postal:{parse:F,isValid:U,error:this.messages.ERROR_POSTAL},url:{parse:$,isValid:P,error:this.messages.ERROR_URL},date:{parse:D,isValid:C,error:this.messages.ERROR_DATE},time:{parse:S,isValid:H,error:this.messages.ERROR_TIME},color:{parse:e=>e.trim().toLowerCase(),isValid:T,error:this.messages.ERROR_COLOR}});d(this,"isSubmitting",!1);if(!e)throw new Error("Validator requires a form to be passed as the first argument.");if(!(e instanceof HTMLFormElement))throw new Error("form argument must be an instance of HTMLFormElement");this.form=e,(e.dataset.preventSubmit===""||e.dataset.preventSubmit)&&(this.preventSubmit=!0),Object.assign(this.messages,t.messages||{}),this.debug=t.debug||!1,this.autoInit=t.autoInit!==!1,this.preventSubmit=t.preventSubmit===!1?!1:this.preventSubmit,this.hiddenClasses=t.hiddenClasses||"hidden opacity-0",this.errorMainClasses=t.errorMainClasses||"m-2 border border-red-500 bg-red-100 p-3 dark:bg-red-900/80 text-center",this.errorInputClasses=t.errorInputClasses||"border-red-600 dark:border-red-500",this.validationSuccessCallback=t.validationSuccessCallback||(()=>{}),this.validationErrorCallback=t.validationErrorCallback||(()=>{}),this.autoInit&&this.init(),new MutationObserver(()=>this.autoInit&&this.init()).observe(e,{childList:!0})}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),this.inputs.forEach(e=>{!e.name&&!e.id&&(e.id=`vl-input-${Math.random().toString(36).slice(2)}`),this.inputErrors[e.name||e.id]=[]}),this.originalNoValidate=this.form.hasAttribute("novalidate"),this.form.setAttribute("novalidate","novalidate"),this.removeEventListeners(),this.addEventListeners()}getErrorEl(e){const t=document.getElementById(e.name+"-error");return t||document.getElementById(e.id+"-error")||null}addErrorMain(e){const t=document.createElement("div");t.id="form-error-main",this.errorMainClasses.split(" ").forEach(s=>{t.classList.add(s)}),e?t.innerHTML=e:t.innerHTML=this.messages.ERROR_MAIN,this.form.appendChild(t)}addInputError(e,t=e.dataset.errorDefault||this.messages.ERROR_GENERIC){const s=e.name||e.id;this.debug&&console.log("Invalid value for "+s+": "+t),s in this.inputErrors||(this.inputErrors[s]=[]),this.inputErrors[s].includes(t)||this.inputErrors[s].push(t)}showInputErrors(e){if(!e||!e.name&&!e.id)return;const t=e.name||e.id,s=t in this.inputErrors?this.inputErrors[t]:[];if(!s.length)return;e.setAttribute("aria-invalid","true"),this.errorInputClasses.split(" ").forEach(a=>{e.classList.add(a)});let i=this.getErrorEl(e);i&&(i.innerHTML=s.join("<br>"),this.hiddenClasses.split(" ").forEach(a=>{i&&i.classList.remove(a)}))}showFormErrors(){if(this.inputs.forEach(e=>this.showInputErrors(e)),Object.values(this.inputErrors).some(e=>Array.isArray(e)&&e.length)){const e=this.form.querySelectorAll("#form-error-main");e.length?e.forEach(t=>{t.innerHTML||(t.innerHTML=this.messages.ERROR_MAIN),this.hiddenClasses.split(" ").forEach(s=>{t.classList.remove(s)})}):this.addErrorMain()}}clearInputErrors(e){this.inputErrors[e.name||e.id]=[],e.removeAttribute("aria-invalid");let t=this.getErrorEl(e);t&&(this.errorInputClasses.split(" ").forEach(s=>{e.classList.remove(s)}),this.hiddenClasses.split(" ").forEach(s=>{t&&t.classList.add(s)}),t.textContent="")}clearFormErrors(){this.form.querySelectorAll("#form-error-main").forEach(e=>{this.hiddenClasses.split(" ").forEach(t=>{e.classList.add(t)})}),this.inputs.forEach(e=>this.clearInputErrors(e))}validateRequired(e){let t=!0;if(e.required&&(e.value===""||e instanceof HTMLInputElement&&["checkbox","radio"].includes(e.type)&&!e.checked))if(e instanceof HTMLInputElement&&["checkbox","radio"].includes(e.type)){let s=!1,i=e.name;const a=this.form.querySelectorAll(`input[name="${i}"]`);if(a.forEach(n=>{if(n instanceof HTMLInputElement&&n.checked===!0){s=!0;return}}),s===!1){t=!1;let n=a.length>1?this.messages.OPTION_REQUIRED:this.messages.CHECKED_REQUIRED;e.dataset.errorDefault&&(n=e.dataset.errorDefault),this.addInputError(e,n)}}else c(e)&&(t=!1,this.addInputError(e,e.dataset.errorDefault||this.messages.ERROR_REQUIRED));return t}validateLength(e){let t=!0;if((e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)&&e.value.length){let s=e.minLength>0?e.minLength:e.dataset.minLength?parseInt(e.dataset.minLength):0,i=e.maxLength>0&&e.maxLength<5e5?e.maxLength:e.dataset.maxLength?parseInt(e.dataset.maxLength):1/0;s>0&&e.value.length<s&&(t=!1,this.addInputError(e,this.messages.ERROR_MINLENGTH.replace("${val}",s.toString()))),e.value.length>i&&(t=!1,this.addInputError(e,this.messages.ERROR_MAXLENGTH.replace("${val}",i.toString())))}return t}validateInputType(e){const t=e.dataset.type||e.type,s=this.inputHandlers[e.type]||this.inputHandlers[t];if(s){const i=e.dataset.dateFormat||e.dataset.timeFormat,a=s.parse(e.value,i),n=["date","time","datetime-local","month","week"];if(a.length&&!n.includes(e.type)&&(e.value=a),!s.isValid(e.value))return this.addInputError(e,s.error),!1}return!0}validateDateRange(e){if(e.dataset.dateRange){const t=e.dataset.dateRange,s=p(e.value);if(!isNaN(s.getTime())&&!x(s,t)){let i=e.dataset.errorDefault||this.messages.ERROR_DATE_RANGE;return t==="past"?i=this.messages.ERROR_DATE_PAST:t==="future"&&(i=this.messages.ERROR_DATE_FUTURE),this.addInputError(e,i),!1}}return!0}validatePattern(e){const t=e.dataset.pattern||e instanceof HTMLInputElement&&e.pattern||null;return t&&!new RegExp(t).test(e.value)?(this.addInputError(e),!1):!0}async validateCustom(e){const t=e.dataset.validation;if(!t||typeof t!="string")return!0;const s=window[t];if(!s||typeof s!="function")return!0;let i;try{i=await Promise.resolve(s(e.value)),i=z(i)}catch{return this.addInputError(e,this.messages.ERROR_CUSTOM_VALIDATION),!1}const a=i.messages.join("<br>")||this.messages.ERROR_CUSTOM_VALIDATION;return i.valid||this.addInputError(e,a),i.valid}async validateInput(e){if(!(e instanceof HTMLInputElement)||!e.value.length)return!0;let t=!0;return t=this.validateInputType(e)&&t,t=this.validateDateRange(e)&&t,t=this.validatePattern(e)&&t,t=await this.validateCustom(e)&&t,t}async validate(e){let t=!0;for(const s of this.inputs)t=this.validateRequired(s)&&t,t=this.validateLength(s)&&t,t=await this.validateInput(s)&&t;return t}async submitHandler(e){if(this.isSubmitting)return;e.preventDefault(),this.clearFormErrors();let t=await this.validate(e);this.showFormErrors();const s=new W(e),i=new B(e);t?(this.form.dispatchEvent(s),this.validationSuccessCallback&&this.validationSuccessCallback(e)):(this.form.dispatchEvent(i),this.validationErrorCallback&&this.validationErrorCallback(e)),t&&!this.preventSubmit&&(this.isSubmitting=!0,s.defaultPrevented||this.form.submit(),this.isSubmitting=!1)}async inputChangeHandler(e){e.target instanceof HTMLInputElement&&(this.clearInputErrors(e.target),await this.validateInput(e.target),this.showInputErrors(e.target))}inputInputHandler(e){const t=e.target;f(t,"integer")&&(t.value=v(t.value)),t.type!=="number"&&f(t,["number","float","decimal"])&&(t.value=w(t.value)),f(t,"color")&&this.syncColorInput(e)}syncColorInput(e){let t=e.target,s=t;t.type==="color"&&(s=this.form.querySelector(`#${t.id.replace(/-color/,"")}`));let i=this.form.querySelector(`#${s.id}-color-label`);if((t.dataset.type||"")==="color"){let a=this.form.querySelector(`input#${t.id}-color`);if(!a||!T(t.value))return;a.value=q(t.value)}t.type==="color"&&(s.value=t.value),i&&(i.style.backgroundColor=t.value),clearTimeout(this.dispatchTimeout),this.dispatchTimeout=window.setTimeout(()=>{s.dispatchEvent(new Event("change",{bubbles:!0}))},200)}inputKeydownHandler(e){e.target instanceof HTMLInputElement&&f(e.target,"integer")&&(e.key==="ArrowUp"?(e.preventDefault(),e.target.value===""&&(e.target.value="0"),e.target.value=(parseInt(e.target.value)+1).toString()):e.key==="ArrowDown"&&(parseInt(e.target.value)>0?e.target.value=(parseInt(e.target.value)-1).toString():e.target.value="0"))}destroy(){this.removeEventListeners(),this.originalNoValidate||this.form.removeAttribute("novalidate")}}m.default=J,m.utils=K,Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
1
|
+
(function(m,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(m=typeof globalThis<"u"?globalThis:m||self,c(m.Validator={}))})(this,function(m){"use strict";var Q=Object.defineProperty;var X=(m,c,f)=>c in m?Q(m,c,{enumerable:!0,configurable:!0,writable:!0,value:f}):m[c]=f;var d=(m,c,f)=>(X(m,typeof c!="symbol"?c+"":c,f),f);function c(r){return r instanceof HTMLInputElement||r instanceof HTMLSelectElement||r instanceof HTMLTextAreaElement}function f(r,e){typeof e=="string"&&(e=[e]);const t=r.dataset.type||"",i=r.type||"";return!!(e.includes(t)||e.includes(i))}function Z(r){return r.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 L(r){const e=parseInt(r);if(typeof r=="number"||!isNaN(e))return e-1;const t=new Date(`1 ${r} 2000`).getMonth();if(!isNaN(t))return t;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 s in i)if(r.toLowerCase().startsWith(s))return i[s];throw new Error("Invalid month name: "+r)}function b(r){return typeof r=="string"&&(r=parseInt(r.replace(/\D/g,""))),r>99?r:r<(new Date().getFullYear()+20)%100?r+2e3:r+1900}function p(r){if(r instanceof Date)return r;r=r.trim().toLowerCase();let e=0,t=0,i=0,s=0,a=0,n=0;const l=new RegExp(/\d{1,2}\:\d\d(?:\:\d\ds?)?\s?(?:[a|p]m?)?/gi);if(l.test(r)){const h=r.match(l)[0];r=r.replace(h,"").trim();const g=E(h);if(g!==null&&({hour:s,minute:a,second:n}=g),r.length<=2){const M=new Date;return new Date(M.getFullYear(),M.getMonth(),M.getDate(),s,a,n)}}const u=/(^|\b)(mo|tu|we|th|fr|sa|su|lu|mard|mer|jeu|ve|dom)[\w]*\.?/gi;r=r.replace(u,"").trim();const o=new Date(new Date().setHours(0,0,0,0));if(/(now|today)/.test(r))return o;if(r.includes("tomorrow"))return new Date(o.setDate(o.getDate()+1));r.length===8&&(r=r.replace(/(\d\d\d\d)(\d\d)(\d\d)/,"$1-$2-$3")),r.length===6&&(r=r.replace(/(\d\d)(\d\d)(\d\d)/,b(r.slice(0,2))+"-$2-$3"));try{({year:e,month:t,day:i}=j(r))}catch{return new Date("")}return new Date(e,t-1,i,s,a,n)}function j(r){function e(n,l=[null,null,null]){const u=o=>o.filter(h=>!l.includes(h));return n===0||n>31?u(["y"]):n>12?u(["d","y"]):n>=1||n<=12?u(["m","d","y"]):[]}const t=r.split(/[\s-/:.,]+/).filter(n=>n!=="");if(t.length<3){if(r.match(/\d{4}/)!==null)throw new Error("Invalid Date");t.unshift(String(new Date().getFullYear()))}const i={year:0,month:0,day:0};function s(n,l){n==="year"?i.year=b(l):i[n]=l}let a=0;for(;!(i.year&&i.month&&i.day);){e:for(const n of t){if(a++,/^[a-zA-Zé]+$/.test(n)){i.month||s("month",L(n)+1);continue}if(/^'\d\d$/.test(n)||/^\d{3,5}$/.test(n)){i.year||s("year",parseInt(n.replace(/'/,"")));continue}const l=parseInt(n);if(isNaN(l))throw console.error(`not date because ${n} isNaN`),new Error("Invalid Date");const u=e(l,[i.year?"y":null,i.month?"m":null,i.day?"d":null]);if(u.length==1)for(let o=0;o<u.length;o++){if(u[o]==="m"&&!i.month){s("month",l);continue e}if(u[o]==="d"&&!i.day){s("day",l);continue e}if(u[o]==="y"&&!i.year){s("year",l);continue e}}a>3&&(!i.month&&u.includes("m")?s("month",l):!i.day&&u.includes("d")?s("day",l):!i.year&&u.includes("y")&&s("year",l))}if(a>6)throw new Error("Invalid Date")}if(i.year&&i.month&&i.day)return i;throw new Error("Invalid Date")}function E(r){if(r=r.trim().toLowerCase(),r==="now"){const o=new Date;return{hour:o.getHours(),minute:o.getMinutes(),second:o.getSeconds()}}const e=r.match(/(\d{3,4})/);if(e){const o=e[1].length,h=e[1].slice(0,o==3?1:2),g=e[1].slice(-2);r=r.replace(e[1],h+":"+g)}const t=new RegExp(/^(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(t.test(r)){const o=r.match(t);if(o===null)return null;r=o[1]+":"+(o[2]||"00")+(o[3]||"")}const i=new RegExp(/^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(!i.test(r))return null;const s=r.match(i);if(s===null)return null;const a=parseInt(s[1]),n=parseInt(s[2]),l=s[3]?parseInt(s[3]):0,u=s[4];return isNaN(a)||isNaN(n)||isNaN(l)?null:u==="p"&&a<12?{hour:a+12,minute:n,second:l}:u==="a"&&a===12?{hour:0,minute:n,second:l}:a<0||a>23||n<0||n>59||l<0||l>59?null:{hour:a,minute:n,second:l}}function S(r,e="h:mm A"){const t=E(r);if(t){const i=new Date;return i.setHours(t.hour),i.setMinutes(t.minute),i.setSeconds(t.second),i.setMilliseconds(0),y(i,e)}return""}function y(r,e="YYYY-MM-DD"){if(r=p(r),isNaN(r.getTime()))return"";const t={y:r.getFullYear(),M:r.getMonth(),D:r.getDate(),W:r.getDay(),H:r.getHours(),m:r.getMinutes(),s:r.getSeconds(),ms:r.getMilliseconds()},i=(o,h=2)=>(o+"").padStart(h,"0"),s=()=>t.H%12||12,a=o=>o<12?"AM":"PM",n=o=>"January|February|March|April|May|June|July|August|September|October|November|December".split("|")[o];function l(o,h=0){const g="Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|");return h?g[o].slice(0,h):g[o]}const u={YY:String(t.y).slice(-2),YYYY:t.y,M:t.M+1,MM:i(t.M+1),MMMM:n(t.M),MMM:n(t.M).slice(0,3),D:String(t.D),DD:i(t.D),d:String(t.W),dd:l(t.W,2),ddd:l(t.W,3),dddd:l(t.W),H:String(t.H),HH:i(t.H),h:s(),hh:i(s()),A:a(t.H),a:a(t.H).toLowerCase(),m:String(t.m),mm:i(t.m),s:String(t.s),ss:i(t.s),SSS:i(t.ms,3)};return e.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,(o,h)=>h||u[o])}function D(r,e){const t=p(r);return isNaN(t.getTime())?"":((!e||e.length===0)&&(e="YYYY-MMM-DD"),y(t,e))}function C(r){let e=p(r);return e==null?!1:!isNaN(e.getTime())}function x(r,e){return!(e==="past"&&r>new Date||e==="future"&&r.getTime()<new Date().setHours(0,0,0,0))}function H(r){let e=E(r);return e===null?!1:!isNaN(e.hour)&&!isNaN(e.minute)&&!isNaN(e.second)}function A(r){if(r.length>255||!new RegExp(/^.+@.+\.[a-zA-Z0-9]{2,}$/).test(r))return!1;let t="";return t+="^([a-zA-Z0-9!#$%'*+/=?^_`{|}~-]+",t+="(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*",t+="|",t+='"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*"',t+=")@(",t+="(",t+="(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+",t+="[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?",t+=")",t+=")$",new RegExp(t).test(r)}function N(r){return r=r.replace(/^[^2-90]+/g,""),r=r.replace(/(\d\d\d).*?(\d\d\d).*?(\d\d\d\d)(.*)/,"$1-$2-$3$4"),r}function O(r){return/^\d\d\d-\d\d\d-\d\d\d\d$/.test(r)}function v(r){return r.replace(/[^0-9]/g,"")}function _(r){return/^\-?\d*\.?\d*$/.test(r)}function w(r){return r.replace(/[^\-0-9.]/g,"").replace(/(^-)|(-)/g,(e,t)=>t?"-":"").replace(/(\..*)\./g,"$1")}function k(r){return/^\-?\d*$/.test(r)}function $(r){return r=r.trim(),new RegExp("^(?:[a-z+]+:)?//","i").test(r)?r:"https://"+r}function P(r){return new RegExp("^(?:[-a-z+]+:)?//","i").test(r)}function Y(r){return r=r.replace(/[^0-9]/g,"").replace(/(.{5})(.*)/,"$1-$2").trim(),r.length===6&&(r=r.replace(/-/,"")),r}function V(r){return new RegExp(/^\d{5}(-\d{4})?$/).test(r)}function U(r){return r=r.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/(.{3})\s*(.*)/,"$1 $2").trim(),r}function F(r){return new RegExp(/^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$/).test(r)}function T(r){return["transparent","currentColor"].includes(r)?!0:typeof r!="string"||!r.trim()?!1:typeof CSS=="object"&&typeof CSS.supports=="function"?CSS.supports("color",r):G(r)}function G(r){const e=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*\)$/),t=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*\)$/),s=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*\)$/),a=new RegExp(/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i);let n="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 l=new RegExp(`^(${n})$`,"i");return e.test(r)||t.test(r)||i.test(r)||s.test(r)||a.test(r)||l.test(r)}let R=null;const I=new Map;function q(r){if(r=r.trim().toLowerCase(),r==="transparent")return"transparent";if(I.has(r))return I.get(r);R===null&&(R=document.createElement("canvas"),R.willReadFrequently=!0);let e=R.getContext("2d");if(!e)throw new Error("Can't get context from colorCanvas");e.fillStyle=r,e.fillRect(0,0,1,1);let t=e.getImageData(0,0,1,1).data,i="#"+("000000"+(t[0]<<16|t[1]<<8|t[2]).toString(16)).slice(-6);return I.set(r,i),i}function z(r){let e={valid:!1,error:!1,messages:[]};return typeof r=="boolean"?{valid:r,error:!1,messages:[]}:typeof r=="string"?{valid:!1,error:!1,messages:[r]}:(typeof r.valid=="boolean"&&(e.valid=r.valid),typeof r.message=="string"&&(e.messages=[r.message]),typeof r.messages=="string"&&(e.messages=[r.messages]),Array.isArray(r.messages)&&(e.messages=r.messages),r.error===!0&&(e.error=!0),e)}const K=Object.freeze(Object.defineProperty({__proto__:null,formatDateTime:y,isColor:T,isDate:C,isDateInRange:x,isEmail:A,isFormControl:c,isInteger:k,isNANPTel:O,isNumber:_,isPostalCA:F,isTime:H,isType:f,isUrl:P,isZip:V,momentToFPFormat:Z,monthToNumber:L,normalizeValidationResult:z,parseColor:q,parseDate:p,parseDateToString:D,parseInteger:v,parseNANPTel:N,parseNumber:w,parsePostalCA:U,parseTime:E,parseTimeToString:S,parseUrl:$,parseZip:Y,yearToFull:b},Symbol.toStringTag,{value:"Module"}));class W extends Event{constructor(t){super("validationSuccess",{cancelable:!0});d(this,"submitEvent");this.submitEvent=t}}class B extends Event{constructor(t){super("validationError",{cancelable:!0});d(this,"submitEvent");this.submitEvent=t}}class J{constructor(e,t={}){d(this,"form");d(this,"inputs",[]);d(this,"inputErrors",{});d(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_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."});d(this,"debug");d(this,"autoInit");d(this,"preventSubmit",!1);d(this,"hiddenClasses");d(this,"errorMainClasses");d(this,"errorInputClasses");d(this,"dispatchTimeout",0);d(this,"originalNoValidate",!1);d(this,"validationSuccessCallback");d(this,"validationErrorCallback");d(this,"submitHandlerRef",this.submitHandler.bind(this));d(this,"inputInputHandlerRef",this.inputInputHandler.bind(this));d(this,"inputChangeHandlerRef",this.inputChangeHandler.bind(this));d(this,"inputKeydownHandlerRef",this.inputKeydownHandler.bind(this));d(this,"inputHandlers",{number:{parse:w,isValid:_,error:this.messages.ERROR_NUMBER},integer:{parse:v,isValid:k,error:this.messages.ERROR_INTEGER},tel:{parse:N,isValid:O,error:this.messages.ERROR_TEL},email:{parse:e=>e.trim(),isValid:A,error:this.messages.ERROR_EMAIL},zip:{parse:Y,isValid:V,error:this.messages.ERROR_ZIP},postal:{parse:U,isValid:F,error:this.messages.ERROR_POSTAL},url:{parse:$,isValid:P,error:this.messages.ERROR_URL},date:{parse:D,isValid:C,error:this.messages.ERROR_DATE},time:{parse:S,isValid:H,error:this.messages.ERROR_TIME},color:{parse:e=>e.trim().toLowerCase(),isValid:T,error:this.messages.ERROR_COLOR}});d(this,"isSubmitting",!1);if(!e)throw new Error("Validator requires a form to be passed as the first argument.");if(!(e instanceof HTMLFormElement))throw new Error("form argument must be an instance of HTMLFormElement");this.form=e,(e.dataset.preventSubmit===""||e.dataset.preventSubmit)&&(this.preventSubmit=!0),Object.assign(this.messages,t.messages||{}),this.debug=t.debug||!1,this.autoInit=t.autoInit!==!1,this.preventSubmit=t.preventSubmit===!1?!1:this.preventSubmit,this.hiddenClasses=t.hiddenClasses||"hidden opacity-0",this.errorMainClasses=t.errorMainClasses||"m-2 border border-red-500 bg-red-100 p-3 dark:bg-red-900/80 text-center",this.errorInputClasses=t.errorInputClasses||"border-red-600 dark:border-red-500",this.validationSuccessCallback=t.validationSuccessCallback||(()=>{}),this.validationErrorCallback=t.validationErrorCallback||(()=>{}),this.autoInit&&this.init(),new MutationObserver(()=>this.autoInit&&this.init()).observe(e,{childList:!0})}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),this.inputs.forEach(e=>{!e.name&&!e.id&&(e.id=`vl-input-${Math.random().toString(36).slice(2)}`),this.inputErrors[e.name||e.id]=[]}),this.originalNoValidate=this.form.hasAttribute("novalidate"),this.form.setAttribute("novalidate","novalidate"),this.removeEventListeners(),this.addEventListeners()}getErrorEl(e){const t=document.getElementById(e.name+"-error");return t||document.getElementById(e.id+"-error")||null}addErrorMain(e){const t=document.createElement("div");t.id="form-error-main",this.errorMainClasses.split(" ").forEach(i=>{t.classList.add(i)}),e?t.innerHTML=e:t.innerHTML=this.messages.ERROR_MAIN,this.form.appendChild(t)}addInputError(e,t=e.dataset.errorDefault||this.messages.ERROR_GENERIC){const i=e.name||e.id;this.debug&&console.log("Invalid value for "+i+": "+t),i in this.inputErrors||(this.inputErrors[i]=[]),this.inputErrors[i].includes(t)||this.inputErrors[i].push(t)}showInputErrors(e){if(!e||!e.name&&!e.id)return;const t=e.name||e.id,i=t in this.inputErrors?this.inputErrors[t]:[];if(!i.length)return;e.setAttribute("aria-invalid","true"),this.errorInputClasses.split(" ").forEach(a=>{e.classList.add(a)});let s=this.getErrorEl(e);s&&(s.innerHTML=i.join("<br>"),this.hiddenClasses.split(" ").forEach(a=>{s&&s.classList.remove(a)}))}showFormErrors(){if(this.inputs.forEach(e=>this.showInputErrors(e)),Object.values(this.inputErrors).some(e=>Array.isArray(e)&&e.length)){const e=this.form.querySelectorAll("#form-error-main");e.length?e.forEach(t=>{t.innerHTML||(t.innerHTML=this.messages.ERROR_MAIN),this.hiddenClasses.split(" ").forEach(i=>{t.classList.remove(i)})}):this.addErrorMain()}}clearInputErrors(e){this.inputErrors[e.name||e.id]=[],e.removeAttribute("aria-invalid");let t=this.getErrorEl(e);t&&(this.errorInputClasses.split(" ").forEach(i=>{e.classList.remove(i)}),this.hiddenClasses.split(" ").forEach(i=>{t&&t.classList.add(i)}),t.textContent="")}clearFormErrors(){this.form.querySelectorAll("#form-error-main").forEach(e=>{this.hiddenClasses.split(" ").forEach(t=>{e.classList.add(t)})}),this.inputs.forEach(e=>this.clearInputErrors(e))}validateRequired(e){let t=!0;if(e.required&&(e.value===""||e instanceof HTMLInputElement&&["checkbox","radio"].includes(e.type)&&!e.checked))if(e instanceof HTMLInputElement&&["checkbox","radio"].includes(e.type)){let i=!1,s=e.name;const a=this.form.querySelectorAll(`input[name="${s}"]`);if(a.forEach(n=>{if(n instanceof HTMLInputElement&&n.checked===!0){i=!0;return}}),i===!1){t=!1;let n=a.length>1?this.messages.OPTION_REQUIRED:this.messages.CHECKED_REQUIRED;e.dataset.errorDefault&&(n=e.dataset.errorDefault),this.addInputError(e,n)}}else c(e)&&(t=!1,this.addInputError(e,e.dataset.errorDefault||this.messages.ERROR_REQUIRED));return t}validateLength(e){let t=!0;if((e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)&&e.value.length){let i=e.minLength>0?e.minLength:e.dataset.minLength?parseInt(e.dataset.minLength):0,s=e.maxLength>0&&e.maxLength<5e5?e.maxLength:e.dataset.maxLength?parseInt(e.dataset.maxLength):1/0;i>0&&e.value.length<i&&(t=!1,this.addInputError(e,this.messages.ERROR_MINLENGTH.replace("${val}",i.toString()))),e.value.length>s&&(t=!1,this.addInputError(e,this.messages.ERROR_MAXLENGTH.replace("${val}",s.toString())))}return t}validateInputType(e){const t=e.dataset.type||e.type,i=this.inputHandlers[e.type]||this.inputHandlers[t];if(i){const s=e.dataset.dateFormat||e.dataset.timeFormat,a=i.parse(e.value,s),n=["date","time","datetime-local","month","week"];if(a.length&&!n.includes(e.type)&&(e.value=a),!i.isValid(e.value))return this.addInputError(e,i.error),!1}return!0}validateDateRange(e){if(e.dataset.dateRange){const t=e.dataset.dateRange,i=p(e.value);if(!isNaN(i.getTime())&&!x(i,t)){let s=e.dataset.errorDefault||this.messages.ERROR_DATE_RANGE;return t==="past"?s=this.messages.ERROR_DATE_PAST:t==="future"&&(s=this.messages.ERROR_DATE_FUTURE),this.addInputError(e,s),!1}}return!0}validatePattern(e){const t=e.dataset.pattern||e instanceof HTMLInputElement&&e.pattern||null;return t&&!new RegExp(t).test(e.value)?(this.addInputError(e),!1):!0}async validateCustom(e){const t=e.dataset.validation;if(!t||typeof t!="string")return!0;const i=window[t];if(!i||typeof i!="function")return!0;let s;try{s=await Promise.resolve(i(e.value)),s=z(s)}catch{return this.addInputError(e,this.messages.ERROR_CUSTOM_VALIDATION),!1}const a=s.messages.join("<br>")||this.messages.ERROR_CUSTOM_VALIDATION;return s.valid||this.addInputError(e,a),s.valid}async validateInput(e){if(!(e instanceof HTMLInputElement)||!e.value.length)return!0;let t=!0;return t=this.validateInputType(e)&&t,t=this.validateDateRange(e)&&t,t=this.validatePattern(e)&&t,t=await this.validateCustom(e)&&t,t}async validate(e){let t=!0;for(const i of this.inputs)t=this.validateRequired(i)&&t,t=this.validateLength(i)&&t,t=await this.validateInput(i)&&t;return t}async submitHandler(e){if(this.isSubmitting)return;e.preventDefault(),this.clearFormErrors();let t=await this.validate(e);this.showFormErrors();const i=new W(e),s=new B(e);t?(this.form.dispatchEvent(i),this.validationSuccessCallback&&this.validationSuccessCallback(e)):(this.form.dispatchEvent(s),this.validationErrorCallback&&this.validationErrorCallback(e)),t&&!this.preventSubmit&&(this.isSubmitting=!0,i.defaultPrevented||this.form.submit(),this.isSubmitting=!1)}async inputChangeHandler(e){e.target instanceof HTMLInputElement&&(this.clearInputErrors(e.target),await this.validateInput(e.target),this.showInputErrors(e.target))}inputInputHandler(e){const t=e.target;f(t,"integer")&&(t.value=v(t.value)),t.type!=="number"&&f(t,["number","float","decimal"])&&(t.value=w(t.value)),f(t,"color")&&this.syncColorInput(e)}syncColorInput(e){let t=e.target,i=t;t.type==="color"&&(i=this.form.querySelector(`#${t.id.replace(/-color/,"")}`));let s=this.form.querySelector(`#${i.id}-color-label`);if((t.dataset.type||"")==="color"){let a=this.form.querySelector(`input#${t.id}-color`);if(!a||!T(t.value))return;a.value=q(t.value)}t.type==="color"&&(i.value=t.value),s&&(s.style.backgroundColor=t.value),clearTimeout(this.dispatchTimeout),this.dispatchTimeout=window.setTimeout(()=>{i.dispatchEvent(new Event("change",{bubbles:!0}))},200)}inputKeydownHandler(e){e.target instanceof HTMLInputElement&&f(e.target,"integer")&&(e.key==="ArrowUp"?(e.preventDefault(),e.target.value===""&&(e.target.value="0"),e.target.value=(parseInt(e.target.value)+1).toString()):e.key==="ArrowDown"&&(parseInt(e.target.value)>0?e.target.value=(parseInt(e.target.value)-1).toString():e.target.value="0"))}destroy(){this.removeEventListeners(),this.originalNoValidate||this.form.removeAttribute("novalidate")}}m.default=J,m.validatorUtils=K,Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|