How to clear v-model used with a select when options change - javascript

I have a cascading select (two part select) where the options in the second dropdown are determined by the value of the first dropdown. I do this by having a computed property which is based off of the first select. This then feeds the options into the second select. This mostly works fine.
The problem I'm having is if I have selected an option in the second select (which through v-model sets the value of the bound variable in Vue), and then I change the value of the first select. The options for the second select then update, and in that second select I appear to be selected to the empty option. However, the bound variable still has the previously selected value. I'm assuming this is because updating the option values for the second select doesn't actually trigger an input or change event so v-model doesn't respond to anything. I suppose I could fix this with a watcher, but I was hoping for a more elegant solution.
Coded example is here: https://codepen.io/Slotheroo/pen/ajwNKO/
JS/Vue:
new Vue({
el: '#app',
data: {
selectedFruit: null,
selectedVariety: null,
fruits: {
"apples": [
{
name: "honeycrisp",
madeBy: "applebees",
},
{
name: "macintosh",
madeBy: "the steves",
},
{
name: "gala",
madeBy: "ac/dc",
},
{
name: "pink lady",
madeBy: "Alecia Beth Moore",
},
],
"pears": [
{
name: "d'anjou",
madeBy: "Maya D'Anjoulou",
},
{
name: "bartlett",
madeBy: "Anton Yelchin",
}
],
},
},
computed: {
fruitVarieties: function() {
return this.fruits[this.selectedFruit]
}
},
});
HTML:
<div id="app">
<div>
<select v-model="selectedFruit">
<option value=""></option>
<option v-for="fruitName in Object.keys(fruits)" :value ="fruitName">{{fruitName}}</option>
</select>
</div>
<select v-model="selectedVariety">
<option value=""></option>
<option v-for="fruitVariety in fruitVarieties" :value="fruitVariety">{{ fruitVariety.name }}</option>
</select>
<div>
</div>
<p>Selected variety: {{ selectedVariety }}</p>
</div>
Steps to reproduce:
Select 'apples' in the first select
Select 'honeycrisp' in the second select
Select 'pears' or 'blank' in the first select
Hoped for result
selectedVariety returns to null
Actual result
selectedVariety still equals honeycrisp

I'd add an on-change handler to the first <select> to empty the selectedVariety when the selection changes...
<select v-model="selectedFruit" #change="selectedVariety = null">
https://codepen.io/anon/pen/JByEwy
Another option would be to add a watch on selectedFruit but Vue generally recommends using event handlers.

if you're using version 3.0.0, there is some feature with :reset-on-options-change='true'
e.g
<v-select required :options="filterKaryawan.unit.options" :reset-on-options-change='true' v-model="filterKaryawan.unit.selected" placeholder="placeholder" >
<template #search="{attributes, events}">
<input
class="vs__search"
v-bind="attributes"
v-on="events"
:required="filterKaryawan.unit.selected"
/>
</template>
</v-select>

The computed propertive is actually a watcher. So just put the reset value code in it.
computed: {
fruitVarieties: function() {
this.selectedVariety = null;
return this.fruits[this.selectedFruit]
}
}

Related

how to get value out of v-for loop in <select> and <option>

I am looking for a way to get a value out of a v-for loop. Can anyone help me with this?
I have the following code:
Select Country:
<select #change="selectCountryStats(country.code)">
<option
v-for="country in everyCountry"
:key="country.name"
value="country.name"
>
{{ country.name }}
</option>
</select>
and in #change I would like to get the value of country.code, but this value is first known, when the v-for loop is triggered, which is not the case.
Any solution for this problem will be appreaciated.
You can't use the v-for's iterator outside of the v-for loop because it's out of scope.
For the change-event handler to receive the country code, you'd have to change the <option>.value bindings from country.name to country.code:
<option :value="country.code">
For inline event handlers, the event parameter is stored in a special $event variable. And since the change event's target is the <select>, you could access the new value (the country code of the selection) in the change-event handler via $event.target.value:
<select #change="selectCountryStats($event.target.value)">
new Vue({
el: '#app',
data: () => ({
everyCountry: [
{
name: 'United States',
code: 'US'
},
{
name: 'Canada',
code: 'CA'
},
]
}),
methods: {
selectCountryStats(e) {
console.log(e)
}
}
})
<script src="https://unpkg.com/vue#2.6.12/dist/vue.min.js"></script>
<div id="app">
<select #change="selectCountryStats($event.target.value)">
<option
v-for="country in everyCountry"
:key="country.name"
:value="country.code"
>
{{ country.name }}
</option>
</select>
</div>

How to add button and input element into drop down list

I've created a simple select menu (dropdown) using bootstrap Vue. My question is how do I insert a button and an input element inside the dropdown list. Below is an example of what I want to achieve, and my current code.
Update I am still trying to solve this issue, any help is greatly appreciated
Picture1: Button inserted at the bottom of the dropdown list
Picture2: When user clicks on the button, there will be an input field for them to enter a value. The value will automatically be inserted to the dropdown list
Current Code
<template>
<b-container class="empty-container">
<b-row align-h="center">
<b-col cols="6">
<b-form-select v-model="selected" :options="options"></b-form-select>
</b-col>
</b-row>
</b-container>
</template>
<script>
export default {
data() {
return {
selected: null,
options: [
{ value: null, text: "Please select an option" },
{ value: "a", text: "This is First option" },
{ value: "b", text: "Selected Option" },
{ value: { C: "3PO" }, text: "This is an option with object value" }
]
};
}
};
</script>
<style>
</style>
I don't know if you'll be able to use the browser's standard dropdown menu. The reason I'm thinking is that you won't be able to reliably select the html of browser specific dropdowns. So I would build my own dropdown and if the last option was clicked convert it to an <input type='text' > and grab the value from that.

Get value from each select

Blocks are created through a loop, there is a select in each block. Tell me how when clicking on a button, take the selected values from all created selects?
I tried join ref to select, and v-model, but not one of them is working properly
<div v-for="attribute in attributes" class="col">
{{ attribute.name }}
<select ref="selectedVariation" class="form-control">
<option selected>---</option>
<option v-for="variation in attribute.variations"
:key="variation.id"
:value="variation.id">
{{ variation.name }}
</option>
</select>
</div>
<button class="btn btn-success" #click="addItemToCart()">Test</button>
Hi Данил and welcome to stack overflow. There's not enough detail in the question to provide an exact solution, but the following hints might get you started. Also, there are several different approaches that could work; this is just one possibility.
First, include a property in the attributes objects that can be used to track the selected value, perhaps calling it .selected.
data: {
attributes: [
{name: "Name 1", selected: null, variations: [/*...*/]},
{name: "Name 2", selected: null, variations: [/*...*/]},
// ...
]
}
Second, tell Vue about that property using the v-model directive:
<select
class="form-control"
v-model="attribute.selected"
>
Then, when the button is clicked, the code can simply read the appropriate values:
methods: {
addItemToCart() {
// get an array of variation.id values
selectedArray = this.attributes.map(attribute => attribute.selected);
}
}

Broken Aurelia binding when object is null

Example based on Aurelia doc.
Page code:
export class MyPage {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProduct = null;
}
Page HTML:
<label>
Select product:<br/>
<select value.bind="selectedProduct">
<option model.bind="null">Choose...</option>
<option repeat.for="product of products"
model.bind="product">
${product.id} - ${product.name}
</option>
</select>
</label>
<div if.bind="selectedProduct">
Selected product 1: ${selectedProduct.id} - ${selectedProduct.name}
<div if.bind="selectedProduct.id > 0">
Selected product 2: ${selectedProduct.id} - ${selectedProduct.name}
</div>
</div>
When selecting CPU, then selecting null value, then selecting Memory, Selected product 1 is updated correctly with a value from a select element, but Selected product 2 is stuck with a CPU value.
How to bind selected value correctly inside the inner div?
In my application, I want to be able to display a content of selected item. Depending on an item type, I have a several <div if.bind="item.type === N">...</div> elements in order to display different HTML for each type of an item.
Note: binding doesn't work with newest packages, but works fine when I assign specific versions to the following packages in my package.json:
"aurelia-templating": "1.4.2"
"aurelia-templating-binding": "1.3.0"
"aurelia-templating-resources": "1.4.0"
"aurelia-templating-router": "1.1.0"

vue js how to set option value selected

I'm using vue js for my application in select option input..I need to set default value should be selected in the drop down and while on change i would like to call two functions ..
I'm new to vue js..
My Code :
var listingVue = new Vue({
el: '#mountain',
data:{
formVariables: {
country_id: '',
mountain_id: '',
peak_id: ''
},
countrylist:[],
mountainlist:[],
},
ready: function() {
var datas = this.formVariables;
this.getCountry();
},
methods: {
getCountry: function()
{
this.$http.get(baseurl+'/api/v1/device/getCountry',function(response)
{
this.$set('countrylist',response.result);
//alert(jQuery('#country_id').val());
});
},
getMountain: function(country_id)
{
var datas = this.formVariables;
datas.$set('country_id', jQuery('#country_id').val() );
postparemeters = {country_id:datas.country_id};
this.$http.post(baseurl+'/api/v1/site/getMountain',postparemeters,function(response)
{
if(response.result)
this.$set('mountainlist',response.result);
else
this.$set('mountainlist','');
});
},
});
<select
class="breadcrumb_mountain_property"
id="country_id"
v-model="formVariables.country_id"
v-on="change:getMountain(formVariables.country_id);">
<option
v-repeat = "country: countrylist"
value="#{{country.id}}" >
#{{country.name}}
</option>
</select>
With vue 2, the provided answer won't work that well. I had the same problem and the vue documentation isn't that clear concerning <select>. The only way I found for <select> tags to work properly, was this (when talking of the question):
<select v-model="formVariables.country_id">
<option v-for = "country in countrylist" :value="country.id" >{{country.name}}</option>
</select>
I assume, that the #-sign in #{{...}} was due to blade, it should not be necessary when not using blade.
In VueJS 2 you can bind selected to the default value you want. For example:
<select
class="breadcrumb_mountain_property"
id="country_id"
v-model="formVariables.country_id"
v-on:change="getMountain(formVariables.country_id);">
<option
v-for = "country in countrylist"
:selected="country.id == 1"
:value="country.id" >
{{country.name}}
</option>
</select>
So, during the iteration of the countryList, the country with the id 1 will be selected because country.id == 1 will be true which means selected="true".
UPDATED:
As Mikee suggested, instead of v-on="change:getMountain(formVariables.country_id);" there is a new way to for binding events. There is also a short form #change="getMountain(formVariables.country_id);"
You should use the 'options' attribute in place of trying to v-repeat <option></option>:
VM
data: {
countryList: [
{ text:'United States',value:'US' },
{ text:'Canada',value:'CA' }
]
},
watch: {
'formVariables.country_id': function() {
// do any number of things on 'change'
}
}
HTML
<select
class="breadcrumb_mountain_property"
id="country_id"
v-model="formVariables.country_id"
options="countryList">
</select>
You can use select in this way. Remember to use array in v-for.
<select v-model="album.primary_artist">
<option v-for="i in artistList" :key="i.id" :value="i.name">
{{ i.name }}
</option>
</select>
You can use this way.
<select v-model="userData.categoryId" class="input mb-3">
<option disabled value="null">Kategori</option>
<option
v-for="category in categoryList"
:key="category.id"
:value="category.id"
>
{{ category.name }}
</option>
</select>
export default {
data() {
return {
categoryList: [],
userData: {
title: null,
categoryId: null,
},
};
},
The important thing here is what the categoryId value is, the default option value should be that.
categoryId: null,
<option disabled value="null">Kategori</option>
Here we use categoryId as value in v-model and initialize it with null. Value must be null in default option.
<select v-model="userData.categoryId" class="input mb-3">

Categories