fix: validation on blur

This commit is contained in:
axolotle 2024-03-18 15:40:21 +01:00
parent 622e5be061
commit 6229e40ca8
8 changed files with 65 additions and 23 deletions

View file

@ -7,7 +7,6 @@
:state="state" :state="state"
:aria-describedby="id + 'local-part-desc'" :aria-describedby="id + 'local-part-desc'"
@update:modelValue="onInput('localPart', $event)" @update:modelValue="onInput('localPart', $event)"
@blur="$parent.$emit('touch')"
/> />
<BInputGroupAppend> <BInputGroupAppend>
@ -20,7 +19,6 @@
:choices="choices" :choices="choices"
:aria-describedby="id + 'domain-desc'" :aria-describedby="id + 'domain-desc'"
@update:modelValue="onInput('domain', $event)" @update:modelValue="onInput('domain', $event)"
@blur="$parent.$emit('touch')"
/> />
</BInputGroupAppend> </BInputGroupAppend>

View file

@ -55,7 +55,7 @@ export default {
setup(props) { setup(props) {
const externalResults = toRef(props, 'externalResults') const externalResults = toRef(props, 'externalResults')
return { return {
v$: useVuelidate({ $externalResults: externalResults, $autoDirty: true }), v$: useVuelidate({ $externalResults: externalResults }),
} }
}, },

View file

@ -48,6 +48,8 @@
</template> </template>
<script> <script>
import { provide } from 'vue'
export default { export default {
name: 'FormField', name: 'FormField',
@ -67,6 +69,22 @@ export default {
validationIndex: { type: Number, default: null }, validationIndex: { type: Number, default: null },
}, },
setup(props) {
function touch(name) {
if (props.validation) {
// For fields that have multiple elements
if (name) {
props.validation[name].$touch()
} else {
props.validation.$touch()
}
}
}
provide('touch', touch)
return { touch }
},
computed: { computed: {
_id() { _id() {
if (this.id) return this.id if (this.id) return this.id
@ -127,19 +145,6 @@ export default {
return '' return ''
}, },
}, },
methods: {
touch(name) {
if (this.validation) {
// For fields that have multiple elements
if (name) {
this.validation[name].$touch()
} else {
this.validation.$touch()
}
}
},
},
} }
</script> </script>

View file

@ -20,13 +20,14 @@
:state="state" :state="state"
:browse-text="$t('words.browse')" :browse-text="$t('words.browse')"
@update:modelValue="onInput" @update:modelValue="onInput"
@blur="$parent.$emit('touch', name)" @blur="touch(name)"
@focusout="$parent.$emit('touch', name)" @focusout="touch(name)"
/> />
</BButtonGroup> </BButtonGroup>
</template> </template>
<script> <script>
import { inject } from 'vue'
import { getFileContent } from '@/helpers/commons' import { getFileContent } from '@/helpers/commons'
export default { export default {
@ -43,6 +44,12 @@ export default {
name: { type: String, default: null }, name: { type: String, default: null },
}, },
setup() {
return {
touch: inject('touch'),
}
},
computed: { computed: {
_placeholder: function () { _placeholder: function () {
return this.modelValue.file === null return this.modelValue.file === null

View file

@ -12,11 +12,13 @@
:step="step" :step="step"
:trim="trim" :trim="trim"
:autocomplete="autocomplete_" :autocomplete="autocomplete_"
@blur="$parent.$emit('touch', name)" @blur="touch(name)"
/> />
</template> </template>
<script> <script>
import { inject } from 'vue'
export default { export default {
name: 'InputItem', name: 'InputItem',
@ -36,6 +38,12 @@ export default {
name: { type: String, default: null }, name: { type: String, default: null },
}, },
setup() {
return {
touch: inject('touch'),
}
},
data() { data() {
return { return {
autocomplete_: this.autocomplete autocomplete_: this.autocomplete

View file

@ -5,20 +5,28 @@
:id="id" :id="id"
:options="choices" :options="choices"
:required="required" :required="required"
@blur="$emit('blur', modelValue)" @blur="touch(name)"
/> />
</template> </template>
<script> <script>
import { inject } from 'vue'
export default { export default {
name: 'SelectItem', name: 'SelectItem',
props: { props: {
modelValue: { type: [String, null], default: null }, modelValue: { type: [String, null], default: null },
id: { type: String, default: null }, id: { type: String, default: null },
choices: { type: [Array, Object], required: true }, choices: { type: Array, required: true },
required: { type: Boolean, default: false }, required: { type: Boolean, default: false },
name: { type: String, default: null }, name: { type: String, default: null },
}, },
setup() {
return {
touch: inject('touch'),
}
},
} }
</script> </script>

View file

@ -10,11 +10,13 @@
remove-on-delete remove-on-delete
:state="state" :state="state"
:options="options" :options="options"
@blur="$parent.$emit('touch', name)" @blur="touch(name)"
/> />
</template> </template>
<script> <script>
import { inject } from 'vue'
export default { export default {
name: 'TagsItem', name: 'TagsItem',
@ -28,5 +30,11 @@ export default {
name: { type: String, default: null }, name: { type: String, default: null },
options: { type: Array, default: null }, options: { type: Array, default: null },
}, },
setup() {
return {
touch: inject('touch'),
}
},
} }
</script> </script>

View file

@ -7,11 +7,13 @@
:required="required" :required="required"
:state="state" :state="state"
rows="4" rows="4"
@blur="$parent.$emit('touch', name)" @blur="touch(name)"
/> />
</template> </template>
<script> <script>
import { inject } from 'vue'
export default { export default {
name: 'TextAreaItem', name: 'TextAreaItem',
@ -24,5 +26,11 @@ export default {
state: { type: Boolean, default: null }, state: { type: Boolean, default: null },
name: { type: String, default: null }, name: { type: String, default: null },
}, },
setup() {
return {
touch: inject('touch'),
}
},
} }
</script> </script>