mirror of
https://github.com/grey-cat-1908/formaptix-web.git
synced 2024-09-22 19:21:59 +03:00
better types of questions support on answers page
This commit is contained in:
parent
cebd6adbd2
commit
63ccc17cc0
11 changed files with 409 additions and 62 deletions
133
src/components/answers/ScaleValue.vue
Normal file
133
src/components/answers/ScaleValue.vue
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<template>
|
||||||
|
<div class="default-card" v-if="modelValue">
|
||||||
|
<div class="view-form-q-title">
|
||||||
|
<h3 class="form-q-title">{{ label }}</h3>
|
||||||
|
<p class="form-q-description">{{ description }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="rating">
|
||||||
|
<div class="rating-options">
|
||||||
|
<label v-for="n in range" :key="n" class="rating-option">
|
||||||
|
<input type="radio" :value="n" v-model="selectedValue" class="rating-option--btn" />
|
||||||
|
<span>{{ n }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import '@/styles/form/view.scss'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const selectedValue = ref(props.modelValue)
|
||||||
|
|
||||||
|
const range = computed(() => {
|
||||||
|
return Array.from({ length: props.max - props.min + 1 }, (_, i) => props.min + i)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.rating {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
//align-items: center;
|
||||||
|
|
||||||
|
&-options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
gap: 0 50px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (max-width: 810px) {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-option {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px 0;
|
||||||
|
|
||||||
|
//&--btn {
|
||||||
|
// width: 20px;
|
||||||
|
// height: 20px;
|
||||||
|
// cursor: pointer;
|
||||||
|
//}
|
||||||
|
|
||||||
|
&--btn:after {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 15px;
|
||||||
|
top: -6px;
|
||||||
|
left: -6px;
|
||||||
|
position: relative;
|
||||||
|
background: var(--color-input-background);
|
||||||
|
border: 2px solid var(--color-main-border);
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
visibility: visible;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--btn:after:hover {
|
||||||
|
border: 2px solid var(--color-secondary-border);
|
||||||
|
background: var(--color-main-background);
|
||||||
|
}
|
||||||
|
&--btn:checked:after {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 15px;
|
||||||
|
top: -6px;
|
||||||
|
left: -6px;
|
||||||
|
position: relative;
|
||||||
|
border: 2px solid var(--color-main);
|
||||||
|
background: var(--color-main-toned);
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 810px) {
|
||||||
|
flex-direction: initial;
|
||||||
|
gap: 0 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-delete {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 1rem;
|
||||||
|
padding: 10px 30px;
|
||||||
|
margin-top: 25px;
|
||||||
|
border: 1px solid var(--color-third-border);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid var(--color-main);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
112
src/components/answers/SelectorValue.vue
Normal file
112
src/components/answers/SelectorValue.vue
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<template>
|
||||||
|
<div class="default-card" v-if="modelValue.length > 0">
|
||||||
|
<div class="view-form-q-title">
|
||||||
|
<h3 class="form-q-title">{{ label }}</h3>
|
||||||
|
<p class="form-q-description">{{ description }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="selector">
|
||||||
|
<div class="selector-options">
|
||||||
|
<div
|
||||||
|
v-for="(option, index) in options"
|
||||||
|
:key="index"
|
||||||
|
class="selector-option default-button"
|
||||||
|
:class="{ selected: isSelected(index) }"
|
||||||
|
>
|
||||||
|
<span>{{ option.label }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import '@/styles/form/view.scss'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function isSelected(index) {
|
||||||
|
return props.modelValue.includes(index)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.selector {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&-labels {
|
||||||
|
&-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0 11px;
|
||||||
|
color: var(--color-description);
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
&--sign {
|
||||||
|
min-width: 23px;
|
||||||
|
min-height: 23px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-options {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-option {
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background: var(--color-input-background);
|
||||||
|
border: 1px solid var(--color-main-border);
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid var(--color-secondary-border);
|
||||||
|
background: var(--color-main-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
border: 1px solid var(--color-main);
|
||||||
|
background: var(--color-main-toned);
|
||||||
|
//color: var(--color-alternative-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-error {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: var(--color-red);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0 13px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
|
||||||
|
&--sign {
|
||||||
|
min-width: 23px;
|
||||||
|
min-height: 23px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,24 +1,73 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="text-question-component">
|
<div class="default-card" v-if="modelValue.length > 0">
|
||||||
<input type="text" :value="modelValue" readonly />
|
<div class="view-form-q-title">
|
||||||
|
<h3 class="form-q-title">{{ label }}</h3>
|
||||||
|
<p class="form-q-description">{{ description }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-question">
|
||||||
|
<input class="text-question-input" type="text" :value="modelValue" readonly />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import '@/styles/form/view.scss'
|
||||||
|
|
||||||
const props = defineProps(['modelValue'])
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.text-question-component {
|
.text-question {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
&-error {
|
||||||
color: red;
|
margin-top: 20px;
|
||||||
margin-top: 5px;
|
color: var(--color-red);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0 13px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
|
||||||
|
&--sign {
|
||||||
|
min-width: 23px;
|
||||||
|
min-height: 23px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
width: 100% !important;
|
||||||
|
background: var(--color-main-background);
|
||||||
|
border: 1px solid var(--color-main-border);
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-weight: 200;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
outline: 0;
|
||||||
|
transition:
|
||||||
|
border,
|
||||||
|
background 0.25s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid var(--color-secondary-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border: 1px solid var(--color-third-border);
|
||||||
|
background: var(--color-input-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { PhCardsThree, PhCaretCircleUpDown } from '@phosphor-icons/vue'
|
import { PhCardsThree, PhCaretCircleUpDown } from '@phosphor-icons/vue'
|
||||||
|
|
||||||
import '@/styles/form/view.scss';
|
import '@/styles/form/view.scss'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
label: {
|
label: {
|
||||||
|
|
|
@ -10,7 +10,14 @@
|
||||||
<div class="selector-labels-info">
|
<div class="selector-labels-info">
|
||||||
<PhCaretCircleUpDown :size="23" class="selector-labels-info--sign" />
|
<PhCaretCircleUpDown :size="23" class="selector-labels-info--sign" />
|
||||||
<div class="selector-labels-info--text">
|
<div class="selector-labels-info--text">
|
||||||
Выберите от {{ minValues }} до {{ Math.min(maxValues, options.length) }} {{ normalizeCountForm(Math.min(maxValues, options.length), ['варианта', 'вариантов', 'вариантов']) }}
|
Выберите от {{ minValues }} до {{ Math.min(maxValues, options.length) }}
|
||||||
|
{{
|
||||||
|
normalizeCountForm(Math.min(maxValues, options.length), [
|
||||||
|
'варианта',
|
||||||
|
'вариантов',
|
||||||
|
'вариантов'
|
||||||
|
])
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,7 +44,7 @@ import { ref, watch } from 'vue'
|
||||||
import { PhCaretCircleUpDown, PhXCircle } from '@phosphor-icons/vue'
|
import { PhCaretCircleUpDown, PhXCircle } from '@phosphor-icons/vue'
|
||||||
import { normalizeCountForm } from '@/utils/formation'
|
import { normalizeCountForm } from '@/utils/formation'
|
||||||
|
|
||||||
import '@/styles/form/view.scss';
|
import '@/styles/form/view.scss'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
label: {
|
label: {
|
||||||
|
@ -99,12 +106,12 @@ function validateSelection() {
|
||||||
error.value = ''
|
error.value = ''
|
||||||
|
|
||||||
if (selectedIndexes.value.length < props.minValues) {
|
if (selectedIndexes.value.length < props.minValues) {
|
||||||
error.value = `Необходимо выбрать минимум ${props.minValues} ${normalizeCountForm(props.minValues, ['вариант', 'варианта', 'вариантов']) }.`
|
error.value = `Необходимо выбрать минимум ${props.minValues} ${normalizeCountForm(props.minValues, ['вариант', 'варианта', 'вариантов'])}.`
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.maxValues && selectedIndexes.value.length > props.maxValues) {
|
if (props.maxValues && selectedIndexes.value.length > props.maxValues) {
|
||||||
error.value = `Необходимо выбрать не больше ${props.maxValues} ${normalizeCountForm(props.maxValues, ['варианта', 'вариантов', 'вариантов']) }.`
|
error.value = `Необходимо выбрать не больше ${props.maxValues} ${normalizeCountForm(props.maxValues, ['варианта', 'вариантов', 'вариантов'])}.`
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import { PhXCircle } from '@phosphor-icons/vue'
|
||||||
import { validateSNILS, validateTIN } from '@/utils/validators'
|
import { validateSNILS, validateTIN } from '@/utils/validators'
|
||||||
import { normalizeCountForm } from '@/utils/formation'
|
import { normalizeCountForm } from '@/utils/formation'
|
||||||
|
|
||||||
import '@/styles/form/view.scss';
|
import '@/styles/form/view.scss'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
label: {
|
label: {
|
||||||
|
@ -75,7 +75,7 @@ function validateInput() {
|
||||||
|
|
||||||
if (props.isRequired || inputValue.value) {
|
if (props.isRequired || inputValue.value) {
|
||||||
if (props.minLength && inputValue.value.length < props.minLength) {
|
if (props.minLength && inputValue.value.length < props.minLength) {
|
||||||
error.value = `Минимальная длина - ${props.minLength} ${normalizeCountForm(props.minValues, ['символ', 'символа', 'символов']) }`
|
error.value = `Минимальная длина - ${props.minLength} ${normalizeCountForm(props.minValues, ['символ', 'символа', 'символов'])}`
|
||||||
}
|
}
|
||||||
if (props.validator === 1 && !validateTIN(inputValue.value)) {
|
if (props.validator === 1 && !validateTIN(inputValue.value)) {
|
||||||
error.value = 'Некорректный ИНН'
|
error.value = 'Некорректный ИНН'
|
||||||
|
@ -116,7 +116,9 @@ function validateInput() {
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
transition: border, background 0.25s ease;
|
transition:
|
||||||
|
border,
|
||||||
|
background 0.25s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid var(--color-secondary-border);
|
border: 1px solid var(--color-secondary-border);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
export function normalizeCountForm (number: number, words_arr: Array<string>) {
|
export function normalizeCountForm(number: number, words_arr: Array<string>) {
|
||||||
let options = [2, 0, 1, 1, 1, 2];
|
let options = [2, 0, 1, 1, 1, 2]
|
||||||
return words_arr[(number % 100 > 4 && number % 100 < 20) ? 2 : options[(number % 10 < 5) ? number % 10 : 5]];
|
return words_arr[
|
||||||
|
number % 100 > 4 && number % 100 < 20 ? 2 : options[number % 10 < 5 ? number % 10 : 5]
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -4,10 +4,13 @@ import { makeAPIRequest } from '@/utils/http'
|
||||||
import FormNotFound from '@/components/FormNotFound.vue'
|
import FormNotFound from '@/components/FormNotFound.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import TextValue from '@/components/answers/TextValue.vue'
|
import TextValue from '@/components/answers/TextValue.vue'
|
||||||
|
import SelectorValue from '@/components/answers/SelectorValue.vue'
|
||||||
|
import ScaleValue from '@/components/answers/ScaleValue.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const data = ref([])
|
const data = ref([])
|
||||||
|
const questionsData = ref({})
|
||||||
const currentPageNumber = ref(0)
|
const currentPageNumber = ref(0)
|
||||||
const isAnswerNotFound = ref(true)
|
const isAnswerNotFound = ref(true)
|
||||||
const mode = ref(0)
|
const mode = ref(0)
|
||||||
|
@ -27,6 +30,19 @@ onMounted(async () => {
|
||||||
if (data.value.length > 0) {
|
if (data.value.length > 0) {
|
||||||
isAnswerNotFound.value = false
|
isAnswerNotFound.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const questionsFormResponse = await makeAPIRequest('/form/get', 'GET', {
|
||||||
|
id: Number(route.params.id)
|
||||||
|
})
|
||||||
|
if (!questionsFormResponse.json || questionsFormResponse.status !== 200) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
questionsFormResponse.json.data.pages.forEach((p: any) => {
|
||||||
|
p.questions.forEach((q: any) => {
|
||||||
|
questionsData.value[q.id] = q
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -41,7 +57,27 @@ onMounted(async () => {
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="" v-for="(value, index) in data[currentPageNumber].data.values">
|
<div class="" v-for="(value, index) in data[currentPageNumber].data.values">
|
||||||
<TextValue v-if="value.question_type === 1" v-model="value.value" />
|
<TextValue
|
||||||
|
v-if="questionsData[value.question_id].question_type === 1"
|
||||||
|
:label="questionsData[value.question_id].label"
|
||||||
|
:description="questionsData[value.question_id].description"
|
||||||
|
v-model="value.value"
|
||||||
|
/>
|
||||||
|
<SelectorValue
|
||||||
|
v-if="questionsData[value.question_id].question_type === 2"
|
||||||
|
:options="questionsData[value.question_id].options"
|
||||||
|
:label="questionsData[value.question_id].label"
|
||||||
|
:description="questionsData[value.question_id].description"
|
||||||
|
v-model="value.values"
|
||||||
|
></SelectorValue>
|
||||||
|
<ScaleValue
|
||||||
|
v-if="questionsData[value.question_id].question_type === 3"
|
||||||
|
:min="questionsData[value.question_id].min_value"
|
||||||
|
:max="questionsData[value.question_id].max_value"
|
||||||
|
:label="questionsData[value.question_id].label"
|
||||||
|
:description="questionsData[value.question_id].description"
|
||||||
|
v-model="value.value"
|
||||||
|
></ScaleValue>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { useRoute } from 'vue-router'
|
||||||
import { PhInfo, PhCardsThree } from '@phosphor-icons/vue'
|
import { PhInfo, PhCardsThree } from '@phosphor-icons/vue'
|
||||||
import { validateSNILS, validateTIN } from '@/utils/validators'
|
import { validateSNILS, validateTIN } from '@/utils/validators'
|
||||||
|
|
||||||
import '@/styles/form/view.scss';
|
import '@/styles/form/view.scss'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
|
@ -36,14 +36,18 @@ function beforeSubmitValidate() {
|
||||||
for (let question of currentPage.value.questions) {
|
for (let question of currentPage.value.questions) {
|
||||||
const answer = answers.value[question.id]
|
const answer = answers.value[question.id]
|
||||||
|
|
||||||
if (!answer) return false;
|
if (!answer) return false
|
||||||
if (question.required && !answer.value && !answer.values) return false;
|
if (question.required && !answer.value && !answer.values) return false
|
||||||
|
|
||||||
if (question.question_type === 1 && answer.value) {
|
if (question.question_type === 1 && answer.value) {
|
||||||
if (!question.validator && question.min_length && answer.value.length < question.min_length) return false;
|
if (!question.validator && question.min_length && answer.value.length < question.min_length)
|
||||||
if (question.validator === 1 && !validateTIN(answer.value)) return false;
|
return false
|
||||||
if (question.validator === 2 && !validateSNILS(answer.value)) return false;
|
if (question.validator === 1 && !validateTIN(answer.value)) return false
|
||||||
} else if (question.question_type === 2 && !(question.required && answer.values.length >= question.min_values)) {
|
if (question.validator === 2 && !validateSNILS(answer.value)) return false
|
||||||
|
} else if (
|
||||||
|
question.question_type === 2 &&
|
||||||
|
!(question.required && answer.values.length >= question.min_values)
|
||||||
|
) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,9 +62,9 @@ async function submitForm() {
|
||||||
} else {
|
} else {
|
||||||
for (let page of data.value.pages) {
|
for (let page of data.value.pages) {
|
||||||
page.questions.forEach((q) => {
|
page.questions.forEach((q) => {
|
||||||
let answer = answers.value[q.id];
|
let answer = answers.value[q.id]
|
||||||
if (!q.required && !(answer.value || answer.values)) {
|
if (!q.required && !(answer.value || answer.values)) {
|
||||||
delete answers.value[q.id];
|
delete answers.value[q.id]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -99,7 +103,9 @@ onMounted(async () => {
|
||||||
<div class="view-form-title view-form-container default-card">
|
<div class="view-form-title view-form-container default-card">
|
||||||
<div class="view-form-info">
|
<div class="view-form-info">
|
||||||
<PhCardsThree :size="23" class="view-form-info--sign" />
|
<PhCardsThree :size="23" class="view-form-info--sign" />
|
||||||
<div class="view-form-info--text">Страница {{ currentPageNumber + 1 }} из {{ data.pages.length }}</div>
|
<div class="view-form-info--text">
|
||||||
|
Страница {{ currentPageNumber + 1 }} из {{ data.pages.length }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="form-title">{{ data.name }}</h2>
|
<h2 class="form-title">{{ data.name }}</h2>
|
||||||
<p class="form-description">{{ currentPage.text }}</p>
|
<p class="form-description">{{ currentPage.text }}</p>
|
||||||
|
|
Loading…
Reference in a new issue