formique 1.0.7 → 1.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/README.md CHANGED
@@ -1,7 +1,31 @@
1
- # Formique
1
+ # Formique JS Form Builder Documentation
2
+
3
+ [![NPM](https://img.shields.io/npm/v/formique.svg)](https://www.npmjs.com/package/formique)
4
+ [![NPM Downloads](https://img.shields.io/npm/dt/formique.svg)](https://www.npmjs.com/package/formique)
5
+ [![GitHub Stars](https://img.shields.io/github/stars/Gugulethu-Nyoni/formique.svg)](https://github.com/Gugulethu-Nyoni/formique/stargazers)
6
+ [![GitHub Issues](https://img.shields.io/github/issues/Gugulethu-Nyoni/formique.svg)](https://github.com/Gugulethu-Nyoni/formique/issues)
7
+ <a href="https://github.com/Gugulethu-Nyoni/formique/blob/main/LICENSE">
8
+ <img alt="Formique uses the MIT license" src="https://img.shields.io/github/license/Gugulethu-Nyoni/formique" style="max-width: 100%;">
9
+ </a>
10
+ [![GitHub Workflow](https://img.shields.io/github/workflow/status/Gugulethu-Nyoni/formique/CI/main.svg)](https://github.com/Gugulethu-Nyoni/formique/actions)
2
11
 
3
12
  <img src="https://github.com/Gugulethu-Nyoni/formique/blob/main/images/formique-js-form-builder-anyframework.png" alt="Formique JS Form Builder Example">
4
13
 
14
+ ## Table of Contents
15
+ - [About Formique](#about-formique)
16
+ - [Why Choose Formique?](#why-choose-formique)
17
+ - [Form Input Types Covered](#form-input-types-covered)
18
+ - [How to Write Form Schema](#how-to-write-form-schema)
19
+ - [Installation](#installation)
20
+ - [Form Schema Example](#form-schema-example)
21
+ - [Dynamic Drop-Down Schema](#dynamic-drop-down-schema)
22
+ - [Nested Conditionality Logic - Schema Definition](#nested-conditionality-logic---schema-definition)
23
+ - [Styling the Form](#styling-the-form)
24
+ - [Testing Form Submission with submitOnPage](#testing-form-submission-with-submitonpage)
25
+ - [Contribute](#contribute)
26
+
27
+
28
+ ## About Formique
5
29
 
6
30
  Formique is a robust and elegant WCAG and ARIA compliant form-building library tailored for JavaScript enthusiasts. It supports a wide array of input types, features JS-driven themes, and offers advanced functionalities like nested conditional logic and dynamic dropdowns. Highly customizable and extensible, Formique is built for the Semantq JS Framework but seamlessly integrates with Vanilla JS, React, Vue, Angular, and Svelte.
7
31
 
@@ -162,13 +186,13 @@ There are two primary ways to install and use Formique in your project:
162
186
  1. **Include the CSS** in the head section of your HTML file:
163
187
 
164
188
  ```html
165
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.1/formique.min.css" formique-style>
189
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.6/formique.min.css" formique-style>
166
190
  ```
167
191
 
168
192
  2. **Include the JavaScript** before the closing `</body>` tag of your HTML file:
169
193
 
170
194
  ```html
171
- <script src="https://cdn.jsdelivr.net/npm/formique@1.0.1/formique.mjs.js"></script>
195
+ <script src="https://cdn.jsdelivr.net/npm/formique@1.0.8/formique.umd.min.js"></script>
172
196
  ```
173
197
 
174
198
  ### Usage Example:
@@ -258,7 +282,7 @@ Formique is also available in additional formats like **ESM (ES Modules)** and *
258
282
  2. Include the CSS and import Formique in the head section of your HTML file:
259
283
 
260
284
  ```html
261
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.1/formique.min.css" formique-style>
285
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.6/formique.min.css" formique-style>
262
286
  ```
263
287
  3. Define form container somewhere in the html body:
264
288
 
@@ -458,6 +482,50 @@ const formParams = {
458
482
  By customizing these parameters, you can control various aspects of the form's behavior and appearance.
459
483
 
460
484
 
485
+ # Complete List of Form Settings
486
+
487
+ The `formSettings` object allows you to customize the behavior and appearance of your form. Below is a comprehensive list of all possible settings:
488
+
489
+ # Form Settings
490
+
491
+ ```javascript
492
+ const formSettings = {
493
+ theme: "dark-blue", // Form theme: see section below on complete list of themes
494
+ submitOnPage: true, // Enable form submission on the same page
495
+ successMessage: "Your registration details have been captured successfully!", // Success message
496
+ errorMessage: "There was an error in submitting your details. Please try again!", // Error message
497
+ requiredFieldIndicator: true, // Display asterisk for required fields
498
+ framework: 'semantic', // Specify framework (optional)
499
+ placeholders: true, // Use labels as placeholders
500
+ containerId: 'form-div', // Target container by ID (optional)
501
+ };
502
+ ```
503
+
504
+ ## Detailed Explanation of Form Settings
505
+
506
+ - **theme**: Defines the appearance of the form. Options include `"dark-blue"`, `"light"`, and more, allowing for customization based on your application's UI.
507
+
508
+ - **submitOnPage**: Controls whether the form submission should happen on the same page (`true`) - omit if you don't need this feature.
509
+
510
+ - **successMessage**: The message displayed to the user after a successful form submission in the context of enabled submitOnPage. This can be customized to fit the context of the form. If submitOnPage is enabled and the successMessage parameter is not defined, Formique will display the default success message upon form submission: "Your details have been submitted successfully!"
511
+
512
+ - **errorMessage**: The message displayed when there is an error in form submission. The actual JSON response error is appended for detailed feedback. If submitOnPage is enabled and the errorMessage parameter is not defined, Formique will display the default error message upon form submission: "An error occurred while submitting the form. Please try again."
513
+
514
+ - **requiredFieldIndicator**: When set to `true`, a red asterisk (`*`) will appear next to fields marked as required, helping users easily identify mandatory fields.
515
+
516
+ - **framework**: Specifies the front-end framework used, such as `'semantq'`, `'svelte'`, `'vue'`, `'angular'`, or `'react'`. If you are not using any framework, this parameter can be omitted.
517
+
518
+ - **placeholders**: Enables labels to be shown as placeholders inside input fields, providing a cleaner look and saving space.
519
+
520
+ - **containerId**: Allows targeting a specific container by its ID where the form will be rendered. If the container ID is `'formique'`, this parameter can be omitted.
521
+
522
+ **All settings are optional:** You can use only the settings that are relevant to your needs.
523
+
524
+ Default Invocation: Just like the formParams object, if no formSettings object is provided, you can simply initialize Formique with the form schema as follows:
525
+
526
+ ```javascript
527
+ const form = new Formique(formSchema);
528
+ ```
461
529
 
462
530
 
463
531
  ## Example HTML Output
@@ -735,7 +803,7 @@ The following schema demonstrates how to implement dynamic dropdowns with nested
735
803
 
736
804
  ## Styling the Form
737
805
 
738
- Formique provides a set of CSS classes to facilitate the styling of various form elements. The default class names for different form components are as follows:
806
+ Additionally, Formique provides a set of CSS classes to facilitate the styling of various form elements. The default class names for different form components are as follows:
739
807
 
740
808
  - **Wrapper (div) for Input Elements:** `input-block`
741
809
  - **Input Fields:** `form-input`
@@ -743,16 +811,51 @@ Formique provides a set of CSS classes to facilitate the styling of various form
743
811
  - **Checkbox Groups:** `checkbox-group`
744
812
  - **Select Dropdowns:** `form-select`
745
813
 
746
- These classes are predefined in the `formique.css` stylesheet. Developers can either use this stylesheet for consistent styling or create their own custom CSS based on these class names to suit their design preferences. Also, Formique implements these class names by default. The input class can be overidden by defining your preferred class names in the input attributes object e.g.
814
+ These classes are predefined in the `formique.css` stylesheet. Developers can either use this stylesheet for consistent styling or create their own custom CSS based on these class names to suit their design preferences. Also, Formique implements these class names by default.
815
+
816
+ The input class can be overidden by defining your preferred class names in the input attributes object e.g.
747
817
 
748
818
  ```javascript
749
819
  { class: 'form-control' }
750
820
  ```
821
+ ## Testing Form Submission with `submitOnPage`
822
+
823
+ For testing purposes, you can define the `method` as `"POST"` in the `formParams` object. This allows you to simulate and test form submissions using Formique's built-in functionality.
824
+
825
+ ### Example:
826
+
827
+ ```javascript
828
+ const formParams = {
829
+ method: "POST",
830
+ // other params
831
+ };
832
+ ```
833
+
834
+ ## Configuration Steps:
835
+
836
+ - **Omit the `action` parameter** in the `formSettings`. This way, Formique will serialize the form data upon submission and send it to the `https://httpbin.org/post` endpoint.
751
837
 
838
+ - **Console Logging**: The response, along with the actual form data, will be logged in the browser's console, allowing you to review and verify the submission process.
839
+
840
+ ## How It Works:
841
+
842
+ - **Fetch API-Based Form Submission**: By omitting the `action` parameter, Formique uses the Fetch API to send the form data to `https://httpbin.org/post`. This sets up a functional testing environment where you can observe the data handling without needing an immediate backend setup.
843
+
844
+ - **Transition to Custom Endpoints**: Once you've tested the form submission, you can define your own `action` URL or endpoint in the `formParams` object. This allows you to direct the form data to your specified backend and handle it according to your application's needs.
845
+
846
+ ### Example for Custom Endpoint:
847
+
848
+ ```javascript
849
+ const formParams = {
850
+ method: "POST", // OR GET, ETC
851
+ action: "https://your-custom-endpoint.com/submit"
852
+ };
853
+ ```
854
+ This approach helps you smoothly transition from testing to production, giving you control over where and how your form data is processed.
752
855
 
753
856
  ### Inline Styling
754
857
 
755
- In addition to external stylesheets, individual form elements can be styled directly via attributes specified in the form schema. This allows for fine grained control over the appearance of each element.
858
+ In addition to external stylesheets, individual form elements can be styled directly via attributes specified in the form schema. This allows for fine grained control (inline styling) over the appearance of each element.
756
859
 
757
860
 
758
861
  ## Contribute
@@ -766,3 +869,6 @@ Formique is licensed under the MIT License.
766
869
  ## Keywords
767
870
 
768
871
  Javascript forms, declarative form syntax, js form library, formique
872
+
873
+ [![Get Started with Formique](https://img.shields.io/badge/Get_Started-FormiqueJS-blue)](https://www.formiquejs.com)
874
+
@@ -0,0 +1 @@
1
+ "use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}module.exports=class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{if(this.formMarkUp+=this.renderFormElement(),this.renderForm(),this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formId}`).addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this))}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}};
package/formique.mjs ADDED
@@ -0,0 +1 @@
1
+ class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}class n extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{if(this.formMarkUp+=this.renderFormElement(),this.renderForm(),this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formId}`).addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this))}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}export{n as default};
package/formique.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).Formique=n()}(this,(function(){"use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}return class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formParams=n,this.formContainerId=t.formContainerId||"formique",this.formAction=n.action||"https://httpbin.org/post",this.method=n.method.toUpperCase()||"POST",this.formMarkUp="",this.dependencyGraph={},this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","green","purple","midnight-blush"],document.addEventListener("DOMContentLoaded",(()=>{if(this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formParams.id}`).addEventListener("submit",(e=>{this.formSettings.submitOnPage&&(e.preventDefault(),this.handleOnPageFormSubmission(this.formParams.id))}))})),this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...t},Object.keys(this.formParams).length>0&&(this.formMarkUp+=this.renderFormElement()),this.renderForm()}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector("link[formique-style]");t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-style' not found!")}renderFormElement(){let e="<form\n";const n=this.formParams||{};for(const[t,i]of Object.entries(n))if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}\n`);else{e+=` ${"accept_charset"===t?"accept-charset":t.replace(/_/g,"-")}="${i}"\n`}if(e+=">\n",n.laravel){e+=`<input type="hidden" name="_token" value="${document.querySelector('meta[name="csrf-token"]').getAttribute("content")}">`}return e=e.replace(/\n\s*$/,"\n"),e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,password:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n;const o=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===o){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}"> \n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}"> \n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}"> \n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n;const o=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===o){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${d}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}"> \n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}"> \n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}"> \n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let d,o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${d}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,o="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?o+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${d}"\n class="${c}"\n ${o}\n ${r}\n ${o.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let d="";if(s.binding)if("bind:value"===s.binding&&n)d=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)d=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${d} \n ${c}\n ${s.id,`id="${o}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${o}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${o+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let d="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(d=` bind:checked="${n}"\n`);let o,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${d} ${$}\n ${s.id,`id="${t}"`}\n class="${o}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const d=["required"];let o="";i&&Object.entries(i).forEach((([t,i])=>{d.includes(t)?"required"===t&&(o+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,b;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,b=t}else h=t,b=t;else h=t;let g=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${o}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(g=g.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=g,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",b),r=b.includes("-")?b.split("-")?.[1]+" Options":"options",a="options"!==r?b.split("-")?.[1]+" Option":r;let d=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${o}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();d=d.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),d=d.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=d}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let d="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(d=` bind:value="${n}" `);let o=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${d}\n \n id="${o}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let d=`\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=d}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: formContainer not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}}));
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).Formique=n()}(this,(function(){"use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}return class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{if(this.formMarkUp+=this.renderFormElement(),this.renderForm(),this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formId}`).addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this))}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "formique",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Formique Declarative Form Syntax JavaScript Library",
5
5
  "main": "formique.umd.js",
6
6
  "module": "formique.mjs",
@@ -13,8 +13,10 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist/*",
17
- "README.md"
16
+ "formique.umd.js",
17
+ "formique.mjs",
18
+ "formique.cjs.js",
19
+ "README.md"
18
20
  ],
19
21
  "keywords": ["form", "javascript", "forms", "library"],
20
22
  "author": "Gugulethu Nyoni",
@@ -1,371 +0,0 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap');
2
-
3
- .dark-theme {
4
- --background-dark: #0A0A0A;
5
- --background-light: #1A1A1A;
6
- --text-light: #E5E5E5;
7
- --border-color: #333333;
8
- --input-background: #1C1C1C;
9
- --input-background-disabled: #2A2A2A;
10
- --label-color: #999999;
11
- --radio-checkbox-accent: #4A90E2;
12
- --button-background: #444444;
13
- --button-background-hover: #555555;
14
- --button-text-color: #E5E5E5;
15
- --input-border-color: #444444;
16
- --input-border-color-focus: #666666;
17
- --secondary-text-color: #B3B3B3;
18
- }
19
-
20
-
21
-
22
- .light-theme {
23
- --background-light: #ffffff;
24
- --background-dark: #1a1a1a;
25
- --text-light: #333333;
26
- --border-color: #cccccc;
27
- --input-background: #ffffff;
28
- --input-background-disabled: #e0e0e0;
29
- --label-color: #555555;
30
- --radio-checkbox-accent: #4A90E2;
31
- --button-background: #888888;
32
- --button-background-hover: #666666;
33
- --button-text-color: #ffffff;
34
- --input-border-color: #cccccc;
35
- --input-border-color-focus: #4A90E2;
36
- --secondary-text-color: #777777;
37
- }
38
-
39
- .pink-theme {
40
- --background-dark: red;
41
- --background-light: #05051e;
42
- --text-light: #fe8bbb;
43
- --border-color: pink;
44
- --input-background: #ffffff;
45
- --input-background-disabled: #f1f8e9;
46
- --label-color: #fe8bbb; /* #c2185b; */
47
- --radio-checkbox-accent: #c2185b;
48
- --button-background: #c2185b; /*#e91e63;*/
49
- --button-background-hover: #f01ff0;
50
- --button-text-color: #ffffff;
51
- --input-border-color: #05051e;
52
- --input-border-color-focus: #c2185b;
53
- --secondary-text-color: #880e4f;
54
- }
55
-
56
-
57
- .light-blue-theme {
58
- --background-light: #f0f8ff;
59
- --background-dark: #003b5c;
60
- --text-light: #fff;
61
- --text-dark: #000;
62
- --border-color: #0077b6;
63
- --input-background: #ffffff;
64
- --input-background-disabled: #d1e4f4;
65
- --label-color: #4a6572;
66
- --radio-checkbox-accent: #0091d3;
67
- --button-background: #1e3a8a;
68
- --button-background-hover: #0f2a5f;
69
- --button-text-color: #ffffff;
70
- --input-border-color: #0077b6;
71
- --input-border-color-focus: #00aaff;
72
- --secondary-text-color: #4f5b62;
73
- --dropdown-option-text-color: #003b5c;
74
- --legend-text-color: #1d3557;
75
-
76
- }
77
-
78
-
79
- .indigo-theme {
80
- --background-dark: #2c2c2c;
81
- --background-light: #3d3d3d;
82
- --text-light: #e0e0e0;
83
- --border-color: #444;
84
- --input-background: #333;
85
- --input-background-disabled: #555;
86
- --label-color: #7986cb;
87
- --radio-checkbox-accent: #3f51b5;
88
- --button-background: #3f51b5;
89
- --button-background-hover: #303f9f;
90
- --button-text-color: #ffffff;
91
- --input-border-color: #3f51b5;
92
- --input-border-color-focus: #303f9f;
93
- --secondary-text-color: #b3b3b3;
94
- }
95
-
96
-
97
-
98
-
99
- .dark-blue-theme {
100
- --background-dark: #0a0a0a;
101
- --background-light: #1a1a1a;
102
- --text-light: #e0e0e0;
103
- --border-color: #333;
104
- --input-background: #222;
105
- --input-background-disabled: #444;
106
- --label-color: #81d4fa;
107
- --radio-checkbox-accent: #2196f3;
108
- --button-background: #2196f3;
109
- --button-background-hover: #1976d2;
110
- --button-text-color: #ffffff;
111
- --input-border-color: #2196f3;
112
- --input-border-color-focus: #1976d2;
113
- --secondary-text-color: #b3b3b3;
114
- }
115
-
116
-
117
-
118
-
119
- .dark-orange-theme {
120
- --background-dark: #121212;
121
- --background-light: #1e1e1e;
122
- --text-light: #e0e0e0;
123
- --border-color: #333;
124
- --input-background: #333;
125
- --input-background-disabled: #444;
126
- --label-color: #f96743;
127
- --radio-checkbox-accent: #f96743;
128
- --button-background: #f96743;
129
- --button-background-hover: #f24e2e;
130
- --button-text-color: #ffffff;
131
- --input-border-color: #f96743;
132
- --input-border-color-focus: #f24e2e;
133
- --secondary-text-color: #b3b3b3;
134
- }
135
-
136
-
137
- .green-theme {
138
- --background-dark: #001700;
139
- --background-light: #011f01;
140
- --text-light: #e0e0e0;
141
- --border-color: #333;
142
- --input-background: #333;
143
- --input-background-disabled: #444;
144
- --label-color: #4caf50;
145
- --radio-checkbox-accent: #4caf50;
146
- --button-background: #4caf50;
147
- --button-background-hover: #388e3c;
148
- --button-text-color: #ffffff;
149
- --input-border-color: #4caf50;
150
- --input-border-color-focus: #388e3c;
151
- --secondary-text-color: #b3b3b3;
152
- }
153
-
154
-
155
- .purple-theme {
156
- --background-dark: #121212;
157
- --background-light: #f3e5f5;
158
- --text-light: #4a148c;
159
- --border-color: #333;
160
- --input-background: #ffffff;
161
- --input-background-disabled: #f1f8e9;
162
- --label-color: #9c27b0;
163
- --radio-checkbox-accent: #9c27b0;
164
- --button-background: #9c27b0;
165
- --button-background-hover: #7b1fa2;
166
- --button-text-color: #ffffff;
167
- --input-border-color: #9c27b0;
168
- --input-border-color-focus: #7b1fa2;
169
- --secondary-text-color: #880e4f;
170
- }
171
-
172
- .midnight-blush-theme {
173
- --background-light: #05051e;
174
- --background-dark: #05051e;
175
- --text-light: #ffbd7a;
176
- --text-dark: #ffffff;
177
- --border-color: #ffbd7a; /* #9e7aff;*/
178
- --input-background: #ffffff;
179
- --input-background-disabled: #d9d9d9;
180
- --label-color: #9e7aff;
181
- --radio-checkbox-accent: #fe8bbb;
182
- --button-background: #ffbd7a;
183
- --button-background-hover: #9e7aff; /*#fe8bbb*/;
184
- --button-text-color: #05051e;
185
- --input-border-color: #9e7aff;
186
- --input-border-color-focus: #fe8bbb;
187
- --secondary-text-color: #ffbd7a;
188
- --dropdown-option-text-color: #05051e;
189
- --legend-text-color: #9e7aff;
190
- }
191
-
192
-
193
-
194
-
195
-
196
- /* Formique Container */
197
- .formique {
198
- max-width: 600px;
199
- margin: auto;
200
- padding: 1rem;
201
- background: var(--background-light);
202
- border-radius: 8px;
203
- color: var(--text-light);
204
- /*font-family: 'Montserrat', sans-serif;*/
205
- font-family: 'Lato', sans-serif;
206
- margin-bottom: 200px;
207
- border: 1px solid var(--border-color);
208
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7);
209
- }
210
-
211
- /* Input Block Styling */
212
- .formique .input-block {
213
- margin-bottom: 1rem;
214
- position: relative;
215
- }
216
-
217
- .formique .input-block label {
218
- display: block;
219
- margin-bottom: 0.5rem;
220
- color: var(--label-color);
221
- }
222
-
223
- .formique .input-block .form-input,
224
- .formique .input-block .form-control {
225
- width: 100%;
226
- padding: 0.75rem 1rem 0.75rem 2.5rem;
227
- border: none;
228
- border-bottom: 1px solid var(--border-color);
229
- border-radius: 0;
230
- background-color: var(--background-light);
231
- color: var(--text-light);
232
- box-sizing: border-box;
233
- font-size: 1rem;
234
- }
235
-
236
-
237
- .formique .input-block .form-input:focus {
238
- outline: none;
239
- border-bottom: 1px solid var(--button-background);
240
- }
241
-
242
-
243
- .formique .input-block .form-input-icon {
244
- position: absolute;
245
- left: 1rem;
246
- top: 50%;
247
- transform: translateY(-50%);
248
- color: var(--label-color);
249
- }
250
-
251
- /* Input Disabled */
252
- .formique .input-block .form-input:disabled {
253
- background-color: var(--input-background-disabled);
254
- cursor: not-allowed;
255
- border-bottom: 1px solid var(--label-color);
256
- }
257
-
258
- /* Fieldset Styling for Radio, Checkbox, and Select Groups */
259
- .formique .radio-group,
260
- .formique .checkbox-group,
261
- .formique .form-select {
262
- margin-bottom: 1rem;
263
- padding: 1rem 0;
264
- border-radius: 8px;
265
- background-color: transparent;
266
- border: 1px solid var(--border-color);
267
- }
268
-
269
- /* Radio and Checkbox Group Styling */
270
- .formique .radio-group legend,
271
- .formique .checkbox-group legend {
272
- margin-bottom: 0.5rem;
273
- font-weight: bold;
274
- color: var(--label-color);
275
- }
276
-
277
- .formique .radio-group div,
278
- .formique .checkbox-group div {
279
- margin-bottom: 0.5rem;
280
- display: flex;
281
- align-items: center;
282
- }
283
-
284
- .formique .radio-group .form-radio-input,
285
- .formique .checkbox-group .form-checkbox-input {
286
- margin-right: 0.5rem;
287
- accent-color: var(--radio-checkbox-accent);
288
- }
289
-
290
- /* Select Styling */
291
- .formique .form-select {
292
- margin-bottom: 1rem;
293
- padding: 1rem 2rem;
294
- border-radius: 8px;
295
- background-color: transparent;
296
- border: 1px solid var(--border-color); /* Reduced thickness */
297
- }
298
-
299
- .formique .form-select legend {
300
- color: var(--legend-text-color);
301
- }
302
-
303
- .formique .form-select select option {
304
- background-color: #000!important;
305
- }
306
-
307
- /* Label for Select */
308
- .formique .form-select label {
309
- display: block;
310
- margin-bottom: 0.5rem;
311
- color: var(--label-color);
312
- }
313
-
314
- /* The Select Input Styling */
315
- .formique .form-select select {
316
- width: 100%;
317
- padding: 0.75rem 1rem 0.75rem 2.5rem;
318
- border: none;
319
- background-color: transparent;
320
- color: var(--legend-text-color);
321
- font-size: 1rem;
322
- box-sizing: border-box;
323
- }
324
-
325
- /* Focus Effect for Select */
326
- .formique .form-select select:focus {
327
- outline: none;
328
- }
329
-
330
- /* Icon for Select, Radio, and Checkbox Inputs */
331
- .formique .radio-group .form-radio-input + label,
332
- .formique .checkbox-group .form-checkbox-input + label {
333
- margin-left: 0.5rem;
334
- }
335
-
336
- .formique .radio-group label,
337
- .formique .checkbox-group label {
338
- color: var(--label-color);
339
- font-weight: normal;
340
- }
341
-
342
- .formique .form-select .form-select-icon {
343
- position: absolute;
344
- left: 1rem;
345
- top: 50%;
346
- transform: translateY(-50%);
347
- color: var(--label-color);
348
- }
349
-
350
- .formique .radio-group div,
351
- .formique .checkbox-group div {
352
- padding-left: 2.5rem;
353
- }
354
-
355
-
356
- .formique .form-submit-btn {
357
- padding: 0.75rem 1.5rem;
358
- border: 1px solid var(--background-light);
359
- border-radius: 4px;
360
- background-color: var(--button-background);
361
- color: var(--button-text-color);
362
- font-size: 1rem;
363
- cursor: pointer;
364
- transition: background-color 0.3s;
365
- }
366
-
367
- .formique .form-submit-btn:hover {
368
- background-color: var(--button-background-hover);
369
- color: var(--button-text-color);
370
- }
371
-