add number validation
This commit is contained in:
@@ -189,7 +189,7 @@ module Api
|
||||
{ metadata: {}, values: {}, roles: [], readonly_fields: [], message: %i[subject body],
|
||||
fields: [:name, :uuid, :default_value, :value, :title, :description,
|
||||
:readonly, :required, :validation_pattern, :invalid_message,
|
||||
{ default_value: [], value: [], preferences: {} }] }]]
|
||||
{ default_value: [], value: [], preferences: {}, validation: {} }] }]]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ module Api
|
||||
{ preferences: {},
|
||||
conditions: [%i[field_uuid value action operation]],
|
||||
options: [%i[value uuid]],
|
||||
validation: %i[message pattern],
|
||||
validation: %i[message pattern min max step],
|
||||
areas: [%i[x y w h cell_w attachment_uuid option_uuid page]] }]]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -124,7 +124,7 @@ class TemplatesController < ApplicationController
|
||||
{ preferences: {},
|
||||
conditions: [%i[field_uuid value action operation]],
|
||||
options: [%i[value uuid]],
|
||||
validation: %i[message pattern],
|
||||
validation: %i[message pattern min max step],
|
||||
areas: [%i[x y w h cell_w attachment_uuid option_uuid page]] }]] }
|
||||
)
|
||||
end
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
</template>
|
||||
</label>
|
||||
<button
|
||||
v-if="withToday"
|
||||
class="btn btn-outline btn-sm !normal-case font-normal set-current-date-button"
|
||||
@click.prevent="[setCurrentDate(), $emit('focus')]"
|
||||
>
|
||||
@@ -46,6 +47,8 @@
|
||||
:id="field.uuid"
|
||||
ref="input"
|
||||
v-model="value"
|
||||
:min="validationMin"
|
||||
:max="validationMax"
|
||||
class="base-input !text-2xl text-center w-full"
|
||||
:required="field.required"
|
||||
type="date"
|
||||
@@ -89,6 +92,44 @@ export default {
|
||||
},
|
||||
emits: ['update:model-value', 'focus', 'submit'],
|
||||
computed: {
|
||||
dateNowString () {
|
||||
const today = new Date()
|
||||
|
||||
const yyyy = today.getFullYear()
|
||||
const mm = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const dd = String(today.getDate()).padStart(2, '0')
|
||||
|
||||
return `${yyyy}-${mm}-${dd}`
|
||||
},
|
||||
validationMin () {
|
||||
if (this.field.validation?.min) {
|
||||
return ['{{date}}', '{date}'].includes(this.field.validation.min) ? this.dateNowString : this.field.validation.min
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
validationMax () {
|
||||
if (this.field.validation?.max) {
|
||||
return ['{{date}}', '{date}'].includes(this.field.validation.max) ? this.dateNowString : this.field.validation.max
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
withToday () {
|
||||
const todayDate = new Date().setHours(0, 0, 0, 0)
|
||||
|
||||
if (this.validationMin) {
|
||||
if (new Date(this.validationMin).setHours(0, 0, 0, 0) <= todayDate) {
|
||||
return this.validationMax ? (new Date(this.validationMax).setHours(0, 0, 0, 0) >= todayDate) : true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else if (this.validationMax) {
|
||||
return new Date(this.validationMax).setHours(0, 0, 0, 0) >= todayDate
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
},
|
||||
value: {
|
||||
set (value) {
|
||||
this.$emit('update:model-value', value)
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
:id="field.uuid"
|
||||
v-model="number"
|
||||
type="number"
|
||||
:step="field.validation?.step || 'any'"
|
||||
:min="field.validation?.min"
|
||||
:max="field.validation?.max"
|
||||
class="base-input !text-2xl w-full"
|
||||
step="any"
|
||||
:required="field.required"
|
||||
:placeholder="`${t('type_here_')}${field.required ? '' : ` (${t('optional')})`}`"
|
||||
:name="`values[${field.uuid}]`"
|
||||
|
||||
@@ -1,31 +1,4 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="field.type === 'number'"
|
||||
class="py-1.5 px-1 relative"
|
||||
@click.stop
|
||||
>
|
||||
<select
|
||||
:placeholder="t('format')"
|
||||
class="select select-bordered select-xs font-normal w-full max-w-xs !h-7 !outline-0 bg-transparent"
|
||||
@change="[field.preferences ||= {}, field.preferences.format = $event.target.value, save()]"
|
||||
>
|
||||
<option
|
||||
v-for="format in numberFormats"
|
||||
:key="format"
|
||||
:value="format"
|
||||
:selected="format === field.preferences?.format || (format === 'none' && !field.preferences?.format)"
|
||||
>
|
||||
{{ formatNumber(123456789.567, format) }}
|
||||
</option>
|
||||
</select>
|
||||
<label
|
||||
:style="{ backgroundColor }"
|
||||
class="absolute -top-1 left-2.5 px-1 h-4"
|
||||
style="font-size: 8px"
|
||||
>
|
||||
{{ t('format') }}
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="field.type === 'verification'"
|
||||
class="py-1.5 px-1 relative"
|
||||
@@ -217,6 +190,77 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="field.type === 'number'"
|
||||
class="py-1.5 px-1 relative flex space-x-1"
|
||||
@click.stop
|
||||
>
|
||||
<div class="w-1/2 relative">
|
||||
<input
|
||||
:placeholder="t('min')"
|
||||
type="number"
|
||||
min="0"
|
||||
:value="field.validation?.min"
|
||||
class="input input-bordered w-full input-xs h-7 !outline-0 bg-transparent"
|
||||
@input="[field.validation ||= {}, $event.target.value ? field.validation.min = $event.target.value : delete field.validation.min]"
|
||||
@blur="save"
|
||||
>
|
||||
<label
|
||||
v-if="field.validation?.min"
|
||||
:style="{ backgroundColor }"
|
||||
class="absolute -top-2.5 left-1.5 px-1 h-4"
|
||||
style="font-size: 8px"
|
||||
>
|
||||
{{ t('min') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="w-1/2 relative">
|
||||
<input
|
||||
:placeholder="t('max')"
|
||||
type="number"
|
||||
min="1"
|
||||
class="input input-bordered w-full input-xs h-7 !outline-0 bg-transparent"
|
||||
:value="field.validation?.max"
|
||||
@input="[field.validation ||= {}, $event.target.value ? field.validation.max = $event.target.value : delete field.validation.max]"
|
||||
@blur="save"
|
||||
>
|
||||
<label
|
||||
v-if="field.validation?.max"
|
||||
:style="{ backgroundColor }"
|
||||
class="absolute -top-2.5 left-1.5 px-1 h-4"
|
||||
style="font-size: 8px"
|
||||
>
|
||||
{{ t('max') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="field.type === 'number'"
|
||||
class="py-1.5 px-1 relative"
|
||||
@click.stop
|
||||
>
|
||||
<select
|
||||
:placeholder="t('format')"
|
||||
class="select select-bordered select-xs font-normal w-full max-w-xs !h-7 !outline-0 bg-transparent"
|
||||
@change="[field.preferences ||= {}, field.preferences.format = $event.target.value, save()]"
|
||||
>
|
||||
<option
|
||||
v-for="format in numberFormats"
|
||||
:key="format"
|
||||
:value="format"
|
||||
:selected="format === field.preferences?.format || (format === 'none' && !field.preferences?.format)"
|
||||
>
|
||||
{{ formatNumber(123456789.567, format) }}
|
||||
</option>
|
||||
</select>
|
||||
<label
|
||||
:style="{ backgroundColor }"
|
||||
class="absolute -top-1 left-2.5 px-1 h-4"
|
||||
style="font-size: 8px"
|
||||
>
|
||||
{{ t('format') }}
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="['text', 'cells'].includes(field.type) && field.validation && !validations[field.validation.pattern] && !lengthValidation"
|
||||
class="py-1.5 px-1 relative"
|
||||
|
||||
@@ -275,6 +275,7 @@ module Submissions
|
||||
end
|
||||
|
||||
field['preferences'] = (field['preferences'] || {}).merge(attrs['preferences']) if attrs['preferences'].present?
|
||||
field['validation'] = (field['validation'] || {}).merge(attrs['validation']) if attrs['validation'].present?
|
||||
|
||||
return field if attrs['validation_pattern'].blank?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user