I have a dropdown that I want to give a validation.
So here is my dropdown component:
<template>
<div class="custom-select" :tabindex="tabindex" @blur="open = false">
<div class="selected" :class="{ open: open }" @click="open = !open">
{{ selected.name }}
</div>
<div class="items" :class="{ selectHide: !open }">
<div v-if="defaultValue != ''">{{defaultValue}}</div>
<div v-for="(option, i) of options" :key="i" @click=" selected = option; open = false; $emit('input', option);">
{{ option.name }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true,
},
defaultValue: {
type: String,
required: false,
default: "Choose an option",
},
tabindex: {
type: Number,
required: false,
default: 0,
},
},
data() {
return {
open: false,
selected: this.setDefaultValue(),
};
},
mounted() {
this.$emit("input", this.selected);
},
methods: {
setDefaultValue () {
if (this.defaultValue == '' && this.options.length > 0) {
return this.options[0];
}
return { name: this.defaultValue};
}
}
};
</script>
and in my parent component, I am using this dropdown, the fetched value from API call and filled with variations. So what I am trying to do is if the value is not selected (default: "Choose an option"), I want to give an error message which is saying, the dropdown is mandatory.
<Dropdown
:options="getVariations"
class="select"
@input="getSelected"
/>
<script>
import Dropdown from "../components/Dropdown";
import apiHelper from "../helpers/apiHelper";
export default {
components: {Dropdown},
data() {
return {
selected: "",
variationId: "",
selectedObject: null
};
},
computed: {
getVariations() {
return this.product.attributes.variations
}
},
methods: {
getSelected(opt) {
this.selectedObject = opt;
this.selected = opt.description;
this.variationId = opt.id;
}
},
};
</script>
CodePudding user response:
This is a simple example of what you are asking for:
// v-model property
selectedVModel: null
// html
<select id="testselect" v-model="selectedVModel" required>
<option :value="null">Default</option>
<option value="bar">Option 1</option>
<option value="foo">Option 2</option>
<option value="baz">Option 3</option>
</select>
<div v-if="!selectedVModel">Error! Choose something!</div>
You can handle the error inside of your child component. In this example, if the v-model
as selectedVModel
is empty, the <div>
with v-if="!selectedVModel"
will be shown. As selectedVModel
is null
it will automatically select <option :value="null">Default</option>
. If you chosse one of the options selectedVModel
get´s a value so v-if="!selectedVModel"
results into false
, no error then. If you select Default
again, the value turns to null
again which results into true
at v-if="!selectedVModel"
, so the error will be visible again.
Combine this simple example with your code and let me know if it helped you.
CodePudding user response:
If you want to validate in your parent component, try to check selectedObject.id
:
Vue.component('Dropdown', {
template: `
<div class="custom-select" :tabindex="tabindex" @blur="open = false">
<div class="selected" :class="{ open: open }" @click="open = !open">
{{ selected.name }}
</div>
<div class="items" :class="{ selectHide: !open }">
<div v-if="defaultValue != ''">{{defaultValue}}</div>
<div v-for="(option, i) of options" :key="i" @click=" selected = option; open = false; $emit('input', option);">
{{ option.name }}
</div>
</div>
</div>
`,
props: {
options: {
type: Array,
required: true,
},
defaultValue: {
type: String,
required: false,
default: "Choose an option",
},
tabindex: {
type: Number,
required: false,
default: 0,
},
},
data() {
return {
open: false,
selected: this.setDefaultValue(),
};
},
mounted() {
this.$emit("input", this.selected);
},
methods: {
setDefaultValue () {
if (this.defaultValue == '' && this.options.length > 0) {
return this.options[0];
}
return { name: this.defaultValue};
}
}
})
new Vue({
el: '#demo',
data() {
return {
selected: "",
variationId: "",
selectedObject: null,
product: {
attributes: {
variations: [{id: 1, name: 'name1', description: 'desc1'}, {id: 2, name: 'name2', description: 'desc2'},{id: 3, name: 'name3', description: 'desc3'},]
}
}
};
},
computed: {
getVariations() {
return this.product.attributes.variations
}
},
methods: {
getSelected(opt) {
this.selectedObject = opt;
this.selected = opt.description;
this.variationId = opt.id;
},
submit() {
if (!this.selectedObject.id) alert('pls select option')
else console.log(this.selectedObject)
}
},
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<button @click="submit">submit</button>
<Dropdown
:options="getVariations"
class="select"
@input="getSelected"
/>
</div>