@@ -80,7 +68,7 @@ const cancel = () => {
type="button"
flat
class="text-primary"
- @click="cancel()"
+ v-close-popup
>
{{ t('globals.cancel') }}
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index b0aa648c1..662efcfe9 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -2,9 +2,11 @@
import { ref, toRefs, computed, watch, onMounted, useAttrs } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'src/components/FetchData.vue';
-import { useValidator } from 'src/composables/useValidator';
+import { useRequired } from 'src/composables/useRequired';
const emit = defineEmits(['update:modelValue', 'update:options', 'remove']);
-
+const $attrs = useAttrs();
+const { t } = useI18n();
+const { isRequired, requiredFieldRule } = useRequired($attrs);
const $props = defineProps({
modelValue: {
type: [String, Number, Object],
@@ -87,10 +89,7 @@ const $props = defineProps({
default: false,
},
});
-const { validations } = useValidator();
-const requiredFieldRule = (val) => validations().required($attrs.required, val);
-const $attrs = useAttrs();
-const { t } = useI18n();
+
const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])];
const { optionLabel, optionValue, optionFilter, optionFilterValue, options, modelValue } =
toRefs($props);
@@ -257,7 +256,7 @@ defineExpose({ opts: myOptions });
:fill-input="nullishToTrue($attrs['fill-input'])"
ref="vnSelectRef"
lazy-rules
- :class="{ required: $attrs.required }"
+ :class="{ required: isRequired }"
:rules="mixinRules"
virtual-scroll-slice-size="options.length"
hide-bottom-space
diff --git a/src/components/common/VnTitle.vue b/src/components/common/VnTitle.vue
index 1fbd43972..89dd8cd0c 100644
--- a/src/components/common/VnTitle.vue
+++ b/src/components/common/VnTitle.vue
@@ -8,7 +8,7 @@ defineProps({