form-father 0.1.0 → 0.1.1

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/FormFather.min.js CHANGED
@@ -1,2 +1,2 @@
1
- var FormFather=function(){"use strict";function e(e,t,r,o){return new(r||(r=Promise))((function(n,s){function i(e){try{a(o.next(e))}catch(e){s(e)}}function l(e){try{a(o.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?n(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,l)}a((o=o.apply(e,t||[])).next())}))}function t(e){const t="FORM"===e.tagName?Array.from(e.elements):Array.from(e.querySelectorAll("input, select, textarea, button")),r=new FormData;return t.forEach((e=>{if(!(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement||e instanceof HTMLButtonElement))return;if(!e.name||e.hasAttribute("data-no-serialize"))return;const{name:t,type:o}=e;if("file"===o)if("true"===e.getAttribute("multiple")){const o=e.files;if(o)for(let e=0;e<o.length;e++)r.append(`${t}[${e}]`,o[e])}else{const o=e.files;o&&o[0]&&r.append(t,o[0])}else{let n;if("select-one"===o||"select-multiple"===o){const s=e;if("select-multiple"===o){Array.from(s.selectedOptions).map((e=>e.value)).forEach(((e,o)=>{r.append(`${t}[${o}]`,e)}))}else n=s.value,n&&r.append(t,n)}else if("tel"===o)n=e.value.split(/[\s()-]/).join("").replace(/^8/,"+7");else if("checkbox"===o||"radio"===o){if(!e.checked)return;n=e.value}else if("date"===o){const t=e.getAttribute("data-date-format");n=t?function(e,t){const r=new Date(e),o=e=>e.toString().padStart(2,"0"),n=o(r.getDate()),s=o(r.getMonth()+1),i=r.getFullYear().toString();return t.replace("dd",n).replace("mm",s).replace("yyyy",i)}(e.value,t):e.value}else n=e.value;n&&"select-one"!==o&&"select-multiple"!==o&&r.append(t,n)}})),r}var r;"function"==typeof SuppressedError&&SuppressedError;const o=Symbol.for("FormFather.validators"),n=null!==(r=globalThis[o])&&void 0!==r?r:globalThis[o]=new Map;function s(e,t,r,{override:o=!1}={}){!n.has(e)||o?n.set(e,{fn:t,defaultMessage:r}):console.warn(`[FormFather] Validator "${e}" already exists; pass { override: true } to replace`)}const i=e=>n.get(e);s("required",(e=>e.trim().length>0),"Пустое значение"),s("email",(e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)),"Неверный формат"),s("tel",(e=>/^\+7\d{10}$/.test(e)),"Неверный формат"),s("url",(e=>/^(https?:\/\/).+\..+/.test(e)),"Неверный формат"),s("not-numbers",(e=>!/[0-9]/.test(e)),"Неверный формат");class l{constructor(e,t){this.$submit=null,this.waitResponse=!1,this.inputs=null,this.$licensesCheckbox=null,this.$el=e,this.options=t;this.config=Object.assign({},{onSubmit:()=>{},onResponse:()=>{},onResponseSuccess:()=>{},onResponseUnsuccess:()=>{},customTypeError:null,loaderColor:"#fff",showLoaderButton:!0,scrollToFirstErroredInput:!0,logging:!1,inputSelector:".input",inputWrapperSelector:".input-primary"},l.defaultParams,t),this.$el?(this.$submit=this.$el.querySelector('input[type="submit"], button[type="submit"]'),this.isCorrectArguments()&&this.initialization()):console.warn("Empty $el")}getOptions(){return this.options}static setDefaultParams(e){this.defaultParams=Object.assign(Object.assign({},this.defaultParams),e)}initialization(){this.inputs=this.$el.querySelectorAll(this.config.inputSelector),this.$licensesCheckbox=this.$el.querySelector('input[data-input-name="user-consent"]'),this.$licensesCheckbox&&(this.$licensesCheckbox.checked?this.enableSubmit():this.disableSubmit(),this.$licensesCheckbox.addEventListener("change",(()=>{this.$licensesCheckbox.checked?this.enableSubmit():this.disableSubmit()})));const r=()=>e(this,void 0,void 0,(function*(){var e;const r=this.$el.getAttribute("action")||"",o=(null===(e=this.$el.getAttribute("method"))||void 0===e?void 0:e.toUpperCase())||"POST",n=this.$el.getAttribute("enctype")||"application/x-www-form-urlencoded";let s=null,i={};const l=t(this.$el);let a={};if(l.forEach(((e,t)=>{a[t]=e})),this.config.logging)for(const e of l.keys())console.log(l.get(e));switch("function"==typeof this.config.wrapData&&(a=this.config.wrapData(a)),n){case"application/x-www-form-urlencoded":s=new URLSearchParams(t(this.$el)).toString(),i["Content-Type"]="application/x-www-form-urlencoded";break;case"multipart/form-data":s=t(this.$el);break;case"text/plain":s=Array.from(t(this.$el)).map((([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`)).join("\n"),i["Content-Type"]="text/plain";break;case"application/json":s=JSON.stringify(a),i["Content-Type"]="application/json";break;default:console.warn(`Неизвестный enctype: ${n}. Используется application/x-www-form-urlencoded.`),s=new URLSearchParams(t(this.$el)).toString(),i["Content-Type"]="application/x-www-form-urlencoded"}return fetch(r,{method:o,body:s,headers:i})})),o=()=>e(this,void 0,void 0,(function*(){var e,t,o,n,s,i,l,a;if(!this.waitResponse){!0===this.config.showLoaderButton&&this.showLoader(),null===(t=(e=this.config).onSubmit)||void 0===t||t.call(e,this),this.waitResponse=!0;const c=yield r(),u=yield c.json();if(this.waitResponse=!1,!0===this.config.showLoaderButton&&this.hideLoader(),null===(n=(o=this.config).onResponse)||void 0===n||n.call(o,u,this),200===c.status)if(function(e){if(Object.prototype.hasOwnProperty.call(e,"redirect-url")&&(window.location.href=e["redirect-url"]),Object.prototype.hasOwnProperty.call(e,"reload")&&!0===e.reload&&window.location.reload(),Object.prototype.hasOwnProperty.call(e,"error-toast")){const t=document.querySelector('[data-toast-name="formErrorToast"]');if(t){const r=t.querySelector(".toast__text");r&&(r.textContent=e["error-toast"],window.Toast.showToast("formErrorToast",{removeAfterClose:!1}))}}}(u),!0===u.success)null===(i=(s=this.config).onResponseSuccess)||void 0===i||i.call(s,u,this);else if(null===(a=(l=this.config).onResponseUnsuccess)||void 0===a||a.call(l,u,this),!0===u.error&&(u["error-msg"]&&this.showErrorForm(u["error-msg"]),u.errors)){const e=[];u.errors.forEach((t=>{const r=this.$el.querySelector(`input[name="${t.name}"]`);r?(e.push(r),this.showError(r,t["error-msg"])):console.warn(`Не найдено поле с именем: ${t.name}, для вывода ошибки: ${t["error-msg"]}`)})),!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(e)}}}));this.$el.addEventListener("submit",(t=>e(this,void 0,void 0,(function*(){t.preventDefault();(yield this.validate())&&(!this.$licensesCheckbox||this.$licensesCheckbox&&this.$licensesCheckbox.checked)&&o()}))))}showError(e,t){(function(e,t){if(null==e)return null;let r=e;for(;r;){if(r.matches(t))return r;r=r.parentElement}return null})(e,this.config.inputWrapperSelector).showError(t)}showLoader(){var e;const t=`\n\t\t\t<svg height="38" viewBox="0 0 38 38" width="38" xmlns="http://www.w3.org/2000/svg">\n\t\t\t\t<defs>\n\t\t\t\t<linearGradient id="form-father-loader" x1="8.042%" x2="65.682%" y1="0%" y2="23.865%">\n\t\t\t\t\t<stop offset="0%" stop-color="${this.config.loaderColor}" stop-opacity="0"/>\n\t\t\t\t\t<stop offset="63.146%" stop-color="${this.config.loaderColor}" stop-opacity=".631"/>\n\t\t\t\t\t<stop offset="100%" stop-color="${this.config.loaderColor}"/>\n\t\t\t\t</linearGradient>\n\t\t\t\t</defs>\n\t\t\t\t<g fill-rule="evenodd" fill="none">\n\t\t\t\t<g transform="translate(1 1)">\n\t\t\t\t\t<path d="M36 18c0-9.94-8.06-18-18-18" id="Oval-2" stroke-width="5" stroke="url(#form-father-loader)"></path>\n\t\t\t\t\t<circle cx="36" cy="18" fill="${this.config.loaderColor}" r="1"></circle>\n\t\t\t\t</g>\n\t\t\t\t</g>\n\t\t\t</svg>\n\t\t`,r=document.createElement("span");r.innerHTML=t,r.className="button__loader",null===(e=this.$submit)||void 0===e||e.insertAdjacentElement("afterbegin",r),requestAnimationFrame((()=>{r.setAttribute("data-showed","")}))}hideLoader(){var e,t;null===(e=this.$submit)||void 0===e||e.classList.remove("button--loading");const r=null===(t=this.$submit)||void 0===t?void 0:t.querySelector(".button__loader");r&&(r.classList.remove("active"),r.removeAttribute("data-showed"),setTimeout((()=>{r.remove()}),250))}hideError(e){const t=e.parentElement;t&&t.classList.contains("input__wrapper")&&(t.getAttribute("data-type-error"),t.classList.remove("input__wrapper--error"))}scrollToFirstErroredInput(e){if(e.length>0){const t=Array.from(this.$el.querySelectorAll("input"));let r=null,o=1/0;if(e.forEach((e=>{const n=t.findIndex((t=>t===e));n<o&&(o=n,r=e)})),r){const e=r.getBoundingClientRect(),t=window.pageYOffset||document.documentElement.scrollTop,o=e.top+t-window.innerHeight/2;document.documentElement.setAttribute("data-now-scrolling",""),window.scrollTo({top:o,behavior:"smooth"}),setTimeout((()=>{document.documentElement.removeAttribute("data-now-scrolling")}),800)}}}validate(){return e(this,void 0,void 0,(function*(){const t=Object.assign(Object.assign({},l.defaultValidationSchema||{}),this.config.validationSchema||{}),r=e=>console.warn(`[FormFather] Unknown validation rule "${e}"`),o=[],n=new WeakSet;let s=!0;const a=(e,t=[])=>{var o;const n=[];e.hasAttribute("required")&&n.push("required"),n.push(...t);const s=(null!==(o=e.getAttribute("data-custom-validate"))&&void 0!==o?o:"").split(",").map((e=>e.trim())).filter(Boolean);n.push(...s);const l=[];for(const e of n){const t="string"==typeof e?e:e.rule;i(t)?l.push(e):r(t)}return l},c=(t,r,...n)=>e(this,[t,r,...n],void 0,(function*(e,t,r={}){var n;if(!("checkbox"===e.type||"radio"===e.type?!e.checked:0===e.value.trim().length)||t.includes("required")){for(const l of t){const{rule:t,params:a}="string"==typeof l?{rule:l,params:void 0}:l,c=i(t);if(!(yield c.fn(e.value,e,this.$el,a))){s=!1;const i=null!==(n=r[t])&&void 0!==n?n:c.defaultMessage;return this.showError(e,i),void o.push(e)}}this.hideError(e)}else this.hideError(e)}));for(const[e,r]of Object.entries(t)){const{selector:t,rules:o=[],messages:s={}}=r,i=t?this.$el.querySelectorAll(t):this.$el.querySelectorAll(`[data-validate="${e}"]`);for(const e of Array.from(i))n.has(e)||(n.add(e),yield c(e,a(e,o),s))}const u=Array.from(this.$el.querySelectorAll("[data-custom-validate]")).filter((e=>!n.has(e)));for(const e of u)n.add(e),yield c(e,a(e,[]));return!s&&this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(o),s}))}disableSubmit(){var e;null===(e=this.$submit)||void 0===e||e.setAttribute("disabled","")}enableSubmit(){var e;null===(e=this.$submit)||void 0===e||e.removeAttribute("disabled")}clearInputs(){var e;null===(e=this.inputs)||void 0===e||e.forEach((e=>{var t;const r=e;"radio"===r.type||"checkbox"===r.type?r.checked=!1:(r.value="",null===(t=r.parentElement)||void 0===t||t.classList.remove("filled"),r.dispatchEvent(new Event("input")))}))}showErrorForm(e){var t;const r=this.$el.querySelectorAll(".input__wrapper"),o=r[r.length-1];let n=this.$el.querySelector(".error-block-under-input__wrapper");n&&o.nextElementSibling===n?(n.classList.add("error-block-under-input--warning"),n.querySelector(".error-block-under-input__icon").innerHTML="\x3c!-- SVG content --\x3e",n.querySelector(".error-block-under-input__main-text").textContent=e):(n=document.createElement("div"),n.className="error-block-under-input__wrapper",n.innerHTML=`\n <div class="error-block-under-input error-block-under-input--warning">\n <div class="error-block-under-input__icon-wrapper">\n <span class="error-block-under-input__icon">\n \x3c!-- SVG content --\x3e\n </span>\n <span class="error-block-under-input__icon error-block-under-input__icon--animated" style="display:none;"></span>\n </div>\n <p class="error-block-under-input__text">\n <span class="error-block-under-input__main-text">${e}</span>\n <span class="error-block-under-input__secondary-text"></span>\n </p>\n </div>`,o.insertAdjacentElement("afterend",n)),this.$el.addEventListener("input",(()=>{this.hideErrorForm()}),{passive:!0,once:!0}),null===(t=n.querySelector(".error-block-under-input"))||void 0===t||t.classList.remove("error-block-under-input--success");const s=n.querySelector(".error-block-under-input__secondary-text");s&&(s.textContent="");const i=parseFloat(n.style.height)||0,l=parseFloat(window.getComputedStyle(n).paddingTop)||0;i!==n.querySelector(".error-block-under-input").scrollHeight+16&&(n.style.height=`${i}px`,n.style.opacity="0",n.style.paddingTop=`${l}px`)}hideErrorForm(){const e=this.$el.querySelectorAll(".input__wrapper"),t=e[e.length-1].nextElementSibling;t&&t.classList.contains("error-block-under-input__wrapper")}isCorrectArguments(){return"FORM"!==this.$el.tagName?(console.warn("$el не является тегом form"),!1):!!this.$submit||(console.warn("В форме нет кнопки с типом submit"),!1)}}return l.defaultParams={},l.defaultValidationSchema={tel:{selector:'input[type="tel"]',rules:["tel"]},email:{selector:'input[type="email"]',rules:["email"]},required:{selector:"[required]",rules:["required"]},url:{selector:'input[type="url"]',rules:["url"]},"not-numbers":{selector:'input[data-validate="not-numbers"]',rules:["not-numbers"]}},l}();
1
+ var FormFather=function(e){"use strict";function t(e,t,r,o){return new(r||(r=Promise))((function(n,s){function i(e){try{a(o.next(e))}catch(e){s(e)}}function l(e){try{a(o.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?n(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,l)}a((o=o.apply(e,t||[])).next())}))}function r(e){const t="FORM"===e.tagName?Array.from(e.elements):Array.from(e.querySelectorAll("input, select, textarea, button")),r=new FormData;return t.forEach((e=>{if(!(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement||e instanceof HTMLButtonElement))return;if(!e.name||e.hasAttribute("data-no-serialize"))return;const{name:t,type:o}=e;if("file"===o)if("true"===e.getAttribute("multiple")){const o=e.files;if(o)for(let e=0;e<o.length;e++)r.append(`${t}[${e}]`,o[e])}else{const o=e.files;o&&o[0]&&r.append(t,o[0])}else{let n;if("select-one"===o||"select-multiple"===o){const s=e;if("select-multiple"===o){Array.from(s.selectedOptions).map((e=>e.value)).forEach(((e,o)=>{r.append(`${t}[${o}]`,e)}))}else n=s.value,n&&r.append(t,n)}else if("tel"===o)n=e.value.split(/[\s()-]/).join("").replace(/^8/,"+7");else if("checkbox"===o||"radio"===o){if(!e.checked)return;n=e.value}else if("date"===o){const t=e.getAttribute("data-date-format");n=t?function(e,t){const r=new Date(e),o=e=>e.toString().padStart(2,"0"),n=o(r.getDate()),s=o(r.getMonth()+1),i=r.getFullYear().toString();return t.replace("dd",n).replace("mm",s).replace("yyyy",i)}(e.value,t):e.value}else n=e.value;n&&"select-one"!==o&&"select-multiple"!==o&&r.append(t,n)}})),r}var o;"function"==typeof SuppressedError&&SuppressedError;const n=Symbol.for("FormFather.validators"),s=null!==(o=globalThis[n])&&void 0!==o?o:globalThis[n]=new Map;function i(e,t,r,{override:o=!1}={}){!s.has(e)||o?s.set(e,{fn:t,defaultMessage:r}):console.warn(`[FormFather] Validator "${e}" already exists; pass { override: true } to replace`)}const l=e=>s.get(e);i("required",(e=>e.trim().length>0),"Пустое значение"),i("email",(e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)),"Неверный формат"),i("tel",(e=>/^\+7\d{10}$/.test(e)),"Неверный формат"),i("url",(e=>/^(https?:\/\/).+\..+/.test(e)),"Неверный формат"),i("not-numbers",(e=>!/[0-9]/.test(e)),"Неверный формат");class a{constructor(e,t){this.$submit=null,this.waitResponse=!1,this.inputs=null,this.$licensesCheckbox=null,this.$el=e,this.options=t;this.config=Object.assign({},{onSubmit:()=>{},onResponse:()=>{},onResponseSuccess:()=>{},onResponseUnsuccess:()=>{},customTypeError:null,loaderColor:"#fff",showLoaderButton:!0,scrollToFirstErroredInput:!0,logging:!1,inputSelector:".input",inputWrapperSelector:".input-primary"},a.defaultParams,t),this.$el?(this.$submit=this.$el.querySelector('input[type="submit"], button[type="submit"]'),this.isCorrectArguments()&&this.initialization()):console.warn("Empty $el")}getOptions(){return this.options}static setDefaultParams(e){this.defaultParams=Object.assign(Object.assign({},this.defaultParams),e)}initialization(){this.inputs=this.$el.querySelectorAll(this.config.inputSelector),this.$licensesCheckbox=this.$el.querySelector('input[data-input-name="user-consent"]'),this.$licensesCheckbox&&(this.$licensesCheckbox.checked?this.enableSubmit():this.disableSubmit(),this.$licensesCheckbox.addEventListener("change",(()=>{this.$licensesCheckbox.checked?this.enableSubmit():this.disableSubmit()})));const e=()=>t(this,void 0,void 0,(function*(){var e;const t=this.$el.getAttribute("action")||"",o=(null===(e=this.$el.getAttribute("method"))||void 0===e?void 0:e.toUpperCase())||"POST",n=this.$el.getAttribute("enctype")||"application/x-www-form-urlencoded";let s=null,i={};const l=r(this.$el);let a={};if(l.forEach(((e,t)=>{a[t]=e})),this.config.logging)for(const e of l.keys())console.log(l.get(e));switch("function"==typeof this.config.wrapData&&(a=this.config.wrapData(a)),n){case"application/x-www-form-urlencoded":s=new URLSearchParams(r(this.$el)).toString(),i["Content-Type"]="application/x-www-form-urlencoded";break;case"multipart/form-data":s=r(this.$el);break;case"text/plain":s=Array.from(r(this.$el)).map((([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`)).join("\n"),i["Content-Type"]="text/plain";break;case"application/json":s=JSON.stringify(a),i["Content-Type"]="application/json";break;default:console.warn(`Неизвестный enctype: ${n}. Используется application/x-www-form-urlencoded.`),s=new URLSearchParams(r(this.$el)).toString(),i["Content-Type"]="application/x-www-form-urlencoded"}return fetch(t,{method:o,body:s,headers:i})})),o=()=>t(this,void 0,void 0,(function*(){var t,r,o,n,s,i,l,a;if(!this.waitResponse){!0===this.config.showLoaderButton&&this.showLoader(),null===(r=(t=this.config).onSubmit)||void 0===r||r.call(t,this),this.waitResponse=!0;const c=yield e(),u=yield c.json();if(this.waitResponse=!1,!0===this.config.showLoaderButton&&this.hideLoader(),null===(n=(o=this.config).onResponse)||void 0===n||n.call(o,u,this),200===c.status)if(function(e){if(Object.prototype.hasOwnProperty.call(e,"redirect-url")&&(window.location.href=e["redirect-url"]),Object.prototype.hasOwnProperty.call(e,"reload")&&!0===e.reload&&window.location.reload(),Object.prototype.hasOwnProperty.call(e,"error-toast")){const t=document.querySelector('[data-toast-name="formErrorToast"]');if(t){const r=t.querySelector(".toast__text");r&&(r.textContent=e["error-toast"],window.Toast.showToast("formErrorToast",{removeAfterClose:!1}))}}}(u),!0===u.success)null===(i=(s=this.config).onResponseSuccess)||void 0===i||i.call(s,u,this);else if(null===(a=(l=this.config).onResponseUnsuccess)||void 0===a||a.call(l,u,this),!0===u.error&&(u["error-msg"]&&this.showErrorForm(u["error-msg"]),u.errors)){const e=[];u.errors.forEach((t=>{const r=this.$el.querySelector(`input[name="${t.name}"]`);r?(e.push(r),this.showError(r,t["error-msg"])):console.warn(`Не найдено поле с именем: ${t.name}, для вывода ошибки: ${t["error-msg"]}`)})),!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(e)}}}));this.$el.addEventListener("submit",(e=>t(this,void 0,void 0,(function*(){e.preventDefault();(yield this.validate())&&(!this.$licensesCheckbox||this.$licensesCheckbox&&this.$licensesCheckbox.checked)&&o()}))))}showError(e,t){(function(e,t){if(null==e)return null;let r=e;for(;r;){if(r.matches(t))return r;r=r.parentElement}return null})(e,this.config.inputWrapperSelector).showError(t)}showLoader(){var e;const t=`\n\t\t\t<svg height="38" viewBox="0 0 38 38" width="38" xmlns="http://www.w3.org/2000/svg">\n\t\t\t\t<defs>\n\t\t\t\t<linearGradient id="form-father-loader" x1="8.042%" x2="65.682%" y1="0%" y2="23.865%">\n\t\t\t\t\t<stop offset="0%" stop-color="${this.config.loaderColor}" stop-opacity="0"/>\n\t\t\t\t\t<stop offset="63.146%" stop-color="${this.config.loaderColor}" stop-opacity=".631"/>\n\t\t\t\t\t<stop offset="100%" stop-color="${this.config.loaderColor}"/>\n\t\t\t\t</linearGradient>\n\t\t\t\t</defs>\n\t\t\t\t<g fill-rule="evenodd" fill="none">\n\t\t\t\t<g transform="translate(1 1)">\n\t\t\t\t\t<path d="M36 18c0-9.94-8.06-18-18-18" id="Oval-2" stroke-width="5" stroke="url(#form-father-loader)"></path>\n\t\t\t\t\t<circle cx="36" cy="18" fill="${this.config.loaderColor}" r="1"></circle>\n\t\t\t\t</g>\n\t\t\t\t</g>\n\t\t\t</svg>\n\t\t`,r=document.createElement("span");r.innerHTML=t,r.className="button__loader",null===(e=this.$submit)||void 0===e||e.insertAdjacentElement("afterbegin",r),requestAnimationFrame((()=>{r.setAttribute("data-showed","")}))}hideLoader(){var e,t;null===(e=this.$submit)||void 0===e||e.classList.remove("button--loading");const r=null===(t=this.$submit)||void 0===t?void 0:t.querySelector(".button__loader");r&&(r.classList.remove("active"),r.removeAttribute("data-showed"),setTimeout((()=>{r.remove()}),250))}hideError(e){const t=e.parentElement;t&&t.classList.contains("input__wrapper")&&(t.getAttribute("data-type-error"),t.classList.remove("input__wrapper--error"))}scrollToFirstErroredInput(e){if(e.length>0){const t=Array.from(this.$el.querySelectorAll("input"));let r=null,o=1/0;if(e.forEach((e=>{const n=t.findIndex((t=>t===e));n<o&&(o=n,r=e)})),r){const e=r.getBoundingClientRect(),t=window.pageYOffset||document.documentElement.scrollTop,o=e.top+t-window.innerHeight/2;document.documentElement.setAttribute("data-now-scrolling",""),window.scrollTo({top:o,behavior:"smooth"}),setTimeout((()=>{document.documentElement.removeAttribute("data-now-scrolling")}),800)}}}validate(){return t(this,void 0,void 0,(function*(){const e=Object.assign(Object.assign({},a.defaultValidationSchema||{}),this.config.validationSchema||{}),r=e=>console.warn(`[FormFather] Unknown validation rule "${e}"`),o=[],n=new WeakSet;let s=!0;const i=(e,t=[])=>{var o;const n=[];e.hasAttribute("required")&&n.push("required"),n.push(...t);const s=(null!==(o=e.getAttribute("data-custom-validate"))&&void 0!==o?o:"").split(",").map((e=>e.trim())).filter(Boolean);n.push(...s);const i=[];for(const e of n){const t="string"==typeof e?e:e.rule;l(t)?i.push(e):r(t)}return i},c=(e,r,...n)=>t(this,[e,r,...n],void 0,(function*(e,t,r={}){var n;if(!("checkbox"===e.type||"radio"===e.type?!e.checked:0===e.value.trim().length)||t.includes("required")){for(const i of t){const{rule:t,params:a}="string"==typeof i?{rule:i,params:void 0}:i,c=l(t);if(!(yield c.fn(e.value,e,this.$el,a))){s=!1;const i=null!==(n=r[t])&&void 0!==n?n:c.defaultMessage;return this.showError(e,i),void o.push(e)}}this.hideError(e)}else this.hideError(e)}));for(const[t,r]of Object.entries(e)){const{selector:e,rules:o=[],messages:s={}}=r,l=e?this.$el.querySelectorAll(e):this.$el.querySelectorAll(`[data-validate="${t}"]`);for(const e of Array.from(l))n.has(e)||(n.add(e),yield c(e,i(e,o),s))}const u=Array.from(this.$el.querySelectorAll("[data-custom-validate]")).filter((e=>!n.has(e)));for(const e of u)n.add(e),yield c(e,i(e,[]));return!s&&this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(o),s}))}disableSubmit(){var e;null===(e=this.$submit)||void 0===e||e.setAttribute("disabled","")}enableSubmit(){var e;null===(e=this.$submit)||void 0===e||e.removeAttribute("disabled")}clearInputs(){var e;null===(e=this.inputs)||void 0===e||e.forEach((e=>{var t;const r=e;"radio"===r.type||"checkbox"===r.type?r.checked=!1:(r.value="",null===(t=r.parentElement)||void 0===t||t.classList.remove("filled"),r.dispatchEvent(new Event("input")))}))}showErrorForm(e){var t;const r=this.$el.querySelectorAll(".input__wrapper"),o=r[r.length-1];let n=this.$el.querySelector(".error-block-under-input__wrapper");n&&o.nextElementSibling===n?(n.classList.add("error-block-under-input--warning"),n.querySelector(".error-block-under-input__icon").innerHTML="\x3c!-- SVG content --\x3e",n.querySelector(".error-block-under-input__main-text").textContent=e):(n=document.createElement("div"),n.className="error-block-under-input__wrapper",n.innerHTML=`\n <div class="error-block-under-input error-block-under-input--warning">\n <div class="error-block-under-input__icon-wrapper">\n <span class="error-block-under-input__icon">\n \x3c!-- SVG content --\x3e\n </span>\n <span class="error-block-under-input__icon error-block-under-input__icon--animated" style="display:none;"></span>\n </div>\n <p class="error-block-under-input__text">\n <span class="error-block-under-input__main-text">${e}</span>\n <span class="error-block-under-input__secondary-text"></span>\n </p>\n </div>`,o.insertAdjacentElement("afterend",n)),this.$el.addEventListener("input",(()=>{this.hideErrorForm()}),{passive:!0,once:!0}),null===(t=n.querySelector(".error-block-under-input"))||void 0===t||t.classList.remove("error-block-under-input--success");const s=n.querySelector(".error-block-under-input__secondary-text");s&&(s.textContent="");const i=parseFloat(n.style.height)||0,l=parseFloat(window.getComputedStyle(n).paddingTop)||0;i!==n.querySelector(".error-block-under-input").scrollHeight+16&&(n.style.height=`${i}px`,n.style.opacity="0",n.style.paddingTop=`${l}px`)}hideErrorForm(){const e=this.$el.querySelectorAll(".input__wrapper"),t=e[e.length-1].nextElementSibling;t&&t.classList.contains("error-block-under-input__wrapper")}isCorrectArguments(){return"FORM"!==this.$el.tagName?(console.warn("$el не является тегом form"),!1):!!this.$submit||(console.warn("В форме нет кнопки с типом submit"),!1)}}return a.defaultParams={},a.defaultValidationSchema={tel:{selector:'input[type="tel"]',rules:["tel"]},email:{selector:'input[type="email"]',rules:["email"]},required:{selector:"[required]",rules:["required"]},url:{selector:'input[type="url"]',rules:["url"]},"not-numbers":{selector:'input[data-validate="not-numbers"]',rules:["not-numbers"]}},e.default=a,e.getAllValidators=function(){return new Map(s)},e.getValidator=l,e.registerValidator=i,Object.defineProperty(e,"__esModule",{value:!0}),e}({});
2
2
  //# sourceMappingURL=FormFather.min.js.map
package/index.d.ts CHANGED
@@ -1,3 +1,14 @@
1
+ type ValidatorFn = (value: string, $input: HTMLInputElement, $form: HTMLElement, params?: any) => boolean | Promise<boolean>;
2
+ interface Validator {
3
+ fn: ValidatorFn;
4
+ defaultMessage: string;
5
+ }
6
+ declare function registerValidator(name: string, fn: ValidatorFn, defaultMessage: string, { override }?: {
7
+ override?: boolean;
8
+ }): void;
9
+ declare const getValidator: (name: string) => Validator | undefined;
10
+ declare function getAllValidators(): Map<string, Validator>;
11
+
1
12
  type ValidationSchema = Record<string, {
2
13
  rules: (string | {
3
14
  rule: string;
@@ -152,4 +163,4 @@ declare class Form {
152
163
  private isCorrectArguments;
153
164
  }
154
165
 
155
- export { Form as default };
166
+ export { Form as default, getAllValidators, getValidator, registerValidator };
package/index.js CHANGED
@@ -194,6 +194,9 @@ function registerValidator(name, fn, defaultMessage, { override = false } = {})
194
194
  validators.set(name, { fn, defaultMessage });
195
195
  }
196
196
  const getValidator = (name) => validators.get(name);
197
+ function getAllValidators() {
198
+ return new Map(validators); // копию, чтобы никто не мутировал оригинал
199
+ }
197
200
  /* ---------- built-in rules ---------- */
198
201
  registerValidator('required', v => v.trim().length > 0, 'Пустое значение');
199
202
  registerValidator('email', v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v), 'Неверный формат');
@@ -684,5 +687,5 @@ Form.defaultValidationSchema = {
684
687
  },
685
688
  };
686
689
 
687
- export { Form as default };
690
+ export { Form as default, getAllValidators, getValidator, registerValidator };
688
691
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "form-father",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Form Father: Библиотека для обработки форм",
5
5
  "type": "module",
6
6
  "scripts": {
package/types/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './validators';
1
2
  type ValidationSchema = Record<string, {
2
3
  rules: (string | {
3
4
  rule: string;
@@ -151,4 +152,3 @@ export default class Form {
151
152
  */
152
153
  private isCorrectArguments;
153
154
  }
154
- export {};