form-father 0.2.0 → 0.2.2

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(t){"use strict";function e(t,e,o,r){return new(o||(o=Promise))((function(n,i){function s(t){try{l(r.next(t))}catch(t){i(t)}}function a(t){try{l(r.throw(t))}catch(t){i(t)}}function l(t){var e;t.done?n(t.value):(e=t.value,e instanceof o?e:new o((function(t){t(e)}))).then(s,a)}l((r=r.apply(t,e||[])).next())}))}function o(t){const e="FORM"===t.tagName?Array.from(t.elements):Array.from(t.querySelectorAll("input, select, textarea, button")),o=new FormData;return e.forEach((t=>{if(!(t instanceof HTMLInputElement||t instanceof HTMLSelectElement||t instanceof HTMLTextAreaElement||t instanceof HTMLButtonElement))return;if(!t.name||t.hasAttribute("data-no-serialize"))return;const{name:e,type:r}=t;if("file"===r)if("true"===t.getAttribute("multiple")){const r=t.files;if(r)for(let t=0;t<r.length;t++)o.append(`${e}[${t}]`,r[t])}else{const r=t.files;r&&r[0]&&o.append(e,r[0])}else{let n;if("select-one"===r||"select-multiple"===r){const i=t;if("select-multiple"===r){Array.from(i.selectedOptions).map((t=>t.value)).forEach(((t,r)=>{o.append(`${e}[${r}]`,t)}))}else n=i.value,n&&o.append(e,n)}else if("tel"===r)n=t.value.split(/[\s()-]/).join("").replace(/^8/,"+7");else if("checkbox"===r||"radio"===r){if(!t.checked)return;n=t.value}else if("date"===r){const e=t.getAttribute("data-date-format");n=e?function(t,e){const o=new Date(t),r=t=>t.toString().padStart(2,"0"),n=r(o.getDate()),i=r(o.getMonth()+1),s=o.getFullYear().toString();return e.replace("dd",n).replace("mm",i).replace("yyyy",s)}(t.value,e):t.value}else n=t.value;n&&"select-one"!==r&&"select-multiple"!==r&&o.append(e,n)}})),o}var r;"function"==typeof SuppressedError&&SuppressedError;const n=Symbol.for("FormFather.validators"),i=null!==(r=globalThis[n])&&void 0!==r?r:globalThis[n]=new Map;function s(t,e,o,{override:r=!1}={}){!i.has(t)||r?i.set(t,{fn:e,defaultMessage:o}):console.warn(`[FormFather] Validator "${t}" already exists; pass { override: true } to replace`)}const a=t=>i.get(t);s("required",((t,e,o)=>{if(e&&e.type){if("checkbox"===e.type)return e.checked;if("radio"===e.type){const t=o.querySelectorAll(`input[type="radio"][name="${e.name}"]`);return Array.from(t).some((t=>t.checked))}}return t.trim().length>0}),"Пустое значение"),s("email",(t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)),"Неверный формат"),s("tel",(t=>/^\+7\d{10}$/.test(t)),"Неверный формат"),s("url",(t=>/^(https?:\/\/).+\..+/.test(t)),"Неверный формат"),s("not-numbers",(t=>!/[0-9]/.test(t)),"Неверный формат");class l{constructor(t,e){this.$submit=null,this.waitResponse=!1,this.inputs=null,this.$licensesCheckbox=null,this._anim={duration:220,easing:"ease",paddingTopOpened:16,iconDuration:700},this.$el=t,this.options=e;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,e),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(t){this.defaultParams=Object.assign(Object.assign({},this.defaultParams),t)}initialization(){this.inputs=this.$el.querySelectorAll(this.config.inputSelector);const t=()=>e(this,void 0,void 0,(function*(){var t;const e=this.$el.getAttribute("action")||"",r=(null===(t=this.$el.getAttribute("method"))||void 0===t?void 0:t.toUpperCase())||"POST",n=this.$el.getAttribute("enctype")||"application/x-www-form-urlencoded";let i=null,s={};const a=o(this.$el);let l={};if(a.forEach(((t,e)=>{l[e]=t})),this.config.logging)for(const t of a.keys())console.log(a.get(t));switch("function"==typeof this.config.wrapData&&(l=this.config.wrapData(l)),n){case"application/x-www-form-urlencoded":i=new URLSearchParams(o(this.$el)).toString(),s["Content-Type"]="application/x-www-form-urlencoded";break;case"multipart/form-data":i=o(this.$el);break;case"text/plain":i=Array.from(o(this.$el)).map((([t,e])=>`${encodeURIComponent(t)}=${encodeURIComponent(e)}`)).join("\n"),s["Content-Type"]="text/plain";break;case"application/json":i=JSON.stringify(l),s["Content-Type"]="application/json";break;default:console.warn(`Неизвестный enctype: ${n}. Используется application/x-www-form-urlencoded.`),i=new URLSearchParams(o(this.$el)).toString(),s["Content-Type"]="application/x-www-form-urlencoded"}return fetch(e,{method:r,body:i,headers:s})})),r=()=>e(this,void 0,void 0,(function*(){var e,o,r,n,i,s,a,l;if(!this.waitResponse){!0===this.config.showLoaderButton&&this.showLoader(),null===(o=(e=this.config).onSubmit)||void 0===o||o.call(e,this),this.waitResponse=!0;const c=yield t(),d=yield c.json();if(this.waitResponse=!1,!0===this.config.showLoaderButton&&this.hideLoader(),null===(n=(r=this.config).onResponse)||void 0===n||n.call(r,d,this),200===c.status){if(!0===d.success)null===(s=(i=this.config).onResponseSuccess)||void 0===s||s.call(i,d,this);else if(null===(l=(a=this.config).onResponseUnsuccess)||void 0===l||l.call(a,d,this),!0===d.error&&(d["error-msg"]&&this.showErrorForm(d["error-msg"]),d.errors)){const t=[];d.errors.forEach((e=>{const o=this.$el.querySelector(`input[name="${e.name}"]`);o?(t.push(o),this.showError(o,e["error-msg"])):console.warn(`Не найдено поле с именем: ${e.name}, для вывода ошибки: ${e["error-msg"]}`)})),!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(t)}!function(t){Object.prototype.hasOwnProperty.call(t,"redirect-url")&&(window.location.href=t["redirect-url"]),Object.prototype.hasOwnProperty.call(t,"reload")&&!0===t.reload&&window.location.reload(),Object.prototype.hasOwnProperty.call(t,"toast")&&window.showToast(t.toast),Object.prototype.hasOwnProperty.call(t,"error-toast")&&window.showToast(t["error-toast"])}(d)}}}));this.$el.addEventListener("submit",(t=>e(this,void 0,void 0,(function*(){var e,o,n,i;t.preventDefault(),null===(o=(e=this.config).onBeforeValidate)||void 0===o||o.call(e,this);const s=yield this.validate();null===(i=(n=this.config).onAfterValidate)||void 0===i||i.call(n,s,this),s&&r()}))))}showError(t,e){(function(t,e){if(null==t)return null;let o=t;for(;o;){if(o.matches(e))return o;o=o.parentElement}return null})(t,this.config.inputWrapperSelector).showError(e)}showLoader(){var t;const e=`\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`,o=document.createElement("span");o.innerHTML=e,o.className="button__loader",null===(t=this.$submit)||void 0===t||t.insertAdjacentElement("afterbegin",o),requestAnimationFrame((()=>{o.setAttribute("data-showed","")}))}hideLoader(){var t,e;null===(t=this.$submit)||void 0===t||t.classList.remove("button--loading");const o=null===(e=this.$submit)||void 0===e?void 0:e.querySelector(".button__loader");o&&(o.classList.remove("active"),o.removeAttribute("data-showed"),setTimeout((()=>{o.remove()}),250))}hideError(t){const e=t.parentElement;e&&e.classList.contains("input__wrapper")&&(e.getAttribute("data-type-error"),e.classList.remove("input__wrapper--error"))}scrollToFirstErroredInput(t){if(t.length>0){const e=Array.from(this.$el.querySelectorAll("input"));let o=null,r=1/0;if(t.forEach((t=>{const n=e.findIndex((e=>e===t));n<r&&(r=n,o=t)})),o){const t=o.getBoundingClientRect(),e=window.pageYOffset||document.documentElement.scrollTop,r=t.top+e-window.innerHeight/2;document.documentElement.setAttribute("data-now-scrolling",""),window.scrollTo({top:r,behavior:"smooth"}),setTimeout((()=>{document.documentElement.removeAttribute("data-now-scrolling")}),800)}}}validate(){return e(this,arguments,void 0,(function*(t=this.$el){const o=Object.assign(Object.assign({},l.defaultValidationSchema||{}),this.config.validationSchema||{}),r=t=>console.warn(`[FormFather] Unknown validation rule "${t}"`),n=[],i=new WeakSet;let s=!0;const c=(t,e=[])=>{var o;const n=[];t.hasAttribute("required")&&n.push("required"),n.push(...e);const i=(null!==(o=t.getAttribute("data-custom-validate"))&&void 0!==o?o:"").split(",").map((t=>t.trim())).filter(Boolean);n.push(...i);const s=[];for(const t of n){const e="string"==typeof t?t:t.rule;a(e)?s.push(t):r(e)}return s},d=(o,r,...i)=>e(this,[o,r,...i],void 0,(function*(e,o,r={}){var i;if(!("checkbox"===e.type||"radio"===e.type?!e.checked:0===e.value.trim().length)||o.includes("required")){for(const l of o){const{rule:o,params:c}="string"==typeof l?{rule:l,params:void 0}:l,d=a(o);if(!(yield d.fn(e.value,e,t,c))){s=!1;const t=null!==(i=r[o])&&void 0!==i?i:d.defaultMessage;return this.showError(e,t),void n.push(e)}}this.hideError(e)}else this.hideError(e)}));for(const[e,r]of Object.entries(o)){const{selector:o,rules:n=[],messages:s={}}=r,a=o?t.querySelectorAll(o):t.querySelectorAll(`[data-validate="${e}"]`);for(const t of Array.from(a))i.has(t)||(i.add(t),yield d(t,c(t,n),s))}const p=Array.from(t.querySelectorAll("[data-custom-validate]")).filter((t=>!i.has(t)));for(const t of p)i.add(t),yield d(t,c(t,[]));return!s&&this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(n),s}))}disableSubmit(){var t;null===(t=this.$submit)||void 0===t||t.setAttribute("disabled","")}enableSubmit(){var t;null===(t=this.$submit)||void 0===t||t.removeAttribute("disabled")}clearInputs(){var t;null===(t=this.inputs)||void 0===t||t.forEach((t=>{var e;const o=t;"radio"===o.type||"checkbox"===o.type?o.checked=!1:(o.value="",null===(e=o.parentElement)||void 0===e||e.classList.remove("filled"),o.dispatchEvent(new Event("input")))}))}_prefersReducedMotion(){var t;return"undefined"!=typeof window&&(null===(t=window.matchMedia)||void 0===t?void 0:t.call(window,"(prefers-reduced-motion: reduce)").matches)}_canAnimate(t){return!(!t||!("animate"in t)||this._prefersReducedMotion())}_cancelAnimations(t){var e;null===(e=null==t?void 0:t.getAnimations)||void 0===e||e.call(t).forEach((t=>t.cancel()))}showErrorForm(t){var e;const o=this.$el.querySelectorAll(this.config.inputWrapperSelector),r=o[o.length-1];let n=this.$el.querySelector(".error-block-under-input__wrapper");n&&r.nextElementSibling===n?(n.style.boxSizing="border-box",n.style.overflow="hidden"):(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" style="display:grid;grid-template-columns:auto 1fr;gap:8px;align-items:start;">\n <div class="error-block-under-input__icon-wrapper" style="position:relative;width:20px;height:20px;">\n <span class="error-block-under-input__icon" style="display:block;width:20px;height:20px;"></span>\n <span class="error-block-under-input__icon error-block-under-input__icon--animated" style="display:block;position:absolute;inset:0;"></span>\n </div>\n <p class="error-block-under-input__text" style="margin:0;">\n <span class="error-block-under-input__main-text"></span>\n <span class="error-block-under-input__secondary-text"></span>\n </p>\n </div>\n ',Object.assign(n.style,{boxSizing:"border-box",overflow:"hidden",height:"0px",paddingTop:"0px",opacity:"0"}),r.insertAdjacentElement("afterend",n)),n.querySelector(".error-block-under-input__main-text").textContent=t;const i=n.querySelector(".error-block-under-input__secondary-text");i&&(i.textContent=""),null===(e=n.querySelector(".error-block-under-input"))||void 0===e||e.classList.remove("error-block-under-input--success"),n.querySelector(".error-block-under-input");const s=n.style.height,a=n.style.paddingTop;n.style.height="auto",n.style.paddingTop=`${this._anim.paddingTopOpened}px`;const l=n.clientHeight;if(n.style.height=s||"0px",n.style.paddingTop=a||"0px",parseFloat(n.style.height)===l&&1===parseFloat(n.style.opacity||"1"))this._ringIcon(n);else{if(this._cancelAnimations(n),this._canAnimate(n)){n.animate([{height:`${parseFloat(n.style.height)||0}px`,paddingTop:`${parseFloat(n.style.paddingTop)||0}px`,opacity:parseFloat(n.style.opacity||"0")},{height:`${l}px`,paddingTop:`${this._anim.paddingTopOpened}px`,opacity:1}],{duration:this._anim.duration,easing:this._anim.easing,fill:"forwards"}).addEventListener("finish",(()=>{n.style.height="auto",n.style.paddingTop=`${this._anim.paddingTopOpened}px`,n.style.opacity="1"}))}else n.style.height="auto",n.style.paddingTop=`${this._anim.paddingTopOpened}px`,n.style.opacity="1";this._ringIcon(n)}this.$el.addEventListener("input",(()=>this.hideErrorForm()),{passive:!0,once:!0})}hideErrorForm(){const t=this.$el.querySelectorAll(this.config.inputWrapperSelector),e=t[t.length-1].nextElementSibling;if(!e||!e.classList.contains("error-block-under-input__wrapper"))return;if((""===e.style.height||"auto"===e.style.height)&&(e.style.height=`${e.clientHeight}px`),e.style.paddingTop=e.style.paddingTop||`${this._anim.paddingTopOpened}px`,e.style.opacity=e.style.opacity||"1",this._cancelAnimations(e),this._canAnimate(e)){e.animate([{height:`${parseFloat(e.style.height)||e.clientHeight}px`,paddingTop:`${parseFloat(e.style.paddingTop)||this._anim.paddingTopOpened}px`,opacity:parseFloat(e.style.opacity||"1")},{height:"0px",paddingTop:"0px",opacity:0}],{duration:this._anim.duration,easing:this._anim.easing,fill:"forwards"}).addEventListener("finish",(()=>{e.remove()}))}else e.remove()}_ringIcon(t){const e=t.querySelector(".error-block-under-input__icon--animated");e&&(this._cancelAnimations(e),this._canAnimate(e)&&e.animate([{transform:"rotate(0deg) scale(1)",opacity:0},{transform:"rotate(-8deg) scale(1.05)",opacity:1,offset:.15},{transform:"rotate(8deg) scale(1.05)",opacity:1,offset:.3},{transform:"rotate(-6deg) scale(1.03)",opacity:1,offset:.45},{transform:"rotate(6deg) scale(1.03)",opacity:1,offset:.6},{transform:"rotate(0deg) scale(1)",opacity:0}],{duration:this._anim.iconDuration,easing:"ease"}))}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"]}},t.default=l,t.getAllValidators=function(){return new Map(i)},t.getValidator=a,t.registerValidator=s,Object.defineProperty(t,"__esModule",{value:!0}),t}({});
1
+ var FormFather=function(t){"use strict";function e(t,e,o,r){return new(o||(o=Promise))((function(i,n){function s(t){try{l(r.next(t))}catch(t){n(t)}}function a(t){try{l(r.throw(t))}catch(t){n(t)}}function l(t){var e;t.done?i(t.value):(e=t.value,e instanceof o?e:new o((function(t){t(e)}))).then(s,a)}l((r=r.apply(t,e||[])).next())}))}function o(t){const e="FORM"===t.tagName?Array.from(t.elements):Array.from(t.querySelectorAll("input, select, textarea, button")),o=new FormData;return e.forEach((t=>{if(!(t instanceof HTMLInputElement||t instanceof HTMLSelectElement||t instanceof HTMLTextAreaElement||t instanceof HTMLButtonElement))return;if(!t.name||t.hasAttribute("data-no-serialize"))return;const{name:e,type:r}=t;if("file"===r)if("true"===t.getAttribute("multiple")){const r=t.files;if(r)for(let t=0;t<r.length;t++)o.append(`${e}[${t}]`,r[t])}else{const r=t.files;r&&r[0]&&o.append(e,r[0])}else{let i;if("select-one"===r||"select-multiple"===r){const n=t;if("select-multiple"===r){Array.from(n.selectedOptions).map((t=>t.value)).forEach(((t,r)=>{o.append(`${e}[${r}]`,t)}))}else i=n.value,i&&o.append(e,i)}else if("tel"===r)i=t.value.split(/[\s()-]/).join("").replace(/^8/,"+7");else if("checkbox"===r||"radio"===r){if(!t.checked)return;i=t.value}else if("date"===r){const e=t.getAttribute("data-date-format");i=e?function(t,e){const o=new Date(t),r=t=>t.toString().padStart(2,"0"),i=r(o.getDate()),n=r(o.getMonth()+1),s=o.getFullYear().toString();return e.replace("dd",i).replace("mm",n).replace("yyyy",s)}(t.value,e):t.value}else i=t.value;i&&"select-one"!==r&&"select-multiple"!==r&&o.append(e,i)}})),o}var r;"function"==typeof SuppressedError&&SuppressedError;const i=Symbol.for("FormFather.validators"),n=null!==(r=globalThis[i])&&void 0!==r?r:globalThis[i]=new Map;function s(t,e,o,{override:r=!1}={}){!n.has(t)||r?n.set(t,{fn:e,defaultMessage:o}):console.warn(`[FormFather] Validator "${t}" already exists; pass { override: true } to replace`)}const a=t=>n.get(t);var l;s("required",((t,e,o)=>{if(e&&e.type){if("checkbox"===e.type)return e.checked;if("radio"===e.type){const t=o.querySelectorAll(`input[type="radio"][name="${e.name}"]`);return Array.from(t).some((t=>t.checked))}}return t.trim().length>0}),"Пустое значение"),s("email",(t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)),"Неверный формат"),s("tel",(t=>/^\+7\d{10}$/.test(t)),"Неверный формат"),s("url",(t=>/^(https?:\/\/).+\..+/.test(t)),"Неверный формат"),s("not-numbers",(t=>!/[0-9]/.test(t)),"Неверный формат");const c=Symbol.for("formfather.shared"),d=null!==(l=globalThis[c])&&void 0!==l?l:globalThis[c]={defaultParams:{},defaultValidationSchema:void 0},u={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"]}};class p{static get defaultParams(){return d.defaultParams}static set defaultParams(t){d.defaultParams=t}static get defaultValidationSchema(){var t;return null!==(t=d.defaultValidationSchema)&&void 0!==t?t:d.defaultValidationSchema=u}static set defaultValidationSchema(t){d.defaultValidationSchema=t}constructor(t,e){this.$submit=null,this.waitResponse=!1,this.inputs=null,this.$licensesCheckbox=null,this._anim={duration:220,easing:"ease",paddingTopOpened:16,iconDuration:700},this.$el=t,this.options=e;this.config=Object.assign({},{onSubmit:()=>{},onResponse:()=>{},onResponseSuccess:()=>{},onResponseUnsuccess:()=>{},customTypeError:null,loaderColor:"#fff",showLoaderButton:!0,scrollToFirstErroredInput:!0,logging:!1,inputSelector:".input",inputWrapperSelector:".input-primary"},p.defaultParams,e),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(t){this.defaultParams=Object.assign(Object.assign({},this.defaultParams),t)}initialization(){this.inputs=this.$el.querySelectorAll(this.config.inputSelector);const t=()=>e(this,void 0,void 0,(function*(){var t;const e=this.$el.getAttribute("action")||"",r=(null===(t=this.$el.getAttribute("method"))||void 0===t?void 0:t.toUpperCase())||"POST",i=this.$el.getAttribute("enctype")||"application/x-www-form-urlencoded";let n=null,s={};const a=o(this.$el);let l={};if(a.forEach(((t,e)=>{l[e]=t})),this.config.logging)for(const t of a.keys())console.log(a.get(t));switch("function"==typeof this.config.wrapData&&(l=this.config.wrapData(l)),i){case"application/x-www-form-urlencoded":n=new URLSearchParams(o(this.$el)).toString(),s["Content-Type"]="application/x-www-form-urlencoded";break;case"multipart/form-data":n=o(this.$el);break;case"text/plain":n=Array.from(o(this.$el)).map((([t,e])=>`${encodeURIComponent(t)}=${encodeURIComponent(e)}`)).join("\n"),s["Content-Type"]="text/plain";break;case"application/json":n=JSON.stringify(l),s["Content-Type"]="application/json";break;default:console.warn(`Неизвестный enctype: ${i}. Используется application/x-www-form-urlencoded.`),n=new URLSearchParams(o(this.$el)).toString(),s["Content-Type"]="application/x-www-form-urlencoded"}return fetch(e,{method:r,body:n,headers:s})})),r=()=>e(this,void 0,void 0,(function*(){var e,o,r,i,n,s,a,l;if(!this.waitResponse){!0===this.config.showLoaderButton&&this.showLoader(),null===(o=(e=this.config).onSubmit)||void 0===o||o.call(e,this),this.waitResponse=!0;const c=yield t(),d=yield c.json();if(this.waitResponse=!1,!0===this.config.showLoaderButton&&this.hideLoader(),null===(i=(r=this.config).onResponse)||void 0===i||i.call(r,d,this),200===c.status){if(!0===d.success)null===(s=(n=this.config).onResponseSuccess)||void 0===s||s.call(n,d,this);else if(null===(l=(a=this.config).onResponseUnsuccess)||void 0===l||l.call(a,d,this),!0===d.error&&(d["error-msg"]&&this.showErrorForm(d["error-msg"]),d.errors)){const t=[];d.errors.forEach((e=>{const o=this.$el.querySelector(`input[name="${e.name}"]`);o?(t.push(o),this.showError(o,e["error-msg"])):console.warn(`Не найдено поле с именем: ${e.name}, для вывода ошибки: ${e["error-msg"]}`)})),!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(t)}!function(t){if(Object.prototype.hasOwnProperty.call(t,"redirect-url"))window.location.href=t["redirect-url"];else if(Object.prototype.hasOwnProperty.call(t,"reload"))!0===t.reload&&window.location.reload();else if(Object.prototype.hasOwnProperty.call(t,"toast")){const e=t.toast;(Array.isArray(e)?e:[e]).forEach((t=>{window.showToast(t)}))}else Object.prototype.hasOwnProperty.call(t,"error-toast")&&window.showToast(t["error-toast"])}(d)}}}));this.$el.addEventListener("submit",(t=>e(this,void 0,void 0,(function*(){var e,o,i,n;t.preventDefault(),null===(o=(e=this.config).onBeforeValidate)||void 0===o||o.call(e,this);const s=yield this.validate();null===(n=(i=this.config).onAfterValidate)||void 0===n||n.call(i,s,this),s&&r()}))))}showError(t,e){(function(t,e){if(null==t)return null;let o=t;for(;o;){if(o.matches(e))return o;o=o.parentElement}return null})(t,this.config.inputWrapperSelector).showError(e)}showLoader(){var t;const e=`\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`,o=document.createElement("span");o.innerHTML=e,o.className="button__loader",null===(t=this.$submit)||void 0===t||t.insertAdjacentElement("afterbegin",o),requestAnimationFrame((()=>{o.setAttribute("data-showed","")}))}hideLoader(){var t,e;null===(t=this.$submit)||void 0===t||t.classList.remove("button--loading");const o=null===(e=this.$submit)||void 0===e?void 0:e.querySelector(".button__loader");o&&(o.classList.remove("active"),o.removeAttribute("data-showed"),setTimeout((()=>{o.remove()}),250))}hideError(t){const e=t.parentElement;e&&e.classList.contains("input__wrapper")&&(e.getAttribute("data-type-error"),e.classList.remove("input__wrapper--error"))}scrollToFirstErroredInput(t){if(t.length>0){const e=Array.from(this.$el.querySelectorAll("input"));let o=null,r=1/0;if(t.forEach((t=>{const i=e.findIndex((e=>e===t));i<r&&(r=i,o=t)})),o){const t=o.getBoundingClientRect(),e=window.pageYOffset||document.documentElement.scrollTop,r=t.top+e-window.innerHeight/2;document.documentElement.setAttribute("data-now-scrolling",""),window.scrollTo({top:r,behavior:"smooth"}),setTimeout((()=>{document.documentElement.removeAttribute("data-now-scrolling")}),800)}}}validate(){return e(this,arguments,void 0,(function*(t=this.$el){const o=Object.assign(Object.assign({},p.defaultValidationSchema||{}),this.config.validationSchema||{}),r=t=>console.warn(`[FormFather] Unknown validation rule "${t}"`),i=[],n=new WeakSet;let s=!0;const l=(t,e=[])=>{var o;const i=[];t.hasAttribute("required")&&i.push("required"),i.push(...e);const n=(null!==(o=t.getAttribute("data-custom-validate"))&&void 0!==o?o:"").split(",").map((t=>t.trim())).filter(Boolean);i.push(...n);const s=[];for(const t of i){const e="string"==typeof t?t:t.rule;a(e)?s.push(t):r(e)}return s},c=(o,r,...n)=>e(this,[o,r,...n],void 0,(function*(e,o,r={}){var n;if(!("checkbox"===e.type||"radio"===e.type?!e.checked:0===e.value.trim().length)||o.includes("required")){for(const l of o){const{rule:o,params:c}="string"==typeof l?{rule:l,params:void 0}:l,d=a(o);if(!(yield d.fn(e.value,e,t,c))){s=!1;const t=null!==(n=r[o])&&void 0!==n?n:d.defaultMessage;return this.showError(e,t),void i.push(e)}}this.hideError(e)}else this.hideError(e)}));for(const[e,r]of Object.entries(o)){const{selector:o,rules:i=[],messages:s={}}=r,a=o?t.querySelectorAll(o):t.querySelectorAll(`[data-validate="${e}"]`);for(const t of Array.from(a))n.has(t)||(n.add(t),yield c(t,l(t,i),s))}const d=Array.from(t.querySelectorAll("[data-custom-validate]")).filter((t=>!n.has(t)));for(const t of d)n.add(t),yield c(t,l(t,[]));return!s&&this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(i),s}))}disableSubmit(){var t;null===(t=this.$submit)||void 0===t||t.setAttribute("disabled","")}enableSubmit(){var t;null===(t=this.$submit)||void 0===t||t.removeAttribute("disabled")}clearInputs(){var t;null===(t=this.inputs)||void 0===t||t.forEach((t=>{var e;const o=t;"radio"===o.type||"checkbox"===o.type?o.checked=!1:(o.value="",null===(e=o.parentElement)||void 0===e||e.classList.remove("filled"),o.dispatchEvent(new Event("input")))}))}_prefersReducedMotion(){var t;return"undefined"!=typeof window&&(null===(t=window.matchMedia)||void 0===t?void 0:t.call(window,"(prefers-reduced-motion: reduce)").matches)}_canAnimate(t){return!(!t||!("animate"in t)||this._prefersReducedMotion())}_cancelAnimations(t){var e;null===(e=null==t?void 0:t.getAnimations)||void 0===e||e.call(t).forEach((t=>t.cancel()))}showErrorForm(t){var e;const o=this.$el.querySelectorAll(this.config.inputWrapperSelector),r=o[o.length-1];let i=this.$el.querySelector(".error-block-under-input__wrapper");i&&r.nextElementSibling===i?(i.style.boxSizing="border-box",i.style.overflow="hidden"):(i=document.createElement("div"),i.className="error-block-under-input__wrapper",i.innerHTML='\n <div class="error-block-under-input error-block-under-input--warning" style="display:grid;grid-template-columns:auto 1fr;gap:8px;align-items:start;">\n <div class="error-block-under-input__icon-wrapper" style="position:relative;width:20px;height:20px;">\n <span class="error-block-under-input__icon" style="display:block;width:20px;height:20px;"></span>\n <span class="error-block-under-input__icon error-block-under-input__icon--animated" style="display:block;position:absolute;inset:0;"></span>\n </div>\n <p class="error-block-under-input__text" style="margin:0;">\n <span class="error-block-under-input__main-text"></span>\n <span class="error-block-under-input__secondary-text"></span>\n </p>\n </div>\n ',Object.assign(i.style,{boxSizing:"border-box",overflow:"hidden",height:"0px",paddingTop:"0px",opacity:"0"}),r.insertAdjacentElement("afterend",i)),i.querySelector(".error-block-under-input__main-text").textContent=t;const n=i.querySelector(".error-block-under-input__secondary-text");n&&(n.textContent=""),null===(e=i.querySelector(".error-block-under-input"))||void 0===e||e.classList.remove("error-block-under-input--success"),i.querySelector(".error-block-under-input");const s=i.style.height,a=i.style.paddingTop;i.style.height="auto",i.style.paddingTop=`${this._anim.paddingTopOpened}px`;const l=i.clientHeight;if(i.style.height=s||"0px",i.style.paddingTop=a||"0px",parseFloat(i.style.height)===l&&1===parseFloat(i.style.opacity||"1"))this._ringIcon(i);else{if(this._cancelAnimations(i),this._canAnimate(i)){i.animate([{height:`${parseFloat(i.style.height)||0}px`,paddingTop:`${parseFloat(i.style.paddingTop)||0}px`,opacity:parseFloat(i.style.opacity||"0")},{height:`${l}px`,paddingTop:`${this._anim.paddingTopOpened}px`,opacity:1}],{duration:this._anim.duration,easing:this._anim.easing,fill:"forwards"}).addEventListener("finish",(()=>{i.style.height="auto",i.style.paddingTop=`${this._anim.paddingTopOpened}px`,i.style.opacity="1"}))}else i.style.height="auto",i.style.paddingTop=`${this._anim.paddingTopOpened}px`,i.style.opacity="1";this._ringIcon(i)}this.$el.addEventListener("input",(()=>this.hideErrorForm()),{passive:!0,once:!0})}hideErrorForm(){const t=this.$el.querySelectorAll(this.config.inputWrapperSelector),e=t[t.length-1].nextElementSibling;if(!e||!e.classList.contains("error-block-under-input__wrapper"))return;if((""===e.style.height||"auto"===e.style.height)&&(e.style.height=`${e.clientHeight}px`),e.style.paddingTop=e.style.paddingTop||`${this._anim.paddingTopOpened}px`,e.style.opacity=e.style.opacity||"1",this._cancelAnimations(e),this._canAnimate(e)){e.animate([{height:`${parseFloat(e.style.height)||e.clientHeight}px`,paddingTop:`${parseFloat(e.style.paddingTop)||this._anim.paddingTopOpened}px`,opacity:parseFloat(e.style.opacity||"1")},{height:"0px",paddingTop:"0px",opacity:0}],{duration:this._anim.duration,easing:this._anim.easing,fill:"forwards"}).addEventListener("finish",(()=>{e.remove()}))}else e.remove()}_ringIcon(t){const e=t.querySelector(".error-block-under-input__icon--animated");e&&(this._cancelAnimations(e),this._canAnimate(e)&&e.animate([{transform:"rotate(0deg) scale(1)",opacity:0},{transform:"rotate(-8deg) scale(1.05)",opacity:1,offset:.15},{transform:"rotate(8deg) scale(1.05)",opacity:1,offset:.3},{transform:"rotate(-6deg) scale(1.03)",opacity:1,offset:.45},{transform:"rotate(6deg) scale(1.03)",opacity:1,offset:.6},{transform:"rotate(0deg) scale(1)",opacity:0}],{duration:this._anim.iconDuration,easing:"ease"}))}isCorrectArguments(){return"FORM"!==this.$el.tagName?(console.warn("$el не является тегом form"),!1):!!this.$submit||(console.warn("В форме нет кнопки с типом submit"),!1)}}return t.default=p,t.getAllValidators=function(){return new Map(n)},t.getValidator=a,t.registerValidator=s,Object.defineProperty(t,"__esModule",{value:!0}),t}({});
2
2
  //# sourceMappingURL=FormFather.min.js.map
package/index.d.ts CHANGED
@@ -94,8 +94,10 @@ declare class Form {
94
94
  private waitResponse;
95
95
  private inputs;
96
96
  private $licensesCheckbox;
97
- private static defaultParams;
98
- static defaultValidationSchema: ValidationSchema;
97
+ private static get defaultParams();
98
+ private static set defaultParams(value);
99
+ static get defaultValidationSchema(): ValidationSchema;
100
+ static set defaultValidationSchema(v: ValidationSchema);
99
101
  /**
100
102
  * Создать форму.
101
103
  *
package/index.js CHANGED
@@ -163,23 +163,31 @@ function parseCommonResponseProperties(responseBody) {
163
163
  if (Object.prototype.hasOwnProperty.call(responseBody, 'redirect-url')) {
164
164
  window.location.href = responseBody['redirect-url'];
165
165
  }
166
- if (Object.prototype.hasOwnProperty.call(responseBody, 'reload')) {
167
- if (responseBody.reload === true)
166
+ else if (Object.prototype.hasOwnProperty.call(responseBody, 'reload')) {
167
+ if (responseBody.reload === true) {
168
168
  window.location.reload();
169
+ }
169
170
  }
170
- if (Object.prototype.hasOwnProperty.call(responseBody, 'toast')) {
171
- window.showToast(responseBody['toast']);
172
- }
173
- /** @deprecated */
174
- if (Object.prototype.hasOwnProperty.call(responseBody, 'error-toast')) {
175
- window.showToast(responseBody['error-toast']);
171
+ // Не показываем тост если делается редирект или обновление страницы (чтобы небыло вспышек) - в этом случае тосты обрабытываются в ответе onResponseSuccess | onResponseUnsuccess
172
+ else {
173
+ if (Object.prototype.hasOwnProperty.call(responseBody, 'toast')) {
174
+ const toasts = responseBody['toast'];
175
+ const normalizedToasts = Array.isArray(toasts) ? toasts : [toasts];
176
+ normalizedToasts.forEach(toast => {
177
+ window.showToast(toast);
178
+ });
179
+ }
180
+ else if (Object.prototype.hasOwnProperty.call(responseBody, 'error-toast')) {
181
+ /** @deprecated */
182
+ window.showToast(responseBody['error-toast']);
183
+ }
176
184
  }
177
185
  }
178
186
 
179
- var _a;
187
+ var _a$1;
180
188
  /* ---------- singleton-storage на globalThis ---------- */
181
189
  const GLOBAL_KEY = Symbol.for('FormFather.validators');
182
- const validators = (_a = globalThis[GLOBAL_KEY]) !== null && _a !== void 0 ? _a : (globalThis[GLOBAL_KEY] = new Map());
190
+ const validators = (_a$1 = globalThis[GLOBAL_KEY]) !== null && _a$1 !== void 0 ? _a$1 : (globalThis[GLOBAL_KEY] = new Map());
183
191
  /* ---------- API ---------- */
184
192
  function registerValidator(name, fn, defaultMessage, { override = false } = {}) {
185
193
  if (validators.has(name) && !override) {
@@ -211,12 +219,59 @@ registerValidator('tel', v => /^\+7\d{10}$/.test(v), 'Неверный форм
211
219
  registerValidator('url', v => /^(https?:\/\/).+\..+/.test(v), 'Неверный формат');
212
220
  registerValidator('not-numbers', v => !/[0-9]/.test(v), 'Неверный формат');
213
221
 
222
+ var _a;
223
+ // --- shared cross-file state (singleton via globalThis) ---
224
+ const FORM_GLOBAL_KEY = Symbol.for('formfather.shared');
225
+ const __shared =
226
+ // уже существует? используем его
227
+ (_a = globalThis[FORM_GLOBAL_KEY]) !== null && _a !== void 0 ? _a :
228
+ // иначе создаём
229
+ (globalThis[FORM_GLOBAL_KEY] = {
230
+ defaultParams: {},
231
+ defaultValidationSchema: undefined,
232
+ });
233
+ /** Изначальная дефолтная схема. */
234
+ const INITIAL_DEFAULT_SCHEMA = {
235
+ tel: {
236
+ selector: 'input[type="tel"]',
237
+ rules: ['tel'],
238
+ },
239
+ email: {
240
+ selector: 'input[type="email"]',
241
+ rules: ['email'],
242
+ },
243
+ required: {
244
+ selector: '[required]',
245
+ rules: ['required'],
246
+ },
247
+ url: {
248
+ selector: 'input[type="url"]',
249
+ rules: ['url'],
250
+ },
251
+ 'not-numbers': {
252
+ selector: 'input[data-validate="not-numbers"]',
253
+ rules: ['not-numbers'],
254
+ },
255
+ };
214
256
  /**
215
257
  * Реализует форму отправки данных.
216
258
  *
217
259
  * @class
218
260
  */
219
261
  class Form {
262
+ static get defaultParams() {
263
+ return __shared.defaultParams;
264
+ }
265
+ static set defaultParams(v) {
266
+ __shared.defaultParams = v;
267
+ }
268
+ static get defaultValidationSchema() {
269
+ var _a;
270
+ return ((_a = __shared.defaultValidationSchema) !== null && _a !== void 0 ? _a : (__shared.defaultValidationSchema = INITIAL_DEFAULT_SCHEMA));
271
+ }
272
+ static set defaultValidationSchema(v) {
273
+ __shared.defaultValidationSchema = v;
274
+ }
220
275
  /**
221
276
  * Создать форму.
222
277
  *
@@ -788,29 +843,6 @@ class Form {
788
843
  return true;
789
844
  }
790
845
  }
791
- Form.defaultParams = {};
792
- Form.defaultValidationSchema = {
793
- tel: {
794
- selector: 'input[type="tel"]',
795
- rules: ['tel'],
796
- },
797
- email: {
798
- selector: 'input[type="email"]',
799
- rules: ['email'],
800
- },
801
- required: {
802
- selector: '[required]',
803
- rules: ['required'],
804
- },
805
- url: {
806
- selector: 'input[type="url"]',
807
- rules: ['url'],
808
- },
809
- 'not-numbers': {
810
- selector: 'input[data-validate="not-numbers"]',
811
- rules: ['not-numbers'],
812
- },
813
- };
814
846
 
815
847
  export { Form as default, getAllValidators, getValidator, registerValidator };
816
848
  //# 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.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Form Father: Библиотека для обработки форм",
5
5
  "type": "module",
6
6
  "scripts": {
package/types/index.d.ts CHANGED
@@ -84,8 +84,10 @@ export default class Form {
84
84
  private waitResponse;
85
85
  private inputs;
86
86
  private $licensesCheckbox;
87
- private static defaultParams;
88
- static defaultValidationSchema: ValidationSchema;
87
+ private static get defaultParams();
88
+ private static set defaultParams(value);
89
+ static get defaultValidationSchema(): ValidationSchema;
90
+ static set defaultValidationSchema(v: ValidationSchema);
89
91
  /**
90
92
  * Создать форму.
91
93
  *