show field area pages list inthe form

pull/217/head
Pete Matsyburka 2 years ago
parent a478112b07
commit e7ef7b552f

@ -0,0 +1,51 @@
<template>
<div
v-if="uniqueAreas.length > 1"
class="mb-2"
>
<div class="flex space-x-1 text-sm ml-1 -mt-3">
<span>
{{ t('appears_on') }}:
</span>
<a
v-for="area in uniqueAreas"
:key="area.uuid"
href="#"
class="link pr-0.5"
@click.prevent="scrollIntoArea(area)"
>
{{ t('page') }} <template v-if="isMultipleDocs">{{ attachmentUuids.indexOf(area.attachment_uuid) + 1 }}-</template>{{ area.page + 1 }}
</a>
</div>
</div>
</template>
<script>
export default {
name: 'AppearsOn',
inject: ['t', 'scrollIntoArea'],
props: {
field: {
type: Object,
required: true
}
},
computed: {
isMultipleDocs () {
return this.attachmentUuids.length > 1
},
attachmentUuids () {
return [...new Set(this.uniqueAreas.map((e) => e.attachment_uuid))]
},
uniqueAreas () {
const areas = {}
this.field.areas.forEach((area) => {
areas[area.attachment_uuid + area.page] ||= area
})
return Object.values(areas).slice(0, 6)
}
}
}
</script>

@ -83,22 +83,25 @@ export default {
return (this.$root.$el?.parentNode?.getRootNode() || document).getElementById(`page-${area.attachment_uuid}-${area.page}`) return (this.$root.$el?.parentNode?.getRootNode() || document).getElementById(`page-${area.attachment_uuid}-${area.page}`)
}, },
scrollIntoField (field) { scrollIntoField (field) {
this.areaRefs.find((area) => { if (field?.areas) {
if (area.field === field) { this.scrollIntoArea(field.areas[0])
const root = this.$root.$el.parentNode.getRootNode() }
const container = root.body || root.querySelector('div') },
scrollIntoArea (area) {
const areaRef = this.areaRefs.find((a) => a.area === area)
if (container.style.overflow === 'hidden') { if (areaRef) {
this.scrollInContainer(area.$el) const root = this.$root.$el.parentNode.getRootNode()
} else { const container = root.body || root.querySelector('div')
area.$refs.scrollToElem.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
return true if (container.style.overflow === 'hidden') {
this.scrollInContainer(areaRef.$el)
} else { } else {
return null areaRef.$refs.scrollToElem.scrollIntoView({ behavior: 'smooth', block: 'start' })
} }
})
return true
}
}, },
scrollInContainer (target) { scrollInContainer (target) {
const root = this.$root.$el.parentNode.getRootNode() const root = this.$root.$el.parentNode.getRootNode()

@ -15,6 +15,7 @@
{{ t('set_today') }} {{ t('set_today') }}
</button> </button>
</div> </div>
<AppearsOn :field="field" />
<div class="text-center"> <div class="text-center">
<input <input
ref="input" ref="input"
@ -31,11 +32,13 @@
<script> <script>
import { IconCalendarCheck } from '@tabler/icons-vue' import { IconCalendarCheck } from '@tabler/icons-vue'
import AppearsOn from './appears_on'
export default { export default {
name: 'DateStep', name: 'DateStep',
components: { components: {
IconCalendarCheck IconCalendarCheck,
AppearsOn
}, },
inject: ['t'], inject: ['t'],
props: { props: {

@ -65,7 +65,7 @@
:key="currentField.uuid" :key="currentField.uuid"
v-model="values[currentField.uuid]" v-model="values[currentField.uuid]"
:field="currentField" :field="currentField"
@focus="$refs.areas.scrollIntoField(currentField)" @focus="scrollIntoField(currentField)"
/> />
</div> </div>
<DateStep <DateStep
@ -73,7 +73,7 @@
:key="currentField.uuid" :key="currentField.uuid"
v-model="values[currentField.uuid]" v-model="values[currentField.uuid]"
:field="currentField" :field="currentField"
@focus="$refs.areas.scrollIntoField(currentField)" @focus="scrollIntoField(currentField)"
/> />
<div v-else-if="currentField.type === 'select'"> <div v-else-if="currentField.type === 'select'">
<label <label
@ -87,13 +87,14 @@
v-else v-else
class="py-1" class="py-1"
/> />
<AppearsOn :field="currentField" />
<select <select
:id="currentField.uuid" :id="currentField.uuid"
:required="currentField.required" :required="currentField.required"
class="select base-input !text-2xl w-full text-center font-normal" class="select base-input !text-2xl w-full text-center font-normal"
:name="`values[${currentField.uuid}]`" :name="`values[${currentField.uuid}]`"
@change="values[currentField.uuid] = $event.target.value" @change="values[currentField.uuid] = $event.target.value"
@focus="$refs.areas.scrollIntoField(currentField)" @focus="scrollIntoField(currentField)"
> >
<option <option
value="" value=""
@ -198,7 +199,7 @@
:onchange="`this.setCustomValidity(validity.valueMissing ? '${t('please_check_the_box_to_continue')}' : '');`" :onchange="`this.setCustomValidity(validity.valueMissing ? '${t('please_check_the_box_to_continue')}' : '');`"
:required="field.required" :required="field.required"
:checked="!!values[field.uuid]" :checked="!!values[field.uuid]"
@click="[$refs.areas.scrollIntoField(field), values[field.uuid] = !values[field.uuid]]" @click="[scrollIntoField(field), values[field.uuid] = !values[field.uuid]]"
> >
<span class="text-xl"> <span class="text-xl">
{{ field.name || field.type + ' ' + (index + 1) }} {{ field.name || field.type + ' ' + (index + 1) }}
@ -216,7 +217,7 @@
:is-direct-upload="isDirectUpload" :is-direct-upload="isDirectUpload"
:attachments-index="attachmentsIndex" :attachments-index="attachmentsIndex"
:submitter-slug="submitterSlug" :submitter-slug="submitterSlug"
@attached="[attachments.push($event), $refs.areas.scrollIntoField(currentField)]" @attached="[attachments.push($event), scrollIntoField(currentField)]"
/> />
<SignatureStep <SignatureStep
v-else-if="currentField.type === 'signature'" v-else-if="currentField.type === 'signature'"
@ -230,7 +231,7 @@
:attachments-index="attachmentsIndex" :attachments-index="attachmentsIndex"
:submitter-slug="submitterSlug" :submitter-slug="submitterSlug"
@attached="attachments.push($event)" @attached="attachments.push($event)"
@start="$refs.areas.scrollIntoField(currentField)" @start="scrollIntoField(currentField)"
@minimize="isFormVisible = false" @minimize="isFormVisible = false"
/> />
<InitialsStep <InitialsStep
@ -244,8 +245,8 @@
:attachments-index="attachmentsIndex" :attachments-index="attachmentsIndex"
:submitter-slug="submitterSlug" :submitter-slug="submitterSlug"
@attached="attachments.push($event)" @attached="attachments.push($event)"
@start="$refs.areas.scrollIntoField(currentField)" @start="scrollIntoField(currentField)"
@focus="$refs.areas.scrollIntoField(currentField)" @focus="scrollIntoField(currentField)"
@minimize="isFormVisible = false" @minimize="isFormVisible = false"
/> />
<AttachmentStep <AttachmentStep
@ -256,7 +257,7 @@
:field="currentField" :field="currentField"
:attachments-index="attachmentsIndex" :attachments-index="attachmentsIndex"
:submitter-slug="submitterSlug" :submitter-slug="submitterSlug"
@attached="[attachments.push($event), $refs.areas.scrollIntoField(currentField)]" @attached="[attachments.push($event), scrollIntoField(currentField)]"
/> />
<PhoneStep <PhoneStep
v-else-if="currentField.type === 'phone'" v-else-if="currentField.type === 'phone'"
@ -266,7 +267,7 @@
:field="currentField" :field="currentField"
:default-value="submitter.phone" :default-value="submitter.phone"
:submitter-slug="submitterSlug" :submitter-slug="submitterSlug"
@focus="$refs.areas.scrollIntoField(currentField)" @focus="scrollIntoField(currentField)"
@submit="submitStep" @submit="submitStep"
/> />
<PaymentStep <PaymentStep
@ -277,7 +278,7 @@
:field="currentField" :field="currentField"
:submitter-slug="submitterSlug" :submitter-slug="submitterSlug"
@attached="attachments.push($event)" @attached="attachments.push($event)"
@focus="$refs.areas.scrollIntoField(currentField)" @focus="scrollIntoField(currentField)"
@submit="submitStep" @submit="submitStep"
/> />
</div> </div>
@ -363,6 +364,7 @@ import TextStep from './text_step'
import DateStep from './date_step' import DateStep from './date_step'
import FormCompleted from './completed' import FormCompleted from './completed'
import { IconInnerShadowTop, IconArrowsDiagonal, IconArrowsDiagonalMinimize2 } from '@tabler/icons-vue' import { IconInnerShadowTop, IconArrowsDiagonal, IconArrowsDiagonalMinimize2 } from '@tabler/icons-vue'
import AppearsOn from './appears_on'
import { t } from './i18n' import { t } from './i18n'
export default { export default {
@ -371,6 +373,7 @@ export default {
FieldAreas, FieldAreas,
ImageStep, ImageStep,
SignatureStep, SignatureStep,
AppearsOn,
AttachmentStep, AttachmentStep,
InitialsStep, InitialsStep,
MultiSelectStep, MultiSelectStep,
@ -386,6 +389,7 @@ export default {
provide () { provide () {
return { return {
baseUrl: this.baseUrl, baseUrl: this.baseUrl,
scrollIntoArea: this.scrollIntoArea,
t: this.t t: this.t
} }
}, },
@ -687,7 +691,7 @@ export default {
this.recalculateButtonDisabledKey = Math.random() this.recalculateButtonDisabledKey = Math.random()
if (scrollToArea) { if (scrollToArea) {
this.$refs.areas.scrollIntoField(step[0]) this.scrollIntoField(step[0])
} }
this.$refs.form.querySelector('input[type="date"], input[type="text"], select')?.focus() this.$refs.form.querySelector('input[type="date"], input[type="text"], select')?.focus()
@ -715,6 +719,12 @@ export default {
}) })
} }
}, },
scrollIntoField (field) {
return this.$refs.areas.scrollIntoField(field)
},
scrollIntoArea (area) {
return this.$refs.areas.scrollIntoArea(area)
},
async submitStep () { async submitStep () {
this.isSubmitting = true this.isSubmitting = true

@ -3,6 +3,8 @@ const en = {
type_here: 'Type here', type_here: 'Type here',
optional: 'optional', optional: 'optional',
option: 'Option', option: 'Option',
appears_on: 'Appears on',
page: 'Page',
select_your_option: 'Select your option', select_your_option: 'Select your option',
complete_hightlighted_checkboxes_and_click: 'Complete hightlighted checkboxes and click', complete_hightlighted_checkboxes_and_click: 'Complete hightlighted checkboxes and click',
submit: 'submit', submit: 'submit',
@ -48,6 +50,8 @@ const es = {
submit_form: 'Enviar Formulario', submit_form: 'Enviar Formulario',
type_here: 'Escribe aquí', type_here: 'Escribe aquí',
optional: 'opcional', optional: 'opcional',
appears_on: 'Aparece en',
page: 'Página',
select_your_option: 'Selecciona tu opción', select_your_option: 'Selecciona tu opción',
complete_hightlighted_checkboxes_and_click: 'Completa las casillas resaltadas y haz clic', complete_hightlighted_checkboxes_and_click: 'Completa las casillas resaltadas y haz clic',
submit: 'enviar', submit: 'enviar',
@ -93,6 +97,8 @@ const it = {
submit_form: 'Invia Modulo', submit_form: 'Invia Modulo',
type_here: 'Digita qui', type_here: 'Digita qui',
optional: 'opzionale', optional: 'opzionale',
appears_on: 'Compare su',
page: 'Pagina',
select_your_option: 'Seleziona la tua opzione', select_your_option: 'Seleziona la tua opzione',
complete_hightlighted_checkboxes_and_click: 'Completa le caselle evidenziate e fai clic', complete_hightlighted_checkboxes_and_click: 'Completa le caselle evidenziate e fai clic',
submit: 'invia', submit: 'invia',
@ -138,6 +144,8 @@ const de = {
submit_form: 'Formular absenden', submit_form: 'Formular absenden',
type_here: 'Hier eingeben', type_here: 'Hier eingeben',
optional: 'optional', optional: 'optional',
appears_on: 'Erscheint auf',
page: 'Seite',
select_your_option: 'Wähle deine Option', select_your_option: 'Wähle deine Option',
complete_hightlighted_checkboxes_and_click: 'Markierte Kontrollkästchen ausfüllen und klicken', complete_hightlighted_checkboxes_and_click: 'Markierte Kontrollkästchen ausfüllen und klicken',
submit: 'absenden', submit: 'absenden',
@ -183,6 +191,8 @@ const fr = {
submit_form: 'Envoyer le Formulaire', submit_form: 'Envoyer le Formulaire',
type_here: 'Tapez ici', type_here: 'Tapez ici',
optional: 'facultatif', optional: 'facultatif',
appears_on: 'Apparaît sur',
page: 'Page',
select_your_option: 'Sélectionnez votre option', select_your_option: 'Sélectionnez votre option',
complete_hightlighted_checkboxes_and_click: 'Complétez les cases à cocher en surbrillance et cliquez', complete_hightlighted_checkboxes_and_click: 'Complétez les cases à cocher en surbrillance et cliquez',
submit: 'envoyer', submit: 'envoyer',
@ -228,6 +238,8 @@ const pl = {
submit_form: 'Wyślij Formularz', submit_form: 'Wyślij Formularz',
type_here: 'Wpisz tutaj', type_here: 'Wpisz tutaj',
optional: 'opcjonalny', optional: 'opcjonalny',
appears_on: 'Pojawia się na',
page: 'Strona',
select_your_option: 'Wybierz swoją opcję', select_your_option: 'Wybierz swoją opcję',
complete_hightlighted_checkboxes_and_click: 'Wypełnij zaznaczone pola wyboru i kliknij', complete_hightlighted_checkboxes_and_click: 'Wypełnij zaznaczone pola wyboru i kliknij',
submit: 'wyślij', submit: 'wyślij',
@ -273,6 +285,8 @@ const uk = {
submit_form: 'Надіслати Форму', submit_form: 'Надіслати Форму',
type_here: 'Введіть тут', type_here: 'Введіть тут',
optional: 'необов’язково', optional: 'необов’язково',
appears_on: "З'являється на",
page: 'Сторінка',
select_your_option: 'Виберіть варіант', select_your_option: 'Виберіть варіант',
complete_hightlighted_checkboxes_and_click: 'Заповніть позначені прапорці та натисніть', complete_hightlighted_checkboxes_and_click: 'Заповніть позначені прапорці та натисніть',
submit: 'надіслати', submit: 'надіслати',
@ -318,6 +332,8 @@ const cs = {
submit_form: 'Odeslat formulář', submit_form: 'Odeslat formulář',
type_here: 'Zadejte zde', type_here: 'Zadejte zde',
optional: 'volitelné', optional: 'volitelné',
appears_on: 'Zobrazuje se na',
page: 'Stránka',
select_your_option: 'Vyberte svou volbu', select_your_option: 'Vyberte svou volbu',
complete_hightlighted_checkboxes_and_click: 'Označte zvýrazněné zaškrtávací políčka a klikněte na', complete_hightlighted_checkboxes_and_click: 'Označte zvýrazněné zaškrtávací políčka a klikněte na',
submit: 'odeslat', submit: 'odeslat',
@ -363,6 +379,8 @@ const pt = {
submit_form: 'Enviar Formulário', submit_form: 'Enviar Formulário',
type_here: 'Digite aqui', type_here: 'Digite aqui',
optional: 'opcional', optional: 'opcional',
appears_on: 'Aparece em',
page: 'Página',
select_your_option: 'Selecione sua opção', select_your_option: 'Selecione sua opção',
complete_hightlighted_checkboxes_and_click: 'Complete as caixas de seleção destacadas e clique', complete_hightlighted_checkboxes_and_click: 'Complete as caixas de seleção destacadas e clique',
submit: 'enviar', submit: 'enviar',

@ -70,6 +70,7 @@
</a> </a>
</div> </div>
</div> </div>
<AppearsOn :field="field" />
<input <input
:value="modelValue || computedPreviousValue" :value="modelValue || computedPreviousValue"
type="hidden" type="hidden"
@ -103,10 +104,12 @@
import { cropCanvasAndExportToPNG } from './crop_canvas' import { cropCanvasAndExportToPNG } from './crop_canvas'
import { IconReload, IconTextSize, IconSignature, IconArrowsDiagonalMinimize2 } from '@tabler/icons-vue' import { IconReload, IconTextSize, IconSignature, IconArrowsDiagonalMinimize2 } from '@tabler/icons-vue'
import SignaturePad from 'signature_pad' import SignaturePad from 'signature_pad'
import AppearsOn from './appears_on'
export default { export default {
name: 'InitialsStep', name: 'InitialsStep',
components: { components: {
AppearsOn,
IconReload, IconReload,
IconTextSize, IconTextSize,
IconSignature, IconSignature,

@ -89,6 +89,7 @@
</a> </a>
</div> </div>
</div> </div>
<AppearsOn :field="field" />
<input <input
:value="modelValue || computedPreviousValue" :value="modelValue || computedPreviousValue"
type="hidden" type="hidden"
@ -122,12 +123,14 @@
import { IconReload, IconCamera, IconSignature, IconTextSize, IconArrowsDiagonalMinimize2 } from '@tabler/icons-vue' import { IconReload, IconCamera, IconSignature, IconTextSize, IconArrowsDiagonalMinimize2 } from '@tabler/icons-vue'
import { cropCanvasAndExportToPNG } from './crop_canvas' import { cropCanvasAndExportToPNG } from './crop_canvas'
import SignaturePad from 'signature_pad' import SignaturePad from 'signature_pad'
import AppearsOn from './appears_on'
let isFontLoaded = false let isFontLoaded = false
export default { export default {
name: 'SignatureStep', name: 'SignatureStep',
components: { components: {
AppearsOn,
IconReload, IconReload,
IconCamera, IconCamera,
IconTextSize, IconTextSize,

@ -10,6 +10,7 @@
v-else v-else
class="py-1" class="py-1"
/> />
<AppearsOn :field="field" />
<div class="items-center flex"> <div class="items-center flex">
<input <input
v-if="!isTextArea" v-if="!isTextArea"
@ -56,11 +57,13 @@
<script> <script>
import { IconAlignBoxLeftTop } from '@tabler/icons-vue' import { IconAlignBoxLeftTop } from '@tabler/icons-vue'
import AppearsOn from './appears_on'
export default { export default {
name: 'TextStep', name: 'TextStep',
components: { components: {
IconAlignBoxLeftTop IconAlignBoxLeftTop,
AppearsOn
}, },
inject: ['t'], inject: ['t'],
props: { props: {

Loading…
Cancel
Save