form-father 0.2.5 → 0.2.7
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 +1 -1
- package/index.d.ts +3 -0
- package/index.js +138 -101
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/types/index.d.ts +3 -0
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(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._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._onSubmitHandler=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()})),this.$el.addEventListener("submit",this._onSubmitHandler)}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={}){if(e.hasAttribute("data-no-validate"))return;if(!("checkbox"===e.type||"radio"===e.type?!e.checked:0===e.value.trim().length)||o.includes("required")){for(const n of o){const{rule:o,params:l}="string"==typeof n?{rule:n,params:void 0}:n,c=a(o),d=yield c.fn(e.value,e,t,l),u="object"==typeof d&&null!==d,p=u?!0===d.valid:!!d;if(u&&d.effect&&(yield d.effect({value:e.value,$input:e,$form:t,params:l})),!p){s=!1;const t=d,n=u&&"string"==typeof t.message&&t.message||r[o]||c.defaultMessage;return this.showError(e,n),void i.push(e)}if(u&&d.stopOthers)return}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.filter((t=>!t.hasAttribute("data-no-error-scroll")))),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"}))}destroy(){var t,e;this._onSubmitHandler&&(this.$el.removeEventListener("submit",this._onSubmitHandler),this._onSubmitHandler=void 0);const o=this.$el.querySelector(".error-block-under-input__wrapper");o&&(this._cancelAnimations(o),o.remove()),null===(t=this.$submit)||void 0===t||t.classList.remove("button--loading");const r=null===(e=this.$submit)||void 0===e?void 0:e.querySelector(".button__loader");r&&r.remove();this.$el.querySelectorAll("input, textarea").forEach((t=>{t instanceof HTMLInputElement&&this.hideError(t)})),document.documentElement.removeAttribute("data-now-scrolling"),this.inputs=null,this.$submit=null,this.waitResponse=!1}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}({});
|
|
1
|
+
var FormFather=function(t){"use strict";function e(t,e,i,o){return new(i||(i=Promise))((function(r,n){function s(t){try{l(o.next(t))}catch(t){n(t)}}function a(t){try{l(o.throw(t))}catch(t){n(t)}}function l(t){var e;t.done?r(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(s,a)}l((o=o.apply(t,e||[])).next())}))}function i(t){const e="FORM"===t.tagName?Array.from(t.elements):Array.from(t.querySelectorAll("input, select, textarea, button")),i=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:o}=t;if("file"===o)if("true"===t.getAttribute("multiple")){const o=t.files;if(o)for(let t=0;t<o.length;t++)i.append(`${e}[${t}]`,o[t])}else{const o=t.files;o&&o[0]&&i.append(e,o[0])}else{let r;if("select-one"===o||"select-multiple"===o){const n=t;if("select-multiple"===o){Array.from(n.selectedOptions).map((t=>t.value)).forEach(((t,o)=>{i.append(`${e}[${o}]`,t)}))}else r=n.value,r&&i.append(e,r)}else if("tel"===o)r=t.value.split(/[\s()-]/).join("").replace(/^8/,"+7");else if("checkbox"===o||"radio"===o){if(!t.checked)return;r=t.value}else if("date"===o){const e=t.getAttribute("data-date-format");r=e?function(t,e){const i=new Date(t),o=t=>t.toString().padStart(2,"0"),r=o(i.getDate()),n=o(i.getMonth()+1),s=i.getFullYear().toString();return e.replace("dd",r).replace("mm",n).replace("yyyy",s)}(t.value,e):t.value}else r=t.value;r&&"select-one"!==o&&"select-multiple"!==o&&i.append(e,r)}})),i}var o;"function"==typeof SuppressedError&&SuppressedError;const r=Symbol.for("FormFather.validators"),n=null!==(o=globalThis[r])&&void 0!==o?o:globalThis[r]=new Map;function s(t,e,i,{override:o=!1}={}){!n.has(t)||o?n.set(t,{fn:e,defaultMessage:i}):console.warn(`[FormFather] Validator "${t}" already exists; pass { override: true } to replace`)}const a=t=>n.get(t);var l;s("required",((t,e,i)=>{if(e&&e.type){if("checkbox"===e.type)return e.checked;if("radio"===e.type){const t=i.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,i){var o;this.$submit=null,this.waitResponse=!1,this.inputs=null,this._anim={duration:220,easing:"ease",paddingTopOpened:16,iconDuration:700},this.$el=t,this.options=i;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,i),this.$el?(this.$submit=this.$el.querySelector('input[type="submit"], button[type="submit"]'),this._onSubmitClickHandler=t=>e(this,void 0,void 0,(function*(){var e,i,o,r;t.preventDefault(),null===(i=(e=this.config).onBeforeValidate)||void 0===i||i.call(e,this);const n=yield this.validate();null===(r=(o=this.config).onAfterValidate)||void 0===r||r.call(o,n,this),n&&(yield this.submit())})),null===(o=this.$submit)||void 0===o||o.addEventListener("click",this._onSubmitClickHandler),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),this._onSubmitHandler=t=>e(this,void 0,void 0,(function*(){var e,i,o,r;t.preventDefault(),null===(i=(e=this.config).onBeforeValidate)||void 0===i||i.call(e,this);const n=yield this.validate();null===(r=(o=this.config).onAfterValidate)||void 0===r||r.call(o,n,this),n&&this.submit()})),this.$el.addEventListener("submit",this._onSubmitHandler)}showError(t,e){(function(t,e){if(null==t)return null;let i=t;for(;i;){if(i.matches(e))return i;i=i.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`,i=document.createElement("span");i.innerHTML=e,i.className="button__loader",null===(t=this.$submit)||void 0===t||t.insertAdjacentElement("afterbegin",i),requestAnimationFrame((()=>{i.setAttribute("data-showed","")}))}hideLoader(){var t,e;null===(t=this.$submit)||void 0===t||t.classList.remove("button--loading");const i=null===(e=this.$submit)||void 0===e?void 0:e.querySelector(".button__loader");i&&(i.classList.remove("active"),i.removeAttribute("data-showed"),setTimeout((()=>{i.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 i=null,o=1/0;if(t.forEach((t=>{const r=e.findIndex((e=>e===t));r<o&&(o=r,i=t)})),i){const t=i.getBoundingClientRect(),e=window.pageYOffset||document.documentElement.scrollTop,o=t.top+e-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,arguments,void 0,(function*(t=this.$el){const i=Object.assign(Object.assign({},p.defaultValidationSchema||{}),this.config.validationSchema||{}),o=t=>console.warn(`[FormFather] Unknown validation rule "${t}"`),r=[],n=new WeakSet;let s=!0;const l=(t,e=[])=>{var i;const r=[];t.hasAttribute("required")&&r.push("required"),r.push(...e);const n=(null!==(i=t.getAttribute("data-custom-validate"))&&void 0!==i?i:"").split(",").map((t=>t.trim())).filter(Boolean);r.push(...n);const s=[];for(const t of r){const e="string"==typeof t?t:t.rule;a(e)?s.push(t):o(e)}return s},c=(i,o,...n)=>e(this,[i,o,...n],void 0,(function*(e,i,o={}){if(e.hasAttribute("data-no-validate"))return;if(!("checkbox"===e.type||"radio"===e.type?!e.checked:0===e.value.trim().length)||i.includes("required")){for(const n of i){const{rule:i,params:l}="string"==typeof n?{rule:n,params:void 0}:n,c=a(i),d=yield c.fn(e.value,e,t,l),u="object"==typeof d&&null!==d,p=u?!0===d.valid:!!d;if(u&&d.effect&&(yield d.effect({value:e.value,$input:e,$form:t,params:l})),!p){s=!1;const t=d,n=u&&"string"==typeof t.message&&t.message||o[i]||c.defaultMessage;return this.showError(e,n),void r.push(e)}if(u&&d.stopOthers)return}this.hideError(e)}else this.hideError(e)}));for(const[e,o]of Object.entries(i)){const{selector:i,rules:r=[],messages:s={}}=o,a=i?t.querySelectorAll(i):t.querySelectorAll(`[data-validate="${e}"]`);for(const t of Array.from(a))n.has(t)||(n.add(t),yield c(t,l(t,r),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(r.filter((t=>!t.hasAttribute("data-no-error-scroll")))),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 i=t;"radio"===i.type||"checkbox"===i.type?i.checked=!1:(i.value="",null===(e=i.parentElement)||void 0===e||e.classList.remove("filled"),i.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 i=this.$el.querySelectorAll(this.config.inputWrapperSelector),o=i[i.length-1];let r=this.$el.querySelector(".error-block-under-input__wrapper");r&&o.nextElementSibling===r?(r.style.boxSizing="border-box",r.style.overflow="hidden"):(r=document.createElement("div"),r.className="error-block-under-input__wrapper",r.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(r.style,{boxSizing:"border-box",overflow:"hidden",height:"0px",paddingTop:"0px",opacity:"0"}),o.insertAdjacentElement("afterend",r)),r.querySelector(".error-block-under-input__main-text").textContent=t;const n=r.querySelector(".error-block-under-input__secondary-text");n&&(n.textContent=""),null===(e=r.querySelector(".error-block-under-input"))||void 0===e||e.classList.remove("error-block-under-input--success"),r.querySelector(".error-block-under-input");const s=r.style.height,a=r.style.paddingTop;r.style.height="auto",r.style.paddingTop=`${this._anim.paddingTopOpened}px`;const l=r.clientHeight;if(r.style.height=s||"0px",r.style.paddingTop=a||"0px",parseFloat(r.style.height)===l&&1===parseFloat(r.style.opacity||"1"))this._ringIcon(r);else{if(this._cancelAnimations(r),this._canAnimate(r)){r.animate([{height:`${parseFloat(r.style.height)||0}px`,paddingTop:`${parseFloat(r.style.paddingTop)||0}px`,opacity:parseFloat(r.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",(()=>{r.style.height="auto",r.style.paddingTop=`${this._anim.paddingTopOpened}px`,r.style.opacity="1"}))}else r.style.height="auto",r.style.paddingTop=`${this._anim.paddingTopOpened}px`,r.style.opacity="1";this._ringIcon(r)}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"}))}destroy(){var t,e,i;this._onSubmitHandler&&(this.$el.removeEventListener("submit",this._onSubmitHandler),this._onSubmitHandler=void 0),this._onSubmitClickHandler&&(null===(t=this.$submit)||void 0===t||t.removeEventListener("click",this._onSubmitClickHandler),this._onSubmitClickHandler=void 0);const o=this.$el.querySelector(".error-block-under-input__wrapper");o&&(this._cancelAnimations(o),o.remove()),null===(e=this.$submit)||void 0===e||e.classList.remove("button--loading");const r=null===(i=this.$submit)||void 0===i?void 0:i.querySelector(".button__loader");r&&r.remove();this.$el.querySelectorAll("input, textarea").forEach((t=>{t instanceof HTMLInputElement&&this.hideError(t)})),document.documentElement.removeAttribute("data-now-scrolling"),this.inputs=null,this.$submit=null,this.waitResponse=!1}isCorrectArguments(){return"FORM"!==this.$el.tagName?(console.warn("$el не является тегом form"),!1):!!this.$submit||(console.warn("В форме нет кнопки с типом submit"),!1)}sendData(){return e(this,void 0,void 0,(function*(){var t;const e=this.$el.getAttribute("action")||"",o=(null===(t=this.$el.getAttribute("method"))||void 0===t?void 0:t.toUpperCase())||"POST",r=this.$el.getAttribute("enctype")||"application/x-www-form-urlencoded";let n=null,s={};const a=i(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)),r){case"application/x-www-form-urlencoded":n=new URLSearchParams(i(this.$el)).toString(),s["Content-Type"]="application/x-www-form-urlencoded";break;case"multipart/form-data":n=i(this.$el);break;case"text/plain":n=Array.from(i(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: ${r}. Используется application/x-www-form-urlencoded.`),n=new URLSearchParams(i(this.$el)).toString(),s["Content-Type"]="application/x-www-form-urlencoded"}return fetch(e,{method:o,body:n,headers:s})}))}submit(){return e(this,void 0,void 0,(function*(){var t,e,i,o,r,n,s,a;if(!this.waitResponse){!0===this.config.showLoaderButton&&this.showLoader(),null===(e=(t=this.config).onSubmit)||void 0===e||e.call(t,this),this.waitResponse=!0;const l=yield this.sendData(),c=yield l.json();if(this.waitResponse=!1,!0===this.config.showLoaderButton&&this.hideLoader(),null===(o=(i=this.config).onResponse)||void 0===o||o.call(i,c,this),200===l.status){if(!0===c.success)null===(n=(r=this.config).onResponseSuccess)||void 0===n||n.call(r,c,this);else if(null===(a=(s=this.config).onResponseUnsuccess)||void 0===a||a.call(s,c,this),!0===c.error&&(c["error-msg"]&&this.showErrorForm(c["error-msg"]),c.errors)){const t=[];c.errors.forEach((e=>{const i=this.$el.querySelector(`input[name="${e.name}"]`);i?(t.push(i),this.showError(i,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"))if(t["redirect-url-delay"]){const e=Number(t["redirect-url-delay"]);setTimeout((()=>{window.location.href=t["redirect-url"]}),e)}else window.location.href=t["redirect-url"];else if(Object.prototype.hasOwnProperty.call(t,"reload")){if(!0===t.reload)if(t["reload-delay"]){const e=Number(t["reload-delay"]);setTimeout((()=>{window.location.reload()}),e)}else 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"])}(c)}}}))}}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
|
@@ -109,6 +109,7 @@ declare class Form {
|
|
|
109
109
|
private waitResponse;
|
|
110
110
|
private inputs;
|
|
111
111
|
private _onSubmitHandler?;
|
|
112
|
+
private _onSubmitClickHandler?;
|
|
112
113
|
private static get defaultParams();
|
|
113
114
|
private static set defaultParams(value);
|
|
114
115
|
static get defaultValidationSchema(): ValidationSchema;
|
|
@@ -195,6 +196,8 @@ declare class Form {
|
|
|
195
196
|
* @returns {boolean} Корректны данные или нет (true/false).
|
|
196
197
|
*/
|
|
197
198
|
private isCorrectArguments;
|
|
199
|
+
private sendData;
|
|
200
|
+
private submit;
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
export { type ValidatorEffectCtx, type ValidatorResult, Form as default, getAllValidators, getValidator, registerValidator };
|
package/index.js
CHANGED
|
@@ -161,11 +161,27 @@ function serializeToFormData($element) {
|
|
|
161
161
|
*/
|
|
162
162
|
function parseCommonResponseProperties(responseBody) {
|
|
163
163
|
if (Object.prototype.hasOwnProperty.call(responseBody, 'redirect-url')) {
|
|
164
|
-
|
|
164
|
+
if (responseBody['redirect-url-delay']) {
|
|
165
|
+
const redirectUrlDelay = Number(responseBody['redirect-url-delay']);
|
|
166
|
+
setTimeout(() => {
|
|
167
|
+
window.location.href = responseBody['redirect-url'];
|
|
168
|
+
}, redirectUrlDelay);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
window.location.href = responseBody['redirect-url'];
|
|
172
|
+
}
|
|
165
173
|
}
|
|
166
174
|
else if (Object.prototype.hasOwnProperty.call(responseBody, 'reload')) {
|
|
167
175
|
if (responseBody.reload === true) {
|
|
168
|
-
|
|
176
|
+
if (responseBody['reload-delay']) {
|
|
177
|
+
const reloadDelay = Number(responseBody['reload-delay']);
|
|
178
|
+
setTimeout(() => {
|
|
179
|
+
window.location.reload();
|
|
180
|
+
}, reloadDelay);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
window.location.reload();
|
|
184
|
+
}
|
|
169
185
|
}
|
|
170
186
|
}
|
|
171
187
|
// Не показываем тост если делается редирект или обновление страницы (чтобы небыло вспышек) - в этом случае тосты обрабытываются в ответе onResponseSuccess | onResponseUnsuccess
|
|
@@ -279,6 +295,7 @@ class Form {
|
|
|
279
295
|
* @param {Object} options - Параметры формы.
|
|
280
296
|
*/
|
|
281
297
|
constructor($el, options) {
|
|
298
|
+
var _a;
|
|
282
299
|
this.$submit = null;
|
|
283
300
|
this.waitResponse = false;
|
|
284
301
|
this.inputs = null;
|
|
@@ -308,6 +325,17 @@ class Form {
|
|
|
308
325
|
this.config = Object.assign({}, defaultConfig, Form.defaultParams, options);
|
|
309
326
|
if (this.$el) {
|
|
310
327
|
this.$submit = this.$el.querySelector('input[type="submit"], button[type="submit"]');
|
|
328
|
+
this._onSubmitClickHandler = (e) => __awaiter(this, void 0, void 0, function* () {
|
|
329
|
+
var _a, _b, _c, _d;
|
|
330
|
+
e.preventDefault();
|
|
331
|
+
(_b = (_a = this.config).onBeforeValidate) === null || _b === void 0 ? void 0 : _b.call(_a, this);
|
|
332
|
+
const isValid = yield this.validate();
|
|
333
|
+
(_d = (_c = this.config).onAfterValidate) === null || _d === void 0 ? void 0 : _d.call(_c, isValid, this);
|
|
334
|
+
if (isValid) {
|
|
335
|
+
yield this.submit();
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
(_a = this.$submit) === null || _a === void 0 ? void 0 : _a.addEventListener('click', this._onSubmitClickHandler);
|
|
311
339
|
if (this.isCorrectArguments())
|
|
312
340
|
this.initialization();
|
|
313
341
|
}
|
|
@@ -340,101 +368,6 @@ class Form {
|
|
|
340
368
|
// else this.disableSubmit();
|
|
341
369
|
// });
|
|
342
370
|
// }
|
|
343
|
-
const sendData = () => __awaiter(this, void 0, void 0, function* () {
|
|
344
|
-
var _a;
|
|
345
|
-
const action = this.$el.getAttribute('action') || '';
|
|
346
|
-
const method = ((_a = this.$el.getAttribute('method')) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'POST';
|
|
347
|
-
const enctype = this.$el.getAttribute('enctype') || 'application/x-www-form-urlencoded';
|
|
348
|
-
let body = null;
|
|
349
|
-
let headers = {};
|
|
350
|
-
// Сбор данных из формы
|
|
351
|
-
const formData = serializeToFormData(this.$el);
|
|
352
|
-
let data = {};
|
|
353
|
-
formData.forEach((value, key) => {
|
|
354
|
-
data[key] = value;
|
|
355
|
-
});
|
|
356
|
-
if (this.config.logging) {
|
|
357
|
-
for (const key of formData.keys())
|
|
358
|
-
console.log(formData.get(key));
|
|
359
|
-
}
|
|
360
|
-
// Применение обёртки, если указано в настройках
|
|
361
|
-
if (typeof this.config.wrapData === 'function') {
|
|
362
|
-
data = this.config.wrapData(data);
|
|
363
|
-
}
|
|
364
|
-
switch (enctype) {
|
|
365
|
-
case 'application/x-www-form-urlencoded':
|
|
366
|
-
body = new URLSearchParams(serializeToFormData(this.$el)).toString();
|
|
367
|
-
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
368
|
-
break;
|
|
369
|
-
case 'multipart/form-data':
|
|
370
|
-
body = serializeToFormData(this.$el);
|
|
371
|
-
// ВАЖНО: Не указываем Content-Type, т.к. браузер сам добавит с корректной границей!
|
|
372
|
-
break;
|
|
373
|
-
case 'text/plain':
|
|
374
|
-
body = Array.from(serializeToFormData(this.$el))
|
|
375
|
-
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
|
376
|
-
.join('\n');
|
|
377
|
-
headers['Content-Type'] = 'text/plain';
|
|
378
|
-
break;
|
|
379
|
-
case 'application/json':
|
|
380
|
-
body = JSON.stringify(data);
|
|
381
|
-
headers['Content-Type'] = 'application/json';
|
|
382
|
-
break;
|
|
383
|
-
default:
|
|
384
|
-
console.warn(`Неизвестный enctype: ${enctype}. Используется application/x-www-form-urlencoded.`);
|
|
385
|
-
body = new URLSearchParams(serializeToFormData(this.$el)).toString();
|
|
386
|
-
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
387
|
-
}
|
|
388
|
-
return fetch(action, {
|
|
389
|
-
method,
|
|
390
|
-
body,
|
|
391
|
-
headers,
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
const submit = () => __awaiter(this, void 0, void 0, function* () {
|
|
395
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
396
|
-
if (!this.waitResponse) {
|
|
397
|
-
if (this.config.showLoaderButton === true)
|
|
398
|
-
this.showLoader();
|
|
399
|
-
(_b = (_a = this.config).onSubmit) === null || _b === void 0 ? void 0 : _b.call(_a, this);
|
|
400
|
-
this.waitResponse = true;
|
|
401
|
-
const response = yield sendData();
|
|
402
|
-
const responseBody = yield response.json();
|
|
403
|
-
this.waitResponse = false;
|
|
404
|
-
if (this.config.showLoaderButton === true)
|
|
405
|
-
this.hideLoader();
|
|
406
|
-
(_d = (_c = this.config).onResponse) === null || _d === void 0 ? void 0 : _d.call(_c, responseBody, this);
|
|
407
|
-
if (response.status === 200) {
|
|
408
|
-
if (responseBody.success === true) {
|
|
409
|
-
(_f = (_e = this.config).onResponseSuccess) === null || _f === void 0 ? void 0 : _f.call(_e, responseBody, this);
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
(_h = (_g = this.config).onResponseUnsuccess) === null || _h === void 0 ? void 0 : _h.call(_g, responseBody, this);
|
|
413
|
-
if (responseBody.error === true) {
|
|
414
|
-
if (responseBody['error-msg']) {
|
|
415
|
-
this.showErrorForm(responseBody['error-msg']);
|
|
416
|
-
}
|
|
417
|
-
if (responseBody.errors) {
|
|
418
|
-
const inputsList = [];
|
|
419
|
-
responseBody.errors.forEach(error => {
|
|
420
|
-
const $input = this.$el.querySelector(`input[name="${error.name}"]`);
|
|
421
|
-
if ($input) {
|
|
422
|
-
inputsList.push($input);
|
|
423
|
-
this.showError($input, error['error-msg']);
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
console.warn(`Не найдено поле с именем: ${error.name}, для вывода ошибки: ${error['error-msg']}`);
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
if (this.config.scrollToFirstErroredInput === true)
|
|
430
|
-
this.scrollToFirstErroredInput(inputsList);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
parseCommonResponseProperties(responseBody);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
371
|
this._onSubmitHandler = (e) => __awaiter(this, void 0, void 0, function* () {
|
|
439
372
|
var _a, _b, _c, _d;
|
|
440
373
|
e.preventDefault();
|
|
@@ -442,7 +375,7 @@ class Form {
|
|
|
442
375
|
const isValid = yield this.validate();
|
|
443
376
|
(_d = (_c = this.config).onAfterValidate) === null || _d === void 0 ? void 0 : _d.call(_c, isValid, this);
|
|
444
377
|
if (isValid)
|
|
445
|
-
submit();
|
|
378
|
+
this.submit();
|
|
446
379
|
});
|
|
447
380
|
this.$el.addEventListener('submit', this._onSubmitHandler);
|
|
448
381
|
}
|
|
@@ -845,12 +778,17 @@ class Form {
|
|
|
845
778
|
}
|
|
846
779
|
/** Полностью снимает слушатели и чистит артефакты формы. */
|
|
847
780
|
destroy() {
|
|
848
|
-
var _a, _b;
|
|
781
|
+
var _a, _b, _c;
|
|
849
782
|
// 1) Снять submit-слушатель
|
|
850
783
|
if (this._onSubmitHandler) {
|
|
851
784
|
this.$el.removeEventListener('submit', this._onSubmitHandler);
|
|
852
785
|
this._onSubmitHandler = undefined;
|
|
853
786
|
}
|
|
787
|
+
// 1.1) Снять click-слушатель с кнопки submit
|
|
788
|
+
if (this._onSubmitClickHandler) {
|
|
789
|
+
(_a = this.$submit) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', this._onSubmitClickHandler);
|
|
790
|
+
this._onSubmitClickHandler = undefined;
|
|
791
|
+
}
|
|
854
792
|
// 2) Удалить формовый error-блок под инпутами (если есть)
|
|
855
793
|
const formErrorWrapper = this.$el.querySelector('.error-block-under-input__wrapper');
|
|
856
794
|
if (formErrorWrapper) {
|
|
@@ -858,8 +796,8 @@ class Form {
|
|
|
858
796
|
formErrorWrapper.remove();
|
|
859
797
|
}
|
|
860
798
|
// 3) Скрыть/удалить лоадер на кнопке submit
|
|
861
|
-
(
|
|
862
|
-
const btnLoader = (
|
|
799
|
+
(_b = this.$submit) === null || _b === void 0 ? void 0 : _b.classList.remove('button--loading');
|
|
800
|
+
const btnLoader = (_c = this.$submit) === null || _c === void 0 ? void 0 : _c.querySelector('.button__loader');
|
|
863
801
|
if (btnLoader)
|
|
864
802
|
btnLoader.remove();
|
|
865
803
|
// 4) Сбросить ошибки у инпутов (если разметка позволяет)
|
|
@@ -891,6 +829,105 @@ class Form {
|
|
|
891
829
|
}
|
|
892
830
|
return true;
|
|
893
831
|
}
|
|
832
|
+
sendData() {
|
|
833
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
834
|
+
var _a;
|
|
835
|
+
const action = this.$el.getAttribute('action') || '';
|
|
836
|
+
const method = ((_a = this.$el.getAttribute('method')) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'POST';
|
|
837
|
+
const enctype = this.$el.getAttribute('enctype') || 'application/x-www-form-urlencoded';
|
|
838
|
+
let body = null;
|
|
839
|
+
let headers = {};
|
|
840
|
+
// Сбор данных из формы
|
|
841
|
+
const formData = serializeToFormData(this.$el);
|
|
842
|
+
let data = {};
|
|
843
|
+
formData.forEach((value, key) => {
|
|
844
|
+
data[key] = value;
|
|
845
|
+
});
|
|
846
|
+
if (this.config.logging) {
|
|
847
|
+
for (const key of formData.keys())
|
|
848
|
+
console.log(formData.get(key));
|
|
849
|
+
}
|
|
850
|
+
// Применение обёртки, если указано в настройках
|
|
851
|
+
if (typeof this.config.wrapData === 'function') {
|
|
852
|
+
data = this.config.wrapData(data);
|
|
853
|
+
}
|
|
854
|
+
switch (enctype) {
|
|
855
|
+
case 'application/x-www-form-urlencoded':
|
|
856
|
+
body = new URLSearchParams(serializeToFormData(this.$el)).toString();
|
|
857
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
858
|
+
break;
|
|
859
|
+
case 'multipart/form-data':
|
|
860
|
+
body = serializeToFormData(this.$el);
|
|
861
|
+
// ВАЖНО: Не указываем Content-Type, т.к. браузер сам добавит с корректной границей!
|
|
862
|
+
break;
|
|
863
|
+
case 'text/plain':
|
|
864
|
+
body = Array.from(serializeToFormData(this.$el))
|
|
865
|
+
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
|
866
|
+
.join('\n');
|
|
867
|
+
headers['Content-Type'] = 'text/plain';
|
|
868
|
+
break;
|
|
869
|
+
case 'application/json':
|
|
870
|
+
body = JSON.stringify(data);
|
|
871
|
+
headers['Content-Type'] = 'application/json';
|
|
872
|
+
break;
|
|
873
|
+
default:
|
|
874
|
+
console.warn(`Неизвестный enctype: ${enctype}. Используется application/x-www-form-urlencoded.`);
|
|
875
|
+
body = new URLSearchParams(serializeToFormData(this.$el)).toString();
|
|
876
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
877
|
+
}
|
|
878
|
+
return fetch(action, {
|
|
879
|
+
method,
|
|
880
|
+
body,
|
|
881
|
+
headers,
|
|
882
|
+
});
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
submit() {
|
|
886
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
887
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
888
|
+
if (!this.waitResponse) {
|
|
889
|
+
if (this.config.showLoaderButton === true)
|
|
890
|
+
this.showLoader();
|
|
891
|
+
(_b = (_a = this.config).onSubmit) === null || _b === void 0 ? void 0 : _b.call(_a, this);
|
|
892
|
+
this.waitResponse = true;
|
|
893
|
+
const response = yield this.sendData();
|
|
894
|
+
const responseBody = yield response.json();
|
|
895
|
+
this.waitResponse = false;
|
|
896
|
+
if (this.config.showLoaderButton === true)
|
|
897
|
+
this.hideLoader();
|
|
898
|
+
(_d = (_c = this.config).onResponse) === null || _d === void 0 ? void 0 : _d.call(_c, responseBody, this);
|
|
899
|
+
if (response.status === 200) {
|
|
900
|
+
if (responseBody.success === true) {
|
|
901
|
+
(_f = (_e = this.config).onResponseSuccess) === null || _f === void 0 ? void 0 : _f.call(_e, responseBody, this);
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
(_h = (_g = this.config).onResponseUnsuccess) === null || _h === void 0 ? void 0 : _h.call(_g, responseBody, this);
|
|
905
|
+
if (responseBody.error === true) {
|
|
906
|
+
if (responseBody['error-msg']) {
|
|
907
|
+
this.showErrorForm(responseBody['error-msg']);
|
|
908
|
+
}
|
|
909
|
+
if (responseBody.errors) {
|
|
910
|
+
const inputsList = [];
|
|
911
|
+
responseBody.errors.forEach(error => {
|
|
912
|
+
const $input = this.$el.querySelector(`input[name="${error.name}"]`);
|
|
913
|
+
if ($input) {
|
|
914
|
+
inputsList.push($input);
|
|
915
|
+
this.showError($input, error['error-msg']);
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
console.warn(`Не найдено поле с именем: ${error.name}, для вывода ошибки: ${error['error-msg']}`);
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
if (this.config.scrollToFirstErroredInput === true)
|
|
922
|
+
this.scrollToFirstErroredInput(inputsList);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
parseCommonResponseProperties(responseBody);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
}
|
|
894
931
|
}
|
|
895
932
|
|
|
896
933
|
export { Form as default, getAllValidators, getValidator, registerValidator };
|
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
package/types/index.d.ts
CHANGED
|
@@ -84,6 +84,7 @@ export default class Form {
|
|
|
84
84
|
private waitResponse;
|
|
85
85
|
private inputs;
|
|
86
86
|
private _onSubmitHandler?;
|
|
87
|
+
private _onSubmitClickHandler?;
|
|
87
88
|
private static get defaultParams();
|
|
88
89
|
private static set defaultParams(value);
|
|
89
90
|
static get defaultValidationSchema(): ValidationSchema;
|
|
@@ -170,4 +171,6 @@ export default class Form {
|
|
|
170
171
|
* @returns {boolean} Корректны данные или нет (true/false).
|
|
171
172
|
*/
|
|
172
173
|
private isCorrectArguments;
|
|
174
|
+
private sendData;
|
|
175
|
+
private submit;
|
|
173
176
|
}
|