this.$refs.textContainer.clientHeight ? this.modelValue.length : 0
})
}
+ },
+ methods: {
+ updateMultipleSelectValue (value) {
+ if (this.modelValue?.includes(value)) {
+ const newValue = [...this.modelValue]
+
+ newValue.splice(newValue.indexOf(value), 1)
+
+ this.$emit('update:model-value', newValue)
+ } else {
+ const newValue = this.modelValue ? [...this.modelValue] : []
+
+ newValue.push(value)
+
+ this.$emit('update:model-value', newValue)
+ }
+ }
}
}
diff --git a/app/javascript/template_builder/area.vue b/app/javascript/template_builder/area.vue
index c5a1cfc45..a405c2742 100644
--- a/app/javascript/template_builder/area.vue
+++ b/app/javascript/template_builder/area.vue
@@ -66,7 +66,7 @@
@keydown.enter.prevent="onNameEnter"
@focus="onNameFocus"
@blur="onNameBlur"
- >{{ field.name || defaultName }}
+ >{{ optionIndexText }} {{ field.name || defaultName }}
o.uuid === this.area.option_uuid) + 1}.`
+ } else {
+ return ''
+ }
+ },
cells () {
const cells = []
diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue
index 248e3122a..d85582eff 100644
--- a/app/javascript/template_builder/builder.vue
+++ b/app/javascript/template_builder/builder.vue
@@ -168,7 +168,7 @@
:selected-submitter="selectedSubmitter"
class="md:hidden"
:editable="editable"
- @cancel="drawField = null"
+ @cancel="[drawField = null, drawOption = null]"
@change-submitter="[selectedSubmitter = $event, drawField.submitter_uuid = $event.uuid]"
/>
@@ -225,7 +225,7 @@
:default-fields="defaultFields"
:with-sticky-submitters="withStickySubmitters"
:editable="editable"
- @set-draw="drawField = $event"
+ @set-draw="[drawField = $event.field, drawOption = $event.option]"
@set-drag="dragField = $event"
@change-submitter="selectedSubmitter = $event"
@drag-end="dragField = null"
@@ -354,6 +354,7 @@ export default {
isSaving: false,
selectedSubmitter: null,
drawField: null,
+ drawOption: null,
dragField: null
}
},
@@ -433,6 +434,7 @@ export default {
}
this.drawField = field
+ this.drawOption = null
},
undo () {
if (this.undoStack.length > 1) {
@@ -482,6 +484,7 @@ export default {
onKeyUp (e) {
if (e.code === 'Escape') {
this.drawField = null
+ this.drawOption = null
this.selectedAreaRef.value = null
}
@@ -528,6 +531,16 @@ export default {
},
onDraw (area) {
if (this.drawField) {
+ if (this.drawOption) {
+ const areaWithoutOption = this.drawField.areas?.find((a) => !a.option_uuid)
+
+ if (areaWithoutOption && !this.drawField.areas.find((a) => a.option_uuid === this.drawField.options[0].uuid)) {
+ areaWithoutOption.option_uuid = this.drawField.options[0].uuid
+ }
+
+ area.option_uuid = this.drawOption.uuid
+ }
+
this.drawField.areas ||= []
this.drawField.areas.push(area)
@@ -536,6 +549,7 @@ export default {
}
this.drawField = null
+ this.drawOption = null
this.selectedAreaRef.value = area
diff --git a/app/javascript/template_builder/field.vue b/app/javascript/template_builder/field.vue
index 3fa0abf7a..00a713457 100644
--- a/app/javascript/template_builder/field.vue
+++ b/app/javascript/template_builder/field.vue
@@ -58,7 +58,7 @@
v-if="field && !field.areas.length"
title="Draw"
class="relative cursor-pointer text-transparent group-hover:text-base-content"
- @click="$emit('set-draw', field)"
+ @click="$emit('set-draw', { field })"
>
-
+
{{ index + 1 }}.
+
+
+
+
@@ -248,7 +271,7 @@ export default {
IconCopy,
FieldType
},
- inject: ['template', 'save', 'backgroundColor'],
+ inject: ['template', 'save', 'backgroundColor', 'selectedAreaRef'],
props: {
field: {
type: Object,
@@ -306,6 +329,13 @@ export default {
}, 1)
}
},
+ maybeFocusOnOptionArea (option) {
+ const area = this.field.areas.find((a) => a.option_uuid === option.uuid)
+
+ if (area) {
+ this.selectedAreaRef.value = area
+ }
+ },
scrollToFirstArea () {
return this.field.areas?.[0] && this.$emit('scroll-to', this.field.areas[0])
},
@@ -317,6 +347,12 @@ export default {
this.save()
},
+ removeOption (option) {
+ this.field.options.splice(this.field.options.indexOf(option), 1)
+ this.field.areas.splice(this.field.areas.findIndex((a) => a.option_uuid === option.uuid), 1)
+
+ this.save()
+ },
maybeUpdateOptions () {
delete this.field.default_value
diff --git a/app/views/submissions/_value.html.erb b/app/views/submissions/_value.html.erb
index 11ef194ce..9306f2371 100644
--- a/app/views/submissions/_value.html.erb
+++ b/app/views/submissions/_value.html.erb
@@ -11,9 +11,16 @@
<% end %>
+
<%= svg_icon('check', class: "aspect-square #{area['w'] > area['h'] ? '!w-auto !h-full' : '!w-full !h-auto'}") %>
+ <% elsif field['type'].in?(%w[multiple radio]) && area['option_uuid'] %>
+ <% option = field['options']&.find { |o| o['uuid'] == area['option_uuid'] } %>
+ <% if option && Array.wrap(value).include?(option['value']) %>
+
+ <%= svg_icon('check', class: "aspect-square #{area['w'] > area['h'] ? '!w-auto !h-full' : '!w-full !h-auto'}") %>
+
+ <% end %>
<% elsif field['type'] == 'cells' %>
<% cell_width = area['cell_w'] / area['w'] * 100 %>
diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb
index 4c8344b57..f26a28dc8 100644
--- a/lib/submissions/generate_result_attachments.rb
+++ b/lib/submissions/generate_result_attachments.rb
@@ -124,7 +124,13 @@ def call(submitter)
layouter.fit(items, area['w'] * width, height_diff.positive? ? box_height : area['h'] * height)
.draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN,
height - (area['y'] * height) + height_diff - TEXT_TOP_MARGIN)
- when 'checkbox'
+ when ->(type) { type == 'checkbox' || (type.in?(%w[multiple radio]) && area['option_uuid'].present?) }
+ if field['type'].in?(%w[multiple radio])
+ option = field['options']&.find { |o| o['uuid'] == area['option_uuid'] }
+
+ value = Array.wrap(value).include?(option['value'])
+ end
+
next unless value == true
scale = [(area['w'] * width) / PdfIcons::WIDTH, (area['h'] * height) / PdfIcons::HEIGHT].min