diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue
index 1c7052289..62181fc5a 100644
--- a/app/javascript/submission_form/area.vue
+++ b/app/javascript/submission_form/area.vue
@@ -450,8 +450,18 @@ export default {
}
},
formatNumber (number, format) {
+ if (!number && number !== 0) {
+ return ''
+ }
+
if (format === 'comma') {
return new Intl.NumberFormat('en-US').format(number)
+ } else if (format === 'usd') {
+ return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(number)
+ } else if (format === 'gbp') {
+ return new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(number)
+ } else if (format === 'eur') {
+ return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(number)
} else if (format === 'dot') {
return new Intl.NumberFormat('de-DE').format(number)
} else if (format === 'space') {
diff --git a/app/javascript/submission_form/areas.vue b/app/javascript/submission_form/areas.vue
index 05fe7e2fa..d17a728cb 100644
--- a/app/javascript/submission_form/areas.vue
+++ b/app/javascript/submission_form/areas.vue
@@ -157,13 +157,15 @@ export default {
const formContainer = root.getElementById('form_container')
const container = root.body || root.querySelector('div')
- const padding = 64
+ const isAndroid = /android/i.test(navigator.userAgent)
+ const padding = isAndroid ? 128 : 64
+ const scrollboxTop = isAndroid ? scrollbox.getBoundingClientRect().top : 0
const boxRect = scrollbox.children[0].getBoundingClientRect()
const targetRect = target.getBoundingClientRect()
const targetTopRelativeToBox = targetRect.top - boxRect.top
- scrollbox.scrollTo({ top: targetTopRelativeToBox - container.offsetHeight + formContainer.offsetHeight + target.offsetHeight + padding, behavior: 'smooth' })
+ scrollbox.scrollTo({ top: targetTopRelativeToBox + scrollboxTop - container.offsetHeight + formContainer.offsetHeight + target.offsetHeight + padding, behavior: 'smooth' })
},
setAreaRef (el) {
if (el) {
diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue
index c1d0d8a1c..cb41d182b 100644
--- a/app/javascript/submission_form/form.vue
+++ b/app/javascript/submission_form/form.vue
@@ -1113,9 +1113,9 @@ export default {
this.minimizeForm()
}
- const isMobileSafariIos = 'ontouchstart' in window && navigator.maxTouchPoints > 0 && /AppleWebKit/i.test(navigator.userAgent)
+ const isMobile = 'ontouchstart' in window && navigator.maxTouchPoints > 0 && /AppleWebKit|android/i.test(navigator.userAgent)
- if (isMobileSafariIos || /iPhone|iPad|iPod/i.test(navigator.userAgent)) {
+ if (isMobile || /iPhone|iPad|iPod/i.test(navigator.userAgent)) {
this.$nextTick(() => {
const root = this.$root.$el.parentNode.getRootNode()
const scrollbox = root.getElementById('scrollbox')
diff --git a/app/javascript/submission_form/phone_step.vue b/app/javascript/submission_form/phone_step.vue
index c6c320e47..84875a86e 100644
--- a/app/javascript/submission_form/phone_step.vue
+++ b/app/javascript/submission_form/phone_step.vue
@@ -297,7 +297,7 @@ export default {
const data = await resp.json()
if (resp.status === 422) {
- alert(this.t('number_phone_is_invalid').replace('{number}', this.fullInternationalPhoneValue))
+ alert(data.error || this.t('number_phone_is_invalid').replace('{number}', this.fullInternationalPhoneValue))
} else if (resp.status === 429) {
alert(data.error)
}
diff --git a/app/javascript/template_builder/area.vue b/app/javascript/template_builder/area.vue
index afd6d62c9..ccb62ab9c 100644
--- a/app/javascript/template_builder/area.vue
+++ b/app/javascript/template_builder/area.vue
@@ -479,7 +479,7 @@ export default {
methods: {
buildDefaultName: Field.methods.buildDefaultName,
closeDropdown () {
- document.activeElement.blur()
+ this.$el.getRootNode().activeElement.blur()
},
maybeToggleDefaultValue () {
if (['text', 'number'].includes(this.field.type)) {
@@ -521,6 +521,12 @@ export default {
formatNumber (number, format) {
if (format === 'comma') {
return new Intl.NumberFormat('en-US').format(number)
+ } else if (format === 'usd') {
+ return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(number)
+ } else if (format === 'gbp') {
+ return new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(number)
+ } else if (format === 'eur') {
+ return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(number)
} else if (format === 'dot') {
return new Intl.NumberFormat('de-DE').format(number)
} else if (format === 'space') {
diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue
index 1e22e3b9b..70e9b0f60 100644
--- a/app/javascript/template_builder/builder.vue
+++ b/app/javascript/template_builder/builder.vue
@@ -222,8 +222,8 @@
({ value: option, uuid: v4() }))
+ } else {
+ field.options = [{ value: '', uuid: v4() }]
+ }
}
if (['stamp', 'heading'].includes(field.type)) {
@@ -1510,29 +1514,29 @@ export default {
onDocumentRemove (item) {
if (window.confirm(this.t('are_you_sure_'))) {
this.template.schema.splice(this.template.schema.indexOf(item), 1)
- }
- const removedFieldUuids = []
+ const removedFieldUuids = []
- this.template.fields.forEach((field) => {
- [...(field.areas || [])].forEach((area) => {
- if (area.attachment_uuid === item.attachment_uuid) {
- field.areas.splice(field.areas.indexOf(area), 1)
+ this.template.fields.forEach((field) => {
+ [...(field.areas || [])].forEach((area) => {
+ if (area.attachment_uuid === item.attachment_uuid) {
+ field.areas.splice(field.areas.indexOf(area), 1)
- removedFieldUuids.push(field.uuid)
- }
+ removedFieldUuids.push(field.uuid)
+ }
+ })
})
- })
- this.template.fields =
- this.template.fields.filter((f) => !removedFieldUuids.includes(f.uuid) || f.areas?.length)
+ this.template.fields =
+ this.template.fields.filter((f) => !removedFieldUuids.includes(f.uuid) || f.areas?.length)
- this.save()
+ this.save()
+ }
},
onDocumentReplace (data) {
const { replaceSchemaItem, schema, documents } = data
- this.template.schema.splice(this.template.schema.indexOf(replaceSchemaItem), 1, schema[0])
+ this.template.schema.splice(this.template.schema.indexOf(replaceSchemaItem), 1, { ...replaceSchemaItem, ...schema[0] })
this.template.documents.push(...documents)
if (data.fields) {
diff --git a/app/javascript/template_builder/field.vue b/app/javascript/template_builder/field.vue
index 169f2ae36..b4941cf7d 100644
--- a/app/javascript/template_builder/field.vue
+++ b/app/javascript/template_builder/field.vue
@@ -192,14 +192,14 @@
class="w-full input input-primary input-xs text-sm bg-transparent"
:placeholder="`${t('option')} ${index + 1}`"
type="text"
- :readonly="!editable"
+ :readonly="!editable || defaultField"
required
dir="auto"
@focus="maybeFocusOnOptionArea(option)"
@blur="save"
>
+
+
+
+