form-father 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/FormFather.min.js CHANGED
@@ -1,2 +1,2 @@
1
- var FormFather=function(){"use strict";function t(t,e,r,n){return new(r||(r=Promise))((function(o,s){function i(t){try{c(n.next(t))}catch(t){s(t)}}function l(t){try{c(n.throw(t))}catch(t){s(t)}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(i,l)}c((n=n.apply(t,e||[])).next())}))}function e(t){const e="FORM"===t.tagName?Array.from(t.elements):Array.from(t.querySelectorAll("input, select, textarea, button")),r=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:n}=t;if("file"===n)if("true"===t.getAttribute("multiple")){const n=t.files;if(n)for(let t=0;t<n.length;t++)r.append(`${e}[${t}]`,n[t])}else{const n=t.files;n&&n[0]&&r.append(e,n[0])}else{let o;if("tel"===n)o=t.value.split(/[\s()-]/).join("").replace(/^8/,"+7");else if("checkbox"===n||"radio"===n){if(!t.checked)return;o=t.value}else if("date"===n){const e=t.getAttribute("data-date-format");o=e?function(t,e){const r=new Date(t),n=t=>t.toString().padStart(2,"0"),o=n(r.getDate()),s=n(r.getMonth()+1),i=r.getFullYear().toString();return e.replace("dd",o).replace("mm",s).replace("yyyy",i)}(t.value,e):t.value}else o=t.value;r.append(e,o)}})),r}"function"==typeof SuppressedError&&SuppressedError;class r{constructor(t,e){this.$submit=null,this.waitResponse=!1,this.inputs=null,this.$licensesCheckbox=null,this.$el=t,this.options=e;this.config=Object.assign({},{onSubmit:()=>{},onResponse:()=>{},onResponseSuccess:()=>{},onResponseUnsuccess:()=>{},customTypeError:null,loaderColor:"#fff",showLoaderButton:!0,scrollToFirstErroredInput:!0,logging:!1},r.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(".input"),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=>t(this,void 0,void 0,(function*(){return fetch(this.$el.getAttribute("action")||"",{method:"POST",body:e})})),n=()=>t(this,void 0,void 0,(function*(){var t,n,o,s,i,l,c,a;if(!this.waitResponse){const u=e(this.$el);if(!0===this.config.showLoaderButton&&this.showLoader(),null===(n=(t=this.config).onSubmit)||void 0===n||n.call(t,this),this.waitResponse=!0,this.config.logging)for(const t of u.keys())console.log(u.get(t));const h=yield r(u),d=yield h.json();if(this.waitResponse=!1,!0===this.config.showLoaderButton&&this.hideLoader(),null===(s=(o=this.config).onResponse)||void 0===s||s.call(o,d,this),200===h.status)if(function(t){if(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,"error-toast")){const e=document.querySelector('[data-toast-name="formErrorToast"]');if(e){const r=e.querySelector(".toast__text");r&&(r.textContent=t["error-toast"],window.Toast.showToast("formErrorToast",{removeAfterClose:!1}))}}}(d),!0===d.success)null===(l=(i=this.config).onResponseSuccess)||void 0===l||l.call(i,d,this);else if(null===(a=(c=this.config).onResponseUnsuccess)||void 0===a||a.call(c,d,this),!0===d.error&&(d["error-msg"]&&this.showErrorForm(d["error-msg"]),d.errors)){const t=[];d.errors.forEach((e=>{const r=this.$el.querySelector(`input[name="${e.name}"]`);r?(t.push(r),this.showError(r,e["error-msg"])):console.warn(`Не найдено поле с именем: ${e.name}, для вывода ошибки: ${e["error-msg"]}`)})),!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(t)}}}));this.$el.addEventListener("submit",(t=>{t.preventDefault(),this.checkInputs()&&(!this.$licensesCheckbox||this.$licensesCheckbox&&this.$licensesCheckbox.checked)&&n()}))}showError(t,e){(function(t,e){if(null==t)return null;let r=t;for(;r;){if(r.matches(e))return r;r=r.parentElement}return null})(t,"input-primary").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="a" 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(#a)"></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=e,r.className="button__loader",null===(t=this.$submit)||void 0===t||t.insertAdjacentElement("afterbegin",r),requestAnimationFrame((()=>{r.setAttribute("data-showed","")}))}hideLoader(){var t,e;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.classList.remove("active"),r.removeAttribute("data-showed"),setTimeout((()=>{r.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 r=null,n=1/0;t.forEach((t=>{const o=e.findIndex((e=>e===t));o<n&&(n=o,r=t)})),r&&(document.documentElement.setAttribute("data-now-scrolling",""),r.scrollIntoView({behavior:"smooth",block:"center",inline:"center"}),setTimeout((()=>{document.documentElement.removeAttribute("data-now-scrolling")}),800))}}checkInputs(){var t;let e=!0;const r={},n=[];if(null===(t=this.inputs)||void 0===t||t.forEach((t=>{var o;const s=t,i=s.getAttribute("data-check-type")||s.getAttribute("type")||"";if((null===(o=this.config.customTypeError)||void 0===o?void 0:o.name)!==i||"TEXTAREA"===s.tagName&&!this.config.customTypeError)if(s.value.length>0){if("email"===i&&(l=s.value,/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/iu.test(l)||(this.showError(s,"Неверный формат"),n.push(s),e=!1)),"tel"===i){const t=this.config.validatePhone||(t=>function(t){const e=[];return Array.from(t).forEach((t=>{(Number(t)||0===Number(t))&&e.push(t)})),!(e.length<11||e.length<12&&"+"===t[1])}(t.value));t(s)||(this.showError(s,"Неверный формат"),n.push(s),e=!1)}if("url"===i&&(function(t){const e=/^https?:\/\//i.test(t)?t:`http://${t}`;try{return new URL(e),!0}catch(t){return!1}}(s.value)||(this.showError(s,"Неверный формат"),n.push(s),e=!1)),"text"===i&&"not-numbers"===s.getAttribute("data-check-type")&&/[0-9]/.test(s.value)&&(this.showError(s,"Неверный формат"),n.push(s),e=!1),"radio"===i){const t=s.getAttribute("name")||"";r[t]||(r[t]={}),r[t][Object.keys(r[t]).length]=s}}else s.hasAttribute("required")&&(this.showError(s,"Пустое значение"),n.push(s),e=!1);var l})),Object.keys(r).length>0)for(const t in r){const e=r[t];let n=!1,o=null;for(const t in e){const r=e[t];if(r.hasAttribute("required")&&(n=!0),r.checked){if(null!==o)return!1;o=r}}if(null===o&&n)return this.showErrorForm("Необходимо указать оценку"),!1}return!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(n),e}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 r=t;"radio"===r.type?r.checked=!1:(r.value="",null===(e=r.parentElement)||void 0===e||e.classList.remove("filled"),r.dispatchEvent(new Event("input")))}))}showErrorForm(t){var e;const r=this.$el.querySelectorAll(".input__wrapper"),n=r[r.length-1];let o=this.$el.querySelector(".error-block-under-input__wrapper");o&&n.nextElementSibling===o?(o.classList.add("error-block-under-input--warning"),o.querySelector(".error-block-under-input__icon").innerHTML="\x3c!-- SVG content --\x3e",o.querySelector(".error-block-under-input__main-text").textContent=t):(o=document.createElement("div"),o.className="error-block-under-input__wrapper",o.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">${t}</span>\n <span class="error-block-under-input__secondary-text"></span>\n </p>\n </div>`,n.insertAdjacentElement("afterend",o)),this.$el.addEventListener("input",(()=>{this.hideErrorForm()}),{passive:!0,once:!0}),null===(e=o.querySelector(".error-block-under-input"))||void 0===e||e.classList.remove("error-block-under-input--success");const s=o.querySelector(".error-block-under-input__secondary-text");s&&(s.textContent="");const i=parseFloat(o.style.height)||0,l=parseFloat(window.getComputedStyle(o).paddingTop)||0;i!==o.querySelector(".error-block-under-input").scrollHeight+16&&(o.style.height=`${i}px`,o.style.opacity="0",o.style.paddingTop=`${l}px`)}hideErrorForm(){const t=this.$el.querySelectorAll(".input__wrapper"),e=t[t.length-1].nextElementSibling;e&&e.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 r.defaultParams={},r}();
1
+ var FormFather=function(){"use strict";function t(t,e,r,o){return new(r||(r=Promise))((function(n,s){function i(t){try{c(o.next(t))}catch(t){s(t)}}function l(t){try{c(o.throw(t))}catch(t){s(t)}}function c(t){var e;t.done?n(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(i,l)}c((o=o.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class e{constructor(t,r){this.$submit=null,this.waitResponse=!1,this.inputs=null,this.$licensesCheckbox=null,this.$el=t,this.options=r;this.config=Object.assign({},{onSubmit:()=>{},onResponse:()=>{},onResponseSuccess:()=>{},onResponseUnsuccess:()=>{},customTypeError:null,loaderColor:"#fff",showLoaderButton:!0,scrollToFirstErroredInput:!0,logging:!1},e.defaultParams,r),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(".input"),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 t;const e=this.$el.getAttribute("action")||"",r=(null===(t=this.$el.getAttribute("method"))||void 0===t?void 0:t.toUpperCase())||"POST",o=this.$el.getAttribute("enctype")||"application/x-www-form-urlencoded";let n=null,s={};const i=new FormData(this.$el);let l={};switch(i.forEach(((t,e)=>{l[e]=t})),"function"==typeof this.config.wrapData&&(l=this.config.wrapData(l)),o){case"application/x-www-form-urlencoded":n=new URLSearchParams(l).toString(),s["Content-Type"]="application/x-www-form-urlencoded";break;case"multipart/form-data":n=new FormData(this.$el);break;case"text/plain":n=Object.entries(l).map((([t,e])=>`${encodeURIComponent(t)}=${encodeURIComponent(e)}`)).join("\n"),s["Content-Type"]="text/plain";break;default:n=JSON.stringify(l),s["Content-Type"]="application/json"}return fetch(e,{method:r,body:n,headers:s})})),r=()=>t(this,void 0,void 0,(function*(){var t,r,o,n,s,i,l,c;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 a=yield e(),u=yield a.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===a.status)if(function(t){if(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,"error-toast")){const e=document.querySelector('[data-toast-name="formErrorToast"]');if(e){const r=e.querySelector(".toast__text");r&&(r.textContent=t["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===(c=(l=this.config).onResponseUnsuccess)||void 0===c||c.call(l,u,this),!0===u.error&&(u["error-msg"]&&this.showErrorForm(u["error-msg"]),u.errors)){const t=[];u.errors.forEach((e=>{const r=this.$el.querySelector(`input[name="${e.name}"]`);r?(t.push(r),this.showError(r,e["error-msg"])):console.warn(`Не найдено поле с именем: ${e.name}, для вывода ошибки: ${e["error-msg"]}`)})),!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(t)}}}));this.$el.addEventListener("submit",(t=>{t.preventDefault(),this.checkInputs()&&(!this.$licensesCheckbox||this.$licensesCheckbox&&this.$licensesCheckbox.checked)&&r()}))}showError(t,e){(function(t,e){if(null==t)return null;let r=t;for(;r;){if(r.matches(e))return r;r=r.parentElement}return null})(t,"input-primary").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="a" 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(#a)"></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=e,r.className="button__loader",null===(t=this.$submit)||void 0===t||t.insertAdjacentElement("afterbegin",r),requestAnimationFrame((()=>{r.setAttribute("data-showed","")}))}hideLoader(){var t,e;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.classList.remove("active"),r.removeAttribute("data-showed"),setTimeout((()=>{r.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 r=null,o=1/0;if(t.forEach((t=>{const n=e.findIndex((e=>e===t));n<o&&(o=n,r=t)})),r){const t=r.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)}}}checkInputs(){var t;let e=!0;const r={},o=[];if(null===(t=this.inputs)||void 0===t||t.forEach((t=>{var n;const s=t,i=s.getAttribute("data-check-type")||s.getAttribute("type")||"";if((null===(n=this.config.customTypeError)||void 0===n?void 0:n.name)!==i||"TEXTAREA"===s.tagName&&!this.config.customTypeError)if(s.value.length>0){if("email"===i&&(l=s.value,/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/iu.test(l)||(this.showError(s,"Неверный формат"),o.push(s),e=!1)),"tel"===i){const t=this.config.validatePhone||(t=>function(t){const e=[];return Array.from(t).forEach((t=>{(Number(t)||0===Number(t))&&e.push(t)})),!(e.length<11||e.length<12&&"+"===t[1])}(t.value));t(s)||(this.showError(s,"Неверный формат"),o.push(s),e=!1)}if("url"===i&&(function(t){const e=/^https?:\/\//i.test(t)?t:`http://${t}`;try{return new URL(e),!0}catch(t){return!1}}(s.value)||(this.showError(s,"Неверный формат"),o.push(s),e=!1)),"text"===i&&"not-numbers"===s.getAttribute("data-check-type")&&/[0-9]/.test(s.value)&&(this.showError(s,"Неверный формат"),o.push(s),e=!1),"radio"===i){const t=s.getAttribute("name")||"";r[t]||(r[t]={}),r[t][Object.keys(r[t]).length]=s}}else s.hasAttribute("required")&&(this.showError(s,"Пустое значение"),o.push(s),e=!1);var l})),Object.keys(r).length>0)for(const t in r){const e=r[t];let o=!1,n=null;for(const t in e){const r=e[t];if(r.hasAttribute("required")&&(o=!0),r.checked){if(null!==n)return!1;n=r}}if(null===n&&o)return this.showErrorForm("Необходимо указать оценку"),!1}return!0===this.config.scrollToFirstErroredInput&&this.scrollToFirstErroredInput(o),e}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 r=t;"radio"===r.type?r.checked=!1:(r.value="",null===(e=r.parentElement)||void 0===e||e.classList.remove("filled"),r.dispatchEvent(new Event("input")))}))}showErrorForm(t){var e;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=t):(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">${t}</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===(e=n.querySelector(".error-block-under-input"))||void 0===e||e.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 t=this.$el.querySelectorAll(".input__wrapper"),e=t[t.length-1].nextElementSibling;e&&e.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 e.defaultParams={},e}();
2
2
  //# sourceMappingURL=FormFather.min.js.map
package/index.d.ts CHANGED
@@ -39,6 +39,8 @@ interface FormOptions {
39
39
  logging?: boolean;
40
40
  /** Пользовательская функция для проверки телефона. По умолчанию стандартный `isPhoneValid` для русских номеров телефонов. */
41
41
  validatePhone?: (input: HTMLInputElement) => boolean;
42
+ /** Функция для обёртки отправляемых данных. */
43
+ wrapData?: (data: Record<string, any>) => Record<string, any>;
42
44
  }
43
45
  /**
44
46
  * Реализует форму отправки данных.
package/index.js CHANGED
@@ -38,21 +38,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
38
38
  *
39
39
  * @returns {string}
40
40
  */
41
- function formatDate(dateValue, format) {
42
- const date = new Date(dateValue);
43
- /**
44
- * Добавляет ведущие нули.
45
- *
46
- * @param {number} num
47
- *
48
- * @returns {string}
49
- */
50
- const pad = (num) => num.toString().padStart(2, '0');
51
- const day = pad(date.getDate());
52
- const month = pad(date.getMonth() + 1);
53
- const year = date.getFullYear().toString();
54
- return format.replace('dd', day).replace('mm', month).replace('yyyy', year);
55
- }
56
41
  /**
57
42
  * Находит родительский элемент по заданому селектору.
58
43
  *
@@ -117,70 +102,6 @@ function isPhoneValid(value) {
117
102
  return false;
118
103
  return true;
119
104
  }
120
- /**
121
- * Кастомная сериализация формы в объект FormData.
122
- *
123
- * @param {HTMLElement} $element - DOM элемент для сериализации.
124
- *
125
- * @returns {FormData} Сериализованные данные формы в объекте FormData.
126
- */
127
- function serializeToFormData($element) {
128
- const elements = $element.tagName === 'FORM'
129
- ? Array.from($element.elements)
130
- : Array.from($element.querySelectorAll('input, select, textarea, button'));
131
- const data = new FormData();
132
- elements.forEach(element => {
133
- if (!(element instanceof HTMLInputElement ||
134
- element instanceof HTMLSelectElement ||
135
- element instanceof HTMLTextAreaElement ||
136
- element instanceof HTMLButtonElement)) {
137
- return;
138
- }
139
- if (!element.name || element.hasAttribute('data-no-serialize')) {
140
- return;
141
- }
142
- const { name, type } = element;
143
- if (type === 'file') {
144
- if (element.getAttribute('multiple') === 'true') {
145
- const files = element.files;
146
- if (files) {
147
- for (let i = 0; i < files.length; i++) {
148
- // Добавляем каждый файл с уникальным ключом
149
- data.append(`${name}[${i}]`, files[i]);
150
- }
151
- }
152
- }
153
- else {
154
- const files = element.files;
155
- if (files && files[0])
156
- data.append(name, files[0]);
157
- }
158
- }
159
- else {
160
- let value;
161
- if (type === 'tel') {
162
- value = element.value
163
- .split(/[\s()-]/)
164
- .join('')
165
- .replace(/^8/, '+7');
166
- }
167
- else if (type === 'checkbox' || type === 'radio') {
168
- if (!element.checked)
169
- return;
170
- value = element.value;
171
- }
172
- else if (type === 'date') {
173
- const format = element.getAttribute('data-date-format');
174
- value = format ? formatDate(element.value, format) : element.value;
175
- }
176
- else {
177
- value = element.value;
178
- }
179
- data.append(name, value);
180
- }
181
- });
182
- return data;
183
- }
184
105
  /**
185
106
  * Функция для разбора общих свойств ответа.
186
107
  *
@@ -277,25 +198,56 @@ class Form {
277
198
  this.disableSubmit();
278
199
  });
279
200
  }
280
- const sendData = (data) => __awaiter(this, void 0, void 0, function* () {
281
- return fetch(this.$el.getAttribute('action') || '', {
282
- method: 'POST',
283
- body: data,
201
+ const sendData = () => __awaiter(this, void 0, void 0, function* () {
202
+ var _a;
203
+ const action = this.$el.getAttribute('action') || '';
204
+ const method = ((_a = this.$el.getAttribute('method')) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'POST';
205
+ const enctype = this.$el.getAttribute('enctype') || 'application/x-www-form-urlencoded';
206
+ let body = null;
207
+ let headers = {};
208
+ // Сбор данных из формы
209
+ const formData = new FormData(this.$el);
210
+ let data = {};
211
+ formData.forEach((value, key) => {
212
+ data[key] = value;
213
+ });
214
+ // Применение обёртки, если указано в настройках
215
+ if (typeof this.config.wrapData === 'function') {
216
+ data = this.config.wrapData(data);
217
+ }
218
+ switch (enctype) {
219
+ case 'application/x-www-form-urlencoded':
220
+ body = new URLSearchParams(data).toString();
221
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
222
+ break;
223
+ case 'multipart/form-data':
224
+ body = new FormData(this.$el);
225
+ break;
226
+ case 'text/plain':
227
+ body = Object.entries(data)
228
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
229
+ .join('\n');
230
+ headers['Content-Type'] = 'text/plain';
231
+ break;
232
+ case 'application/json':
233
+ default:
234
+ body = JSON.stringify(data);
235
+ headers['Content-Type'] = 'application/json';
236
+ }
237
+ return fetch(action, {
238
+ method,
239
+ body,
240
+ headers,
284
241
  });
285
242
  });
286
243
  const submit = () => __awaiter(this, void 0, void 0, function* () {
287
244
  var _a, _b, _c, _d, _e, _f, _g, _h;
288
245
  if (!this.waitResponse) {
289
- const data = serializeToFormData(this.$el);
290
246
  if (this.config.showLoaderButton === true)
291
247
  this.showLoader();
292
248
  (_b = (_a = this.config).onSubmit) === null || _b === void 0 ? void 0 : _b.call(_a, this);
293
249
  this.waitResponse = true;
294
- if (this.config.logging) {
295
- for (const key of data.keys())
296
- console.log(data.get(key));
297
- }
298
- const response = yield sendData(data);
250
+ const response = yield sendData();
299
251
  const responseBody = yield response.json();
300
252
  this.waitResponse = false;
301
253
  if (this.config.showLoaderButton === true)
@@ -420,11 +372,13 @@ class Form {
420
372
  }
421
373
  });
422
374
  if ($firstInputOnForm) {
375
+ const rect = $firstInputOnForm.getBoundingClientRect();
376
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
377
+ const scrollTargetY = rect.top + scrollTop - (window.innerHeight / 2);
423
378
  document.documentElement.setAttribute('data-now-scrolling', '');
424
- $firstInputOnForm.scrollIntoView({
379
+ window.scrollTo({
380
+ top: scrollTargetY,
425
381
  behavior: 'smooth',
426
- block: 'center',
427
- inline: 'center',
428
382
  });
429
383
  setTimeout(() => {
430
384
  document.documentElement.removeAttribute('data-now-scrolling');
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.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Form Father: Библиотека для обработки форм",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/types/index.d.ts CHANGED
@@ -39,6 +39,8 @@ interface FormOptions {
39
39
  logging?: boolean;
40
40
  /** Пользовательская функция для проверки телефона. По умолчанию стандартный `isPhoneValid` для русских номеров телефонов. */
41
41
  validatePhone?: (input: HTMLInputElement) => boolean;
42
+ /** Функция для обёртки отправляемых данных. */
43
+ wrapData?: (data: Record<string, any>) => Record<string, any>;
42
44
  }
43
45
  /**
44
46
  * Реализует форму отправки данных.