domma-cms 0.14.7 → 0.14.8
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/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(c,l){typeof module<"u"&&module.exports?module.exports=l():c.FormLogicEngine=l()})(typeof globalThis<"u"?globalThis:this,function(){"use strict";function c(e){return e===""||e===null||e===void 0?"":String(e)}function l(e){const s=parseFloat(e);return isNaN(s)?null:s}function f(e){return e==null?!0:typeof e=="string"?e.trim()==="":Array.isArray(e)?e.length===0:!1}function p(e,s){if(!e||!e.field||!e.operator)return!0;const t=s[e.field],n=c(t),
|
|
1
|
+
(function(c,l){typeof module<"u"&&module.exports?module.exports=l():c.FormLogicEngine=l()})(typeof globalThis<"u"?globalThis:this,function(){"use strict";function c(e){return e===""||e===null||e===void 0?"":String(e)}function l(e){const s=parseFloat(e);return isNaN(s)?null:s}function f(e){return e==null?!0:typeof e=="string"?e.trim()==="":Array.isArray(e)?e.length===0:!1}function p(e,s){if(!e||!e.field||!e.operator)return!0;const t=s[e.field],n=c(t),r=c(e.value);switch(e.operator){case"equals":return n===r;case"not_equals":return n!==r;case"contains":return n.toLowerCase().includes(r.toLowerCase());case"not_contains":return!n.toLowerCase().includes(r.toLowerCase());case"starts_with":return n.toLowerCase().startsWith(r.toLowerCase());case"ends_with":return n.toLowerCase().endsWith(r.toLowerCase());case"greater_than":{const i=l(t),a=l(e.value);return i!==null&&a!==null&&i>a}case"less_than":{const i=l(t),a=l(e.value);return i!==null&&a!==null&&i<a}case"is_empty":return f(t);case"is_not_empty":return!f(t);case"in":return(Array.isArray(e.value)?e.value.map(c):String(e.value).split(",").map(a=>a.trim())).includes(n);case"not_in":return!(Array.isArray(e.value)?e.value.map(c):String(e.value).split(",").map(a=>a.trim())).includes(n);case"matches_regex":try{const i=e.flags||"";return new RegExp(e.value,i).test(n)}catch(i){return typeof console<"u"&&console.warn&&console.warn('[FormLogicEngine] Invalid regex in condition for field "'+e.field+'": '+e.value,i&&i.message),!1}default:return!0}}function u(e,s){return e?Array.isArray(e.all)?e.all.every(t=>t.all||t.any?u(t,s):p(t,s)):Array.isArray(e.any)?e.any.some(t=>t.all||t.any?u(t,s):p(t,s)):e.field&&e.operator?p(e,s):!0:!0}function d(e,s){const t=e.logic;if(!t||!t.visibility)return"visible";const n=t.visibility,r=n.conditions||[];for(const i of r)if(i.when&&u(i.when,s))return i.then==="hidden"?"hidden":"visible";return n.default==="hidden"?"hidden":"visible"}function y(e,s){const t=e.logic;if(!t||!t.requirement)return e.required||!1;const n=t.requirement,r=n.conditions||[];for(const i of r)if(i.when&&u(i.when,s))return i.then===!0;return n.default===!0}function h(e,s,t){const n=e.logic;if(!n||!Array.isArray(n.validation))return[];const r=[];for(const i of n.validation)switch(i.type){case"regex":{if(!f(s))try{new RegExp(i.pattern||"",i.flags||"").test(c(s))||r.push({message:i.message||"Invalid format."})}catch{}break}case"match":{const a=t[i.field];!f(s)&&c(s)!==c(a)&&r.push({message:i.message||"Fields do not match."});break}}return r}function m(e,s){const t=e.logic;if(!t||!t.cascade||!t.cascade.sourceField)return null;const n=t.cascade,r=c(s[n.sourceField]),i=n.mapping||{};return Object.prototype.hasOwnProperty.call(i,r)?i[r]||[]:n.defaultOptions||null}function _(e,s){s==="fade"?(e.style.transition="opacity 0.25s ease",e.style.opacity="1",requestAnimationFrame(function(){e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.opacity=""},260)})):s==="slide"?(e.style.overflow="hidden",e.style.maxHeight=e.scrollHeight+"px",e.style.transition="max-height 0.3s ease, opacity 0.2s ease",requestAnimationFrame(function(){e.style.maxHeight="0",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},320)})):s==="scale"&&(e.style.transition="opacity 0.2s ease, transform 0.2s ease",e.style.transform="scale(1)",e.style.opacity="1",requestAnimationFrame(function(){e.style.transform="scale(0.95)",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.transform="",e.style.opacity=""},220)}))}function v(e,s){e.classList.remove("fb-field-hidden"),s==="fade"?(e.style.opacity="0",e.style.transition="opacity 0.25s ease",requestAnimationFrame(function(){e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.opacity=""},260)})):s==="slide"?(e.style.overflow="hidden",e.style.maxHeight="0",e.style.opacity="0",e.style.transition="max-height 0.3s ease, opacity 0.2s ease",requestAnimationFrame(function(){e.style.maxHeight=e.scrollHeight+"px",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},320)})):s==="scale"&&(e.style.transform="scale(0.95)",e.style.opacity="0",e.style.transition="opacity 0.2s ease, transform 0.2s ease",requestAnimationFrame(function(){e.style.transform="scale(1)",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.transform="",e.style.opacity=""},220)}))}function o(e,s){this._form=e,this._wrapper=s,this._fields=(e.fields||[]).filter(t=>t.type!=="page-break"),this._listeners=[],this._depMap=new Map,this._initialEval=!1}return o.prototype._buildDepMap=function(){this._depMap.clear();const e=this;e._fields.forEach(function(s){const t=s.logic;if(!t)return;function n(r){if(!r)return;(r.all||r.any||[]).forEach(function(a){a.field?(e._depMap.has(a.field)||e._depMap.set(a.field,new Set),e._depMap.get(a.field).add(s.name)):n(a)})}if(t.visibility&&(t.visibility.conditions||[]).forEach(function(r){n(r.when)}),t.requirement&&(t.requirement.conditions||[]).forEach(function(r){n(r.when)}),t.cascade&&t.cascade.sourceField){const r=t.cascade.sourceField;e._depMap.has(r)||e._depMap.set(r,new Set),e._depMap.get(r).add(s.name)}})},o.prototype._getValues=function(){const e={};return this._fields.forEach(function(s){const t=this._wrapper.querySelector('[name="'+s.name+'"]');if(t)if(t.type==="radio"){const n=this._wrapper.querySelector('[name="'+s.name+'"]:checked');e[s.name]=n?n.value:""}else if(t.type==="checkbox"){const n=this._wrapper.querySelectorAll('input[type="checkbox"][name="'+s.name+'"]');if(n.length>1){const r=[];n.forEach(function(i){i.checked&&r.push(i.value)}),e[s.name]=r}else e[s.name]=t.checked?t.value||"true":""}else e[s.name]=t.value},this),e},o.prototype._applyVisibility=function(e,s){const n=d(e,s)==="hidden",r=this._findFieldWrapper(e.name);if(!r)return;r.setAttribute("aria-hidden",String(n));const i=this._initialEval?"none":e.logic?.visibility?.transition||"none";if(i==="none"){r.classList.toggle("fb-field-hidden",n);return}r.style.transition="",n?_(r,i):v(r,i)},o.prototype._applyRequirement=function(e,s){const t=y(e,s),n=this._wrapper.querySelector('[name="'+e.name+'"]');n&&(t?n.setAttribute("required",""):n.removeAttribute("required"))},o.prototype._applyCascade=function(e,s){const t=m(e,s);if(t===null)return;const n=this._wrapper.querySelector('select[name="'+e.name+'"]');if(!n)return;const r=n.value;n.textContent="",t.forEach(function(i){const a=document.createElement("option");a.value=i.value,a.textContent=i.label||i.value,i.value===r&&(a.selected=!0),n.appendChild(a)})},o.prototype._applyValidation=function(e,s){const t=this._wrapper.querySelector('[name="'+e.name+'"]');if(!t)return;const n=t.type==="checkbox"?t.checked?t.value||"true":"":t.value,r=h(e,n,s);let i=t.parentNode.querySelector(".fb-validation-error");r.length?(i||(i=document.createElement("div"),i.className="fb-validation-error",t.parentNode.appendChild(i)),i.textContent=r[0].message):i&&i.remove()},o.prototype._findFieldWrapper=function(e){const s=this._wrapper.querySelector('[name="'+e+'"]');if(!s)return null;const t=s.closest("form")||this._wrapper;let n=s;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode;return n},o.prototype.evaluate=function(e){const s=this._getValues(),t=this;let n;if(e&&this._depMap.has(e)){const r=this._depMap.get(e);n=this._fields.filter(function(i){return r.has(i.name)})}else n=this._fields;n.forEach(function(r){r.logic&&(t._applyVisibility(r,s),t._applyRequirement(r,s),t._applyCascade(r,s))})},o.prototype.init=function(){this._buildDepMap();const e=this;this._wrapper.querySelectorAll("input, select, textarea").forEach(function(t){const n=t.getAttribute("name");if(!n)return;const r=function(){e.evaluate(n)};t.addEventListener("input",r),t.addEventListener("change",r),e._listeners.push({el:t,event:"input",fn:r}),e._listeners.push({el:t,event:"change",fn:r});const i=e._fields.find(function(a){return a.name===n});if(i&&i.logic&&Array.isArray(i.logic.validation)&&i.logic.validation.length){const a=function(){const g=e._getValues();e._applyValidation(i,g)};t.addEventListener("blur",a),e._listeners.push({el:t,event:"blur",fn:a})}}),this._initialEval=!0,this.evaluate(),this._initialEval=!1},o.prototype.destroy=function(){this._listeners.forEach(function(e){e.el.removeEventListener(e.event,e.fn)}),this._listeners=[]},{evaluateCondition:p,evaluateConditionGroup:u,evaluateFieldVisibility:d,evaluateFieldRequirement:y,validateField:h,getCascadeOptions:m,FormLogicRuntime:o}});
|
package/public/js/forms.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const targets=document.querySelectorAll("[data-form]");targets.length&&targets.forEach(initFormTarget);function showMessage(i,r,t){const e=i.querySelector(".fb-form-success, .fb-form-error");e&&e.remove();const
|
|
1
|
+
const targets=document.querySelectorAll("[data-form]");targets.length&&targets.forEach(initFormTarget);function showMessage(i,r,t){const e=i.querySelector(".fb-form-success, .fb-form-error");e&&e.remove();const a=document.createElement("div");a.className=t==="success"?"fb-form-success":"fb-form-error",a.textContent=r,i.appendChild(a)}function attachRuntimeLifecycle(i,r){if(i._formLogicRuntime=r,!i.parentNode||typeof MutationObserver>"u")return;const t=new MutationObserver(function(e){for(const a of e)for(const n of a.removedNodes)if(n===i||n.nodeType===1&&n.contains&&n.contains(i)){r.destroy(),t.disconnect();return}});t.observe(i.parentNode,{childList:!0,subtree:!1})}function buildBlueprintFromFields(i,r){const t={};return i.forEach(function(e){if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const a=e.type==="checkbox"?"boolean":e.type==="date"?"string":e.type,n={...e.formConfig||{}};n.span==="full"&&r&&(n.span=r),t[e.name]={type:a,label:e.label||e.name,required:e.required||!1,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...n}},e.minLength!==void 0&&(t[e.name].minLength=e.minLength),e.maxLength!==void 0&&(t[e.name].maxLength=e.maxLength),e.min!==void 0&&(t[e.name].min=e.min),e.max!==void 0&&(t[e.name].max=e.max)}),t}function buildInitialData(i){const r={};return i.forEach(function(t){if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(r[t.name]=typeof e=="object"?e.value:e)}}),r}function patchDateInputs(i,r){(r||[]).forEach(function(t){if(t.type!=="date"||!t.name)return;const e=i.querySelector('[name="'+t.name+'"]');e&&e.type!=="date"&&(e.type="date")})}function buildWizardSteps(i,r){const t=[];let e=[],a=r||"Step 1",n="";return i.forEach(function(u){u.type==="page-break"?(t.push({title:a,description:n,fieldGroup:e}),e=[],a=u.label||"Step "+(t.length+1),n=u.description||""):u.type!=="spacer"&&e.push(u)}),t.push({title:a,description:n,fieldGroup:e}),t}function injectHoneypot(i){const r=document.createElement("div");r.className="fb-form-honeypot",r.setAttribute("aria-hidden","true");const t=document.createElement("input");t.name="website",t.type="text",t.tabIndex=-1,t.autocomplete="url",t.placeholder="https://",r.appendChild(t);const e=document.createElement("input");e.name="_t",e.type="hidden",e.value=Date.now(),r.appendChild(e),i.appendChild(r)}function injectSpacers(i,r){const t=i.querySelector("form");if(!t)return;const e=Array.from(t.querySelectorAll(".form-group"));let a=0;r.forEach(function(n){if(n.type==="spacer"){const u=document.createElement("div");u.className="fb-spacer";const s=e[a];if(s)t.insertBefore(u,s);else{const l=t.querySelector('[type="submit"]');l?t.insertBefore(u,l):t.appendChild(u)}}else n.type!=="page-break"&&a++})}function submitForm(i,r,t,e,a){const n=a||e,u=n.querySelector('[name="website"]')?.value||"",s=n.querySelector('[name="_t"]')?.value||"",l=Object.assign({},r,{_hp:u,_t:s});return fetch("/api/forms/submit/"+i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}).then(m=>m.json().then(c=>({ok:m.ok,body:c}))).then(m=>{m.ok&&m.body.ok?(e.textContent="",showMessage(e,m.body.message||t.successMessage||"Thank you.","success")):showMessage(e,m.body.error||"Something went wrong.","error")}).catch(()=>{showMessage(e,"Unable to submit. Please check your connection.","error")})}function renderManualForm(i,r,t,e,a){const n=document.createElement("form");n.noValidate=!0,r.forEach(function(s){const l=document.createElement("div");l.className="form-group",l.style.marginBottom="1.25rem";const m=document.createElement("label");if(m.className="form-label",m.textContent=s.label||s.name,s.required){const o=document.createElement("span");o.textContent=" *",o.style.color="#f87171",m.appendChild(o)}let c;s.type==="textarea"?(c=document.createElement("textarea"),c.rows=s.formConfig?.rows||4,c.className="form-input"):s.type==="select"?(c=document.createElement("select"),c.className="form-input",(s.options||[]).forEach(function(o){const p=document.createElement("option");p.value=typeof o=="string"?o:o.value??"",p.textContent=typeof o=="string"?o:o.label||p.value,c.appendChild(p)})):(c=document.createElement("input"),c.type=s.type||"text",c.className="form-input",s.placeholder&&(c.placeholder=s.placeholder)),c.name=s.name,c.required=s.required||!1,l.appendChild(m),l.appendChild(c),n.appendChild(l)}),t.honeypot&&injectHoneypot(n);const u=document.createElement("button");u.type="submit",u.className="btn btn-primary",u.textContent=t.submitText||"Submit",n.appendChild(u),n.addEventListener("submit",function(s){s.preventDefault();const l={};if(r.forEach(function(m){const c=n.querySelector('[name="'+m.name+'"]');c&&(l[m.name]=c.value)}),window.FormLogicEngine&&a){const m=window.FormLogicEngine,c=[],o=[];if(r.forEach(function(p){if(m.evaluateFieldVisibility(p,l)==="hidden"){delete l[p.name];return}const h=m.evaluateFieldRequirement(p,l),f=l[p.name];h&&(!f||!String(f).trim())&&c.push(p.label||p.name);const d=m.validateField(p,f||"",l);d.length&&o.push(d[0].message)}),c.length||o.length){const p=[];c.length&&p.push("Required: "+c.join(", ")),o.length&&p.push(o.join("; ")),showMessage(i,p.join(". "),"error");return}}i.classList.add("fb-form-loading"),u.disabled=!0,submitForm(e,l,t,i,n).finally(function(){i.classList.remove("fb-form-loading"),u.disabled=!1})}),i.appendChild(n),window.FormLogicEngine&&a&&r.some(s=>s.logic)&&new window.FormLogicEngine.FormLogicRuntime(a,i).init()}function initFormTarget(i){const r=i.getAttribute("data-form");r&&fetch("/api/forms/"+r+"/public").then(t=>{if(!t.ok)throw new Error("Form not found: "+r);return t.json()}).then(t=>{const e=t.fields||[],a=t.settings||{},n=document.createElement("div");n.className="fb-form-wrapper",i.appendChild(n);const u=e.some(s=>s.type==="page-break");if(typeof Domma<"u"&&Domma.forms){const s=a.columns||1;if(u&&Domma.forms.wizard){const m=buildWizardSteps(e,t.title).map(function(o){return{title:o.title,description:o.description,fields:buildBlueprintFromFields(o.fieldGroup,s)}}),c=Domma.forms.wizard(n,{schema:{steps:m},onSubmit:function(o){return submitForm(r,o,a,n,null)}});Promise.resolve(c).then(function(){if(patchDateInputs(n,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,n);o.init(),attachRuntimeLifecycle(n,o)}if(a.honeypot){const o=n.querySelector("form");o&&injectHoneypot(o)}})}else if(Domma.forms.render){const l=buildBlueprintFromFields(e,s),m=buildInitialData(e),c=Domma.forms.render(n,l,m,{submitText:a.submitText||"Submit",layout:a.layout||"stacked",columns:s,onSubmit:function(o){return submitForm(r,o,a,n,null)}});Promise.resolve(c).then(function(){if(patchDateInputs(n,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,n);o.init(),attachRuntimeLifecycle(n,o)}if(e.some(o=>o.type==="spacer")&&injectSpacers(n,e),a.honeypot){const o=n.querySelector("form");o&&injectHoneypot(o)}})}}else renderManualForm(n,e.filter(s=>s.type!=="page-break"&&s.type!=="spacer"),a,r,t)}).catch(t=>{const e=document.createElement("p");e.textContent="Form unavailable.",e.style.cssText="color:#f87171;font-style:italic;",i.appendChild(e),console.warn("[forms]",t.message)})}
|