use hash for field options
This commit is contained in:
@@ -57,7 +57,7 @@ module Api
|
||||
schema: [%i[attachment_uuid name]],
|
||||
submitters: [%i[name uuid]],
|
||||
fields: [[:uuid, :submitter_uuid, :name, :type, :required, :readonly, :default_value,
|
||||
{ options: [], areas: [%i[x y w h cell_w attachment_uuid page]] }]]
|
||||
{ options: [%i[value uuid]], areas: [%i[x y w h cell_w attachment_uuid option_uuid page]] }]]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -99,12 +99,12 @@
|
||||
{{ t('select_your_option') }}
|
||||
</option>
|
||||
<option
|
||||
v-for="(option, index) in currentField.options"
|
||||
:key="index"
|
||||
:selected="values[currentField.uuid] == option"
|
||||
:value="option"
|
||||
v-for="option in currentField.options"
|
||||
:key="option.uuid"
|
||||
:selected="values[currentField.uuid] == option.value"
|
||||
:value="option.value"
|
||||
>
|
||||
{{ option }}
|
||||
{{ option.value }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -119,24 +119,24 @@
|
||||
<div class="flex w-full">
|
||||
<div class="space-y-3.5 mx-auto">
|
||||
<div
|
||||
v-for="(option, index) in currentField.options"
|
||||
:key="index"
|
||||
v-for="option in currentField.options"
|
||||
:key="option.uuid"
|
||||
>
|
||||
<label
|
||||
:for="currentField.uuid + option"
|
||||
:for="option.uuid"
|
||||
class="flex items-center space-x-3"
|
||||
>
|
||||
<input
|
||||
:id="currentField.uuid + option"
|
||||
:id="option.uuid"
|
||||
v-model="values[currentField.uuid]"
|
||||
type="radio"
|
||||
class="base-radio !h-7 !w-7"
|
||||
:name="`values[${currentField.uuid}]`"
|
||||
:value="option"
|
||||
:value="option.value"
|
||||
:required="currentField.required"
|
||||
>
|
||||
<span class="text-xl">
|
||||
{{ option }}
|
||||
{{ option.value }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -7,25 +7,25 @@
|
||||
<div class="flex w-full">
|
||||
<div class="space-y-3.5 mx-auto">
|
||||
<div
|
||||
v-for="(option, index) in field.options"
|
||||
:key="index"
|
||||
v-for="option in field.options"
|
||||
:key="option.uuid"
|
||||
>
|
||||
<label
|
||||
:for="field.uuid + option"
|
||||
:for="option.uuid"
|
||||
class="flex items-center space-x-3"
|
||||
>
|
||||
<input
|
||||
:id="field.uuid + option"
|
||||
:id="option.uuid"
|
||||
:ref="setInputRef"
|
||||
type="checkbox"
|
||||
:name="`values[${field.uuid}][]`"
|
||||
:value="option"
|
||||
:value="option.value"
|
||||
class="base-checkbox !h-7 !w-7"
|
||||
:checked="(modelValue || []).includes(option)"
|
||||
:checked="(modelValue || []).includes(option.value)"
|
||||
@change="onChange"
|
||||
>
|
||||
<span class="text-xl">
|
||||
{{ option }}
|
||||
{{ option.value }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -140,6 +140,7 @@ import FieldSubmitter from './field_submitter'
|
||||
import FieldType from './field_type'
|
||||
import Field from './field'
|
||||
import { IconX } from '@tabler/icons-vue'
|
||||
import { v4 } from 'uuid'
|
||||
|
||||
export default {
|
||||
name: 'FieldArea',
|
||||
@@ -303,7 +304,7 @@ export default {
|
||||
}
|
||||
|
||||
if (['select', 'multiple', 'radio'].includes(this.field.type)) {
|
||||
this.field.options ||= ['']
|
||||
this.field.options ||= [{ value: '', uuid: v4() }]
|
||||
}
|
||||
|
||||
(this.field.areas || []).forEach((area) => {
|
||||
|
||||
@@ -429,7 +429,7 @@ export default {
|
||||
}
|
||||
|
||||
if (['select', 'multiple', 'radio'].includes(type)) {
|
||||
field.options = ['']
|
||||
field.options = [{ value: '', uuid: v4() }]
|
||||
}
|
||||
|
||||
this.drawField = field
|
||||
@@ -592,7 +592,7 @@ export default {
|
||||
}
|
||||
|
||||
if (['select', 'multiple', 'radio'].includes(field.type)) {
|
||||
field.options = ['']
|
||||
field.options = [{ value: '', uuid: v4() }]
|
||||
}
|
||||
|
||||
const fieldArea = {
|
||||
|
||||
@@ -194,17 +194,19 @@
|
||||
<div
|
||||
v-if="field.options"
|
||||
class="border-t border-base-300 mx-2 pt-2 space-y-1.5"
|
||||
draggable="true"
|
||||
@dragstart.prevent.stop
|
||||
>
|
||||
<div
|
||||
v-for="(option, index) in field.options"
|
||||
:key="index"
|
||||
:key="option.uuid"
|
||||
class="flex space-x-1.5 items-center"
|
||||
>
|
||||
<span class="text-sm w-3.5">
|
||||
{{ index + 1 }}.
|
||||
</span>
|
||||
<input
|
||||
v-model="field.options[index]"
|
||||
v-model="option.value"
|
||||
class="w-full input input-primary input-xs text-sm bg-transparent"
|
||||
type="text"
|
||||
required
|
||||
@@ -220,7 +222,7 @@
|
||||
<button
|
||||
v-if="field.options"
|
||||
class="text-center text-sm w-full pb-1"
|
||||
@click="[field.options.push(''), save()]"
|
||||
@click="addOption"
|
||||
>
|
||||
+ Add option
|
||||
</button>
|
||||
@@ -233,6 +235,7 @@
|
||||
import Contenteditable from './contenteditable'
|
||||
import FieldType from './field_type'
|
||||
import { IconShape, IconNewSection, IconTrashX, IconCopy, IconSettings } from '@tabler/icons-vue'
|
||||
import { v4 } from 'uuid'
|
||||
|
||||
export default {
|
||||
name: 'TemplateField',
|
||||
@@ -309,6 +312,11 @@ export default {
|
||||
closeDropdown () {
|
||||
document.activeElement.blur()
|
||||
},
|
||||
addOption () {
|
||||
this.field.options.push({ value: '', uuid: v4() })
|
||||
|
||||
this.save()
|
||||
},
|
||||
maybeUpdateOptions () {
|
||||
delete this.field.default_value
|
||||
|
||||
@@ -317,7 +325,7 @@ export default {
|
||||
}
|
||||
|
||||
if (['radio', 'multiple', 'select'].includes(this.field.type)) {
|
||||
this.field.options ||= ['']
|
||||
this.field.options ||= [{ value: '', uuid: v4() }]
|
||||
}
|
||||
|
||||
(this.field.areas || []).forEach((area) => {
|
||||
|
||||
@@ -252,7 +252,7 @@ export default {
|
||||
}
|
||||
|
||||
if (['select', 'multiple', 'radio'].includes(type)) {
|
||||
field.options = ['']
|
||||
field.options = [{ value: '', uuid: v4() }]
|
||||
}
|
||||
|
||||
this.fields.push(field)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class UpdateFieldOptions < ActiveRecord::Migration[7.0]
|
||||
class MigrationTemplate < ApplicationRecord
|
||||
self.table_name = 'templates'
|
||||
end
|
||||
|
||||
class MigrationSubmission < ApplicationRecord
|
||||
self.table_name = 'submissions'
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics
|
||||
def up
|
||||
MigrationTemplate.find_each do |template|
|
||||
next if template.fields.blank?
|
||||
|
||||
template_fields = JSON.parse(template.fields)
|
||||
|
||||
new_fields = template_fields.deep_dup
|
||||
|
||||
new_fields.each do |field|
|
||||
if field['options'].present? && !field['options'].first.is_a?(Hash)
|
||||
field['options'] = field['options'].map { |o| { value: o || '', uuid: SecureRandom.uuid } }
|
||||
end
|
||||
end
|
||||
|
||||
template.update_columns(fields: new_fields.to_json) if template_fields != new_fields
|
||||
end
|
||||
|
||||
MigrationSubmission.find_each do |submission|
|
||||
next if submission.template_fields.blank?
|
||||
|
||||
template_fields = JSON.parse(submission.template_fields)
|
||||
|
||||
new_fields = template_fields.deep_dup
|
||||
|
||||
new_fields.each do |field|
|
||||
if field['options'].present? && !field['options'].first.is_a?(Hash)
|
||||
field['options'] = field['options'].map { |o| { value: o || '', uuid: SecureRandom.uuid } }
|
||||
end
|
||||
end
|
||||
|
||||
submission.update_columns(template_fields: new_fields.to_json) if template_fields != new_fields
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics
|
||||
|
||||
def down
|
||||
nil
|
||||
end
|
||||
end
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_11_02_171817) do
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_11_12_224432) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user