text formula

master^2
Pete Matsyburka 5 days ago
parent b8c29324b8
commit 5ec8e4ccc7

@ -69,8 +69,8 @@
:attachments-index="attachmentsIndex"
/>
<FieldArea
v-else-if="item.type === 'formula_area' && isMathLoaded"
:model-value="calculateFormula(item.field)"
v-else-if="item.type === 'formula_area' && (isMathLoaded || item.field.type === 'text')"
:model-value="item.field.type === 'text' ? evalTextFormula(item.field) : calculateFormula(item.field)"
:is-inline-size="isInlineSize"
:field="item.field"
:area="item.area"
@ -289,6 +289,7 @@ export default {
methods: {
normalizeFormula: FormulaAreas.methods.normalizeFormula,
calculateFormula: FormulaAreas.methods.calculateFormula,
evalTextFormula: FormulaAreas.methods.evalTextFormula,
scrollInContainer: FieldAreas.methods.scrollInContainer,
scrollIntoArea: FieldAreas.methods.scrollIntoArea,
scrollIntoField: FieldAreas.methods.scrollIntoField,

@ -12,8 +12,8 @@
:to="findPageElementForArea(area)"
>
<FieldArea
v-if="isMathLoaded"
:model-value="calculateFormula(field)"
v-if="isMathLoaded || field.type === 'text'"
:model-value="field.type === 'text' ? evalTextFormula(field) : calculateFormula(field)"
:is-inline-size="isInlineSize"
:field="field"
:area="area"
@ -95,6 +95,25 @@ export default {
})
return this.math.evaluate(transformedFormula.toLowerCase())
},
evalTextFormula (field, depth = 0) {
if (depth > 10) return ''
return field.preferences.formula.replace(/{{(.*?)}}/g, (match, uuid) => {
const formulaField = this.fieldsUuidIndex[uuid]
if (formulaField?.preferences?.formula) {
if (formulaField.type === 'text') {
return this.evalTextFormula(formulaField, depth + 1)
} else if (this.isMathLoaded) {
return this.calculateFormula(formulaField)
}
}
const value = this.readonlyValues[uuid] ?? this.values[uuid]
return Array.isArray(value) ? value.join(', ') : (value ?? '')
})
}
}
}

@ -1259,7 +1259,7 @@ export default {
return formulaFields.reduce((acc, f) => {
if (this.conditionalFieldIndex[f.uuid] !== false) {
acc[f.uuid] = this.calculateFormula(f)
acc[f.uuid] = f.type === 'text' ? this.evalTextFormula(f) : this.calculateFormula(f)
}
return acc
@ -1526,6 +1526,25 @@ export default {
return this.math.evaluate(transformedFormula.toLowerCase())
},
evalTextFormula (field, depth = 0) {
if (depth > 10) return ''
return field.preferences.formula.replace(/{{(.*?)}}/g, (match, uuid) => {
const formulaField = this.fieldsUuidIndex[uuid]
if (formulaField?.preferences?.formula) {
if (formulaField.type === 'text') {
return this.evalTextFormula(formulaField, depth + 1)
} else if (this.isMathLoaded) {
return this.calculateFormula(formulaField)
}
}
const value = formulaField?.default_value
return Array.isArray(value) ? value.join(', ') : (value ?? '')
})
},
hasFormulaDependencyValue (field) {
const normalized = this.normalizeFormula(field.preferences.formula)

@ -611,7 +611,7 @@ export default {
return this.withCondition && !['stamp', 'heading'].includes(this.field.type)
},
showFormula () {
return this.field.type === 'number' || this.field.type === 'payment'
return this.field.type === 'number' || this.field.type === 'payment' || !!this.field.preferences?.formula
},
showRequired () {
return this.withRequired && !['phone', 'stamp', 'verification', 'strikethrough', 'heading'].includes(this.field.type)

@ -500,7 +500,7 @@
</label>
</li>
<li
v-if="field.type == 'number'"
v-if="field.type == 'number' || field.preferences?.formula"
class="field-settings-formula"
>
<label

@ -61,7 +61,10 @@
@input="resizeTextarea"
/>
</div>
<div class="mb-3 mt-1">
<div
v-if="field.type !== 'text'"
class="mb-3 mt-1"
>
<div
target="blank"
class="text-sm mb-2 inline space-x-2 font-mono"
@ -161,7 +164,9 @@ export default {
computed: {
fields () {
return this.template.fields.reduce((acc, f) => {
if (f !== this.field && this.isNumberField(f) && (!f.preferences?.formula || !f.preferences.formula.includes(this.field.uuid))) {
const isAllowed = this.field.type === 'text' ? this.isTextField(f) : this.isNumberField(f)
if (f !== this.field && isAllowed && (!f.preferences?.formula || !f.preferences.formula.includes(this.field.uuid))) {
acc.push(f)
}
@ -179,6 +184,9 @@ export default {
isNumberField (field) {
return field.type === 'number' || (['radio', 'select'].includes(field.type) && field.options?.every((o) => String(o.value).match(/^[\d.-]+$/)))
},
isTextField (field) {
return ['text', 'number', 'select', 'radio', 'cells', 'phone'].includes(field.type)
},
humanizeFormula (text) {
return text.replace(/{{(.*?)}}/g, (match, uuid) => {
const foundField = this.template.fields.find((f) => f.uuid === uuid)

@ -220,9 +220,16 @@ module Submitters
submitter.values
end
formula = normalize_formula(formula, submitter.submission, submission_values:)
values = submission_values.merge(acc.compact_blank)
acc[field['uuid']] = calculate_formula_value(formula, submission_values.merge(acc.compact_blank))
acc[field['uuid']] =
if field['type'] == 'text'
eval_text_formula_value(formula, values, submitter.submission)
else
normalized_formula = normalize_formula(formula, submitter.submission, submission_values:)
calculate_formula_value(normalized_formula, values)
end
end
computed_values.compact_blank
@ -250,6 +257,10 @@ module Submitters
0
end
def eval_text_formula_value(_formula, _values, _submission)
''
end
def replace_current_date_placeholders(submitter)
submitter.values.each_with_object({}) do |(uuid, v), acc|
acc[uuid] =

Loading…
Cancel
Save