Add FormProgressbar Component and Refactor OpenForm.vue (#740)
This commit is contained in:
parent
838ab8d846
commit
bedd4541b5
|
|
@ -0,0 +1,59 @@
|
||||||
|
<template>
|
||||||
|
<template v-if="form.show_progress_bar">
|
||||||
|
<div
|
||||||
|
v-if="isIframe"
|
||||||
|
class="mb-4 p-2"
|
||||||
|
>
|
||||||
|
<div class="w-full h-2 bg-gray-200 dark:bg-gray-600 relative border rounded-full overflow-hidden">
|
||||||
|
<div
|
||||||
|
class="h-full transition-all duration-300 rounded-r-full"
|
||||||
|
:class="{ 'w-0': formProgress === 0 }"
|
||||||
|
:style="{ width: formProgress + '%', background: form.color }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="fixed top-0 left-0 right-0 z-50"
|
||||||
|
>
|
||||||
|
<div class="w-full h-[0.2rem] bg-gray-200 dark:bg-gray-600 relative overflow-hidden">
|
||||||
|
<div
|
||||||
|
class="h-full transition-all duration-300"
|
||||||
|
:class="{ 'w-0': formProgress === 0 }"
|
||||||
|
:style="{ width: formProgress + '%', background: form.color }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useIsIframe } from '~/composables/useIsIframe'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
formData: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const isIframe = useIsIframe()
|
||||||
|
|
||||||
|
const formProgress = computed(() => {
|
||||||
|
const requiredFields = props.fields.filter(field => field.required)
|
||||||
|
if (requiredFields.length === 0) {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
const completedFields = requiredFields.filter(field => ![null, undefined, ''].includes(props.formData[field.id]))
|
||||||
|
const progress = (completedFields.length / requiredFields.length) * 100
|
||||||
|
return Math.round(progress)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -13,32 +13,11 @@
|
||||||
ref="form-timer"
|
ref="form-timer"
|
||||||
:form="form"
|
:form="form"
|
||||||
/>
|
/>
|
||||||
<template v-if="form.show_progress_bar">
|
<FormProgressbar
|
||||||
<div
|
:form="form"
|
||||||
v-if="isIframe"
|
:fields="fields"
|
||||||
class="mb-4 p-2"
|
:form-data="dataFormValue"
|
||||||
>
|
/>
|
||||||
<div class="w-full h-2 bg-gray-200 dark:bg-gray-600 relative border rounded-full overflow-hidden">
|
|
||||||
<div
|
|
||||||
class="h-full transition-all duration-300 rounded-r-full"
|
|
||||||
:class="{ 'w-0': formProgress === 0 }"
|
|
||||||
:style="{ width: formProgress + '%', background: form.color }"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="fixed top-0 left-0 right-0 z-50"
|
|
||||||
>
|
|
||||||
<div class="w-full h-[0.2rem] bg-gray-200 dark:bg-gray-600 relative overflow-hidden">
|
|
||||||
<div
|
|
||||||
class="h-full transition-all duration-300"
|
|
||||||
:class="{ 'w-0': formProgress === 0 }"
|
|
||||||
:style="{ width: formProgress + '%', background: form.color }"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<transition
|
<transition
|
||||||
name="fade"
|
name="fade"
|
||||||
mode="out-in"
|
mode="out-in"
|
||||||
|
|
@ -132,13 +111,14 @@ import {pendingSubmission} from "~/composables/forms/pendingSubmission.js"
|
||||||
import FormLogicPropertyResolver from "~/lib/forms/FormLogicPropertyResolver.js"
|
import FormLogicPropertyResolver from "~/lib/forms/FormLogicPropertyResolver.js"
|
||||||
import CachedDefaultTheme from "~/lib/forms/themes/CachedDefaultTheme.js"
|
import CachedDefaultTheme from "~/lib/forms/themes/CachedDefaultTheme.js"
|
||||||
import FormTimer from './FormTimer.vue'
|
import FormTimer from './FormTimer.vue'
|
||||||
|
import FormProgressbar from './FormProgressbar.vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { FormMode, createFormModeStrategy } from "~/lib/forms/FormModeStrategy.js"
|
import { FormMode, createFormModeStrategy } from "~/lib/forms/FormModeStrategy.js"
|
||||||
import clonedeep from 'clone-deep'
|
import clonedeep from 'clone-deep'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'OpenForm',
|
name: 'OpenForm',
|
||||||
components: {draggable, OpenFormField, OpenFormButton, CaptchaInput, FormTimer},
|
components: {draggable, OpenFormField, OpenFormButton, CaptchaInput, FormTimer, FormProgressbar},
|
||||||
props: {
|
props: {
|
||||||
form: {
|
form: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -245,15 +225,6 @@ export default {
|
||||||
isAdminPreview() {
|
isAdminPreview() {
|
||||||
return this.formModeStrategy.admin.showAdminControls
|
return this.formModeStrategy.admin.showAdminControls
|
||||||
},
|
},
|
||||||
formProgress() {
|
|
||||||
const requiredFields = this.fields.filter(field => field.required)
|
|
||||||
if (requiredFields.length === 0) {
|
|
||||||
return 100
|
|
||||||
}
|
|
||||||
const completedFields = requiredFields.filter(field => ![null, undefined, ''].includes(this.dataFormValue[field.id]))
|
|
||||||
const progress = (completedFields.length / requiredFields.length) * 100
|
|
||||||
return Math.round(progress)
|
|
||||||
},
|
|
||||||
currentFields: {
|
currentFields: {
|
||||||
get() {
|
get() {
|
||||||
return this.fieldGroups[this.formPageIndex]
|
return this.fieldGroups[this.formPageIndex]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue