I have a page with a b-form-select control from Bootstrap Vue. When I change the value of this control I want to execute a function that can possibly cancel this event, and not change the value.
To make things more complicated, my select is in a child component and the function I execute is in the parent.
The child component
public values: any[] = [
{ name: 'default'},
{ name: 'forbidden'},
{ name: 'other option' },
]
<b-form-select :value="property" @change="$emit('onPropertyChange', arguments[0])">
<option v-for="(val, key) in values" :value="val" :key="key">{{val.Name}}</option>
</b-form-select>
The parent component:
this.property = { name: 'default' }
public onPropertyChange(newValue) {
if (newValue.name === 'forbidden') {
// Not changing this.property
} else {
// Changing it
this.property = newValue
}
}
<child :property="property" @onPropertyChange="onPropertyChange"></child>
When I select 'forbidden' in the select. I see that the select box has changed to this value, but the property in the child and also the property in the parent still have the old value, which is what I want. How can I also have the select to have the old value?
Bootstrap Vue does not seem to have a prevent modifier on the change event. I have also tried using the native event but that has the same issue.
Am I doing something wrong?
It would probably be a better user experience to disable forbidden options than to mysteriously have them not select the selected value, but you can get that behavior in your change event handler by saving the old value and restoring it on nextTick
.
Note that your options
structure isn't suited for use with b-form-select
. I have made a computed that makes the right structure and handles setting disabled
, and used that in the b-form-select
.
new Vue({
el: '#app',
data: {
selected: 'default',
options: [{
name: 'default',
},
{
name: 'forbidden'
},
{
name: 'other option'
},
{
name: 'what I had before'
},
]
},
computed: {
selectOptions() {
return this.options.map((opt) => ({
text: opt.name,
value: opt.name,
disabled: opt.name === 'forbidden'
}));
}
},
methods: {
onChange(newValue) {
const oldValue = this.selected;
if (newValue === 'what I had before') {
this.$nextTick(() => {
this.selected = oldValue;
});
}
}
}
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-form-select v-model="selected" :options="selectOptions" @change="onChange">
</b-form-select>
<div>Selected: <strong>{{selected}}</strong></div>
</div>