@@ -41,7 +41,7 @@
-
+
-
\ No newline at end of file
diff --git a/client/composables/forms/initForm.js b/client/composables/forms/initForm.js
index 70068ff..5694d72 100644
--- a/client/composables/forms/initForm.js
+++ b/client/composables/forms/initForm.js
@@ -1,11 +1,12 @@
+import {generateUUID} from "~/lib/utils.js";
-export const initForm = (defaultValue = {}) => {
+export const initForm = (defaultValue = {}, withDefaultProperties = false) => {
return useForm({
title: 'My Form',
description: null,
visibility: 'public',
workspace_id: null,
- properties: [],
+ properties: withDefaultProperties ? getDefaultProperties() :[],
notifies: false,
slack_notifies: false,
@@ -52,3 +53,28 @@ export const initForm = (defaultValue = {}) => {
...defaultValue
})
}
+
+function getDefaultProperties () {
+ return [
+ {
+ name: 'Name',
+ type: 'text',
+ hidden: false,
+ required: true,
+ id: generateUUID()
+ },
+ {
+ name: 'Email',
+ type: 'email',
+ hidden: false,
+ id: generateUUID()
+ },
+ {
+ name: 'Message',
+ type: 'text',
+ hidden: false,
+ multi_lines: true,
+ id: generateUUID()
+ }
+ ]
+}
diff --git a/client/lib/utils.js b/client/lib/utils.js
index 7d3df6f..f5ddf80 100644
--- a/client/lib/utils.js
+++ b/client/lib/utils.js
@@ -13,6 +13,22 @@ export const hash = (str, seed = 0) => {
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
+export const generateUUID = () => {
+ let d = new Date().getTime()// Timestamp
+ let d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0// Time in microseconds since page-load or 0 if unsupported
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ let r = Math.random() * 16// random number between 0 and 16
+ if (d > 0) { // Use timestamp until depleted
+ r = (d + r) % 16 | 0
+ d = Math.floor(d / 16)
+ } else { // Use microseconds since page-load if supported
+ r = (d2 + r) % 16 | 0
+ d2 = Math.floor(d2 / 16)
+ }
+ return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
+ })
+}
+
/*
* Url and domain related utils
*/
diff --git a/client/pages/forms/[slug]/index.vue b/client/pages/forms/[slug]/index.vue
index 25fe79b..6475df9 100644
--- a/client/pages/forms/[slug]/index.vue
+++ b/client/pages/forms/[slug]/index.vue
@@ -111,13 +111,6 @@ const loadForm = async (setup=false) => {
// Adapt page to form: colors, custom code etc
handleDarkMode(form.value.dark_mode)
handleTransparentMode(form.value.transparent_background)
-
- if (process.server) return
- if (form.value.custom_code) {
- const scriptEl = document.createRange().createContextualFragment(form.value.custom_code)
- document.head.append(scriptEl)
- }
- if (!isIframe) focusOnFirstFormElement()
}
await loadForm(true)
@@ -127,6 +120,14 @@ onMounted(() => {
if (form.value) {
handleDarkMode(form.value?.dark_mode)
handleTransparentMode(form.value?.transparent_background)
+
+ if (process.client) {
+ if (form.value.custom_code) {
+ const scriptEl = document.createRange().createContextualFragment(form.value.custom_code)
+ document.head.append(scriptEl)
+ }
+ if (!isIframe) focusOnFirstFormElement()
+ }
}
})
@@ -165,6 +166,9 @@ useHead({
return titleChunk
}
return titleChunk ? `${titleChunk} - OpnForm` : 'OpnForm';
- }
+ },
+ ... form.value.custom_code ? {
+ script: [ { src: '/widgets/iframeResizer.contentWindow.min.js' } ]
+ } : {}
})
diff --git a/client/pages/forms/create/guest.vue b/client/pages/forms/create/guest.vue
index 677f672..8700691 100644
--- a/client/pages/forms/create/guest.vue
+++ b/client/pages/forms/create/guest.vue
@@ -75,7 +75,7 @@ onMounted(() => {
is_pro: false
}])
- form.value = initForm()
+ form.value = initForm({}, true)
if (route.query.template !== undefined && route.query.template) {
const template = templatesStore.getByKey(route.query.template)
if (template && template.structure) {
diff --git a/client/pages/forms/create/index.vue b/client/pages/forms/create/index.vue
index aff4797..d19d797 100644
--- a/client/pages/forms/create/index.vue
+++ b/client/pages/forms/create/index.vue
@@ -92,7 +92,7 @@ onMounted(() => {
formStore.loadAll(workspace.value.id)
}
- form.value = initForm({workspace_id: workspace.value?.id})
+ form.value = initForm({workspace_id: workspace.value?.id}, true)
formInitialHash.value = hash(JSON.stringify(form.value.data()))
if (route.query.template !== undefined && route.query.template) {
const template = templatesStore.getByKey(route.query.template)
diff --git a/client/public/widgets/iframeResize.min.js b/client/public/widgets/iframeResize.min.js
new file mode 100644
index 0000000..4ad7495
--- /dev/null
+++ b/client/public/widgets/iframeResize.min.js
@@ -0,0 +1,8 @@
+/*! iFrame Resizer (iframeSizer.min.js ) - v4.3.9 - 2023-11-10
+ * Desc: Force cross domain iframes to size to content.
+ * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame.
+ * Copyright: (c) 2023 David J. Bradshaw - dave@bradshaw.net
+ * License: MIT
+ */
+!function(d){var c,u,a,v,x,I,M,r,f,k,i,l,z;function m(){return window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver}function F(e,n,i){e.addEventListener(n,i,!1)}function B(e,n,i){e.removeEventListener(n,i,!1)}function p(e){return x+"["+(n="Host page: "+(e=e),n=window.top!==window.self?window.parentIFrame&&window.parentIFrame.getId?window.parentIFrame.getId()+": "+e:"Nested host page: "+e:n)+"]";var n}function t(e){return k[e]?k[e].log:u}function O(e,n){o("log",e,n,t(e))}function E(e,n){o("info",e,n,t(e))}function R(e,n){o("warn",e,n,!0)}function o(e,n,i,t){!0===t&&"object"==typeof window.console&&console[e](p(n),i)}function w(e){function i(){t("Height"),t("Width"),P(function(){H(w),C(b),l("onResized",w)},w,"init")}function n(){var e=p.slice(I).split(":"),n=e[1]?parseInt(e[1],10):0,i=k[e[0]]&&k[e[0]].iframe,t=getComputedStyle(i);return{iframe:i,id:e[0],height:n+function(e){if("border-box"!==e.boxSizing)return 0;var n=e.paddingTop?parseInt(e.paddingTop,10):0,e=e.paddingBottom?parseInt(e.paddingBottom,10):0;return n+e}(t)+function(e){if("border-box"!==e.boxSizing)return 0;var n=e.borderTopWidth?parseInt(e.borderTopWidth,10):0,e=e.borderBottomWidth?parseInt(e.borderBottomWidth,10):0;return n+e}(t),width:e[2],type:e[3]}}function t(e){var n=Number(k[b]["max"+e]),i=Number(k[b]["min"+e]),e=e.toLowerCase(),t=Number(w[e]);O(b,"Checking "+e+" is in range "+i+"-"+n),t
k[r]["max"+e])throw new Error("Value for min"+e+" can not be greater than max"+e)}}function h(e,n){null===i&&(i=setTimeout(function(){i=null,e()},n))}function e(){"hidden"!==document.visibilityState&&(O("document","Trigger event: Visibility change"),h(function(){b("Tab Visible","resize")},16))}function b(i,t){Object.keys(k).forEach(function(e){var n;k[n=e]&&"parent"===k[n].resizeFrom&&k[n].autoResize&&!k[n].firstRun&&A(i,t,k[e].iframe,e)})}function y(){F(window,"message",w),F(window,"resize",function(){var e;O("window","Trigger event: "+(e="resize")),h(function(){b("Window "+e,"resize")},16)}),F(document,"visibilitychange",e),F(document,"-webkit-visibilitychange",e)}function n(){function t(e,n){if(n){if(!n.tagName)throw new TypeError("Object is not a valid DOM element");if("IFRAME"!==n.tagName.toUpperCase())throw new TypeError("Expected