I am new to Vue.js. I want to know how to show next input field based on previous dropdown menu selection. I have checked other forums and tried to implement but that didn't work.
Here is my code:
<select v-model="receive_method" id="">
<option value="cheque">Cheque</option>
<option value="eftn">EFTN</option>
<option value="cash">CASH</option>
</select>
<div v-if="receive_method === 'Cheque' ">
<input type="integer" v-model="cheque_number" placeholder="Cheque Number">
</div>
If I select cheque option from the dropdown list the next input field will appear else it will remain hidden.
Please help.
You need to reference the value of the options element.
If value="cheque" is lowercase, v-if="receive_method === 'cheque'" should too.
This works:
<script setup>
import { ref } from 'vue'
const receive_method = ref()
const cheque_number = ref()
</script>
<template>
<select v-model="receive_method" id="">
<option value="cheque">Cheque</option>
<option value="eftn">EFTN</option>
<option value="cash">CASH</option>
</select>
<div v-if="receive_method === 'cheque'">
<input type="integer" v-model="cheque_number" placeholder="Cheque Number">
</div>
</template>
If using Options API
<script>
export default {
data() {
return {
receive_method: undefined,
cheque_number: undefined
}
}
}
</script>
Related
I wish to build a from using Vue composition api. And in the form, there would be two drop boxes. When first dropbox item selected, it will return the corresponding option in second dropbox? How could it be achieved in vue?
eg. When selected Avengers in team (first dropbox), it will display ["Captain America", "Iron Man", "Thor", "Hulk", "Black Widow", "Hawkeye"] option in second dropbox.
When selected JLA in team (first dropbox), it will display ["Superman", "Batman", "Wonder Woman", "Flash", "Green Lantern", "Aquaman"] option in second dropbox.
<div class="row mb-3">
<label class="col-sm-2 col-form-label">Favourite Team</label>
<select class="form-select" aria-label="Default select example" onchange="teamSelected(this.value)" name="team">
<option selected>Open this select menu</option>
<option value="Avengers">Avengers</option>
<option value="JLA">Justice League</option>
</select>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">Favourite Hero</label>
<select class="form-select" aria-label="Default select example" id="superhero" disabled name="superhero">
</select>
</div>
<script>
import { ref } from 'vue';
export default {
name: 'App',
setup() {
const teamSelected = (event) => {
course.value = event.target.value;
};
return {
teamSelected,
};
},
};
</script>
Thanks in advance
I am looking for help on how to display the second option in a select drop-down menu after the select menu is disabled.
It is disabled if there are fewer than 2 options left. The first option is the 'Please select' option but I would like it to display the one remaining option which is the second option. i.e. 'Scotland' in the code below. The data is pulled in using an Axios call so I do not know what the value will be.
Any help would be greatly appreciated.
The select menu code
<select disabled="disabled">
<option disabled="disabled" value="">Select nationality</option>
<option value="Scotland"> Scotland </option>
</select>
Vue
computed: {
selectDisabled: function() {
return this.options.length <= 2;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="quantity" :disabled="selectDisabled">
<option disabled value="">Select</option>
<option v-for="option in options" :value="option">{{option}}</option>
</select>
</div>
You need to create a special computed property that will dynamically tell the <select> which option it should show inside itself. <select> show the option that matches the <select>'s value.
So:
When the select is disabled (has less than 2 options) force it's value to be the value of the first listed option (this.options[0]).
When the select is enabled, pass the normal value selected by the user (this.value)
I've implemented the logic you need below (make sure to click "Run snippet"):
const App = {
el: '#app',
template: `
<div>
<!--
Remember that writing v-model="quantity" is the same as writing :value="quantity" #input="quantity = $event"
(or #input="quanity = $event.target.value" if you put in HTML elements)
You can't use v-model="valueFormatted" here because this would be the same as writing
:value="valueFormatted" #input="valueFormatted = $event.target.value"
So that's a mistake, because valueFormatted is a computed and you can't assign to it
(unless you create a special computed with a setter, but that's not what you need right now)
-->
<select :value="valueFormatted" #input="value = $event.target.value" :disabled="disabled">
<option disabled="disabled" value="">Select nationality</option>
<option v-for="option in options" :value="option">{{option}}</option>
</select>
<hr>
<div>
<button #click="options = ['Scotland']">Make the select have 1 item</button>
<button #click="options = ['Scotland', 'Poland']">Make the seelct have 2 items</button>
</div>
</div>
`,
data() {
return {
options: ["Scotland", "Poland"],
value: '',
}
},
computed: {
disabled() {
return this.options.length < 2
},
/*
* If this.disabled is true, returns the value of the first option
* If it's false, it returns the normal value from data (user selected)
*/
valueFormatted() {
//watch out - this computed will return undefined if this.disabled is true and if options is empty
//to avoid that, you can do for example this:
//return this.disabled === true ? (this.options[0] ?? '' ) : this.value;
return this.disabled === true ? this.options[0] : this.value;
},
},
}
new Vue(App);
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<html>
<body>
<div id="app" />
</body>
</html>
You're probably going to use this select's value later to make eg. an API call, so make sure to send this.valueFormatted instead of this.value
Let's go to the point of the question. I have a selection component, it looks like this:
<template>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="category_id">
Product Category
</label>
<select
name="category_id"
id="category_id"
:class="form.errors.has('category_id') ? 'form-control is-invalid' : 'form-control'"
v-model="form.sharedState.category_id">
<option value="" disabled hidden>Select Category</option>
<option
v-for="category in categories"
:key="category.id"
v-text="category.name"
:value="category.id"
#click="$emit('category-selected', category.sub_categories)">
</option>
</select>
<small
class="form-text text-danger"
v-if="form.errors.has('category_id')"
v-text="form.errors.get('category_id')"></small>
</div>
</div>
<div class="col-md-6">
<div
class="form-group"
v-if="revealSubCategory"
#category-selected="show">
<label for="category_id">
Sub Category
</label>
<select
name="sub_category_id"
id="sub_category_id"
:class="form.errors.has('sub_category_id') ? 'form-control is-invalid' : 'form-control'"
v-model="form.sharedState.sub_category_id">
<option value="" disabled hidden>Select Sub Category</option>
<option
v-for="subcategory in subcategories"
:key="subcategory.id"
v-text="subcategory.name"
:value="subcategory.id">
</option>
</select>
<small
class="form-text text-danger"
v-if="form.errors.has('category_id')"
v-text="form.errors.get('category_id')"></small>
</div>
</div>
</div>
</template>
<script>
import BaseCard from './BaseCard.vue';
export default {
components: {
BaseCard
},
data() {
return {
categories: [],
revealSubCategory: false,
subcategories: [],
form: new Form({
sharedState: product.data
})
}
},
mounted() {
this.getCategories();
},
methods: {
getCategories() {
axios.get('categories')
.then(({data}) => this.categories = data);
},
show(subcategories) {
this.revealSubCategory = true;
this.subcategories = subcategories
}
}
}
</script>
And a select sub category input (it is there on the second column) which is will be displayed once the user has selected one of the categories options. Each category option has relation to sub categories taken from the API.
How can I get the sub categories and display the input? I already tried #change on the select tag but I can't pass the sub category object because it is outside the loop. And #click event seems to be not working in an option tag.
You can watch the v-model of the first select and change subcategory.
watch:{
"form.sharedState.category_id": function (val) {
// update subcategories here
}
You can see my case below
My vue component is like this :
<template>
<select class="form-control" :name="elementName" v-model="selected" :required="module === 'addProduct'" >
<option>Choose</option>
<option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>
</select>
</template>
<script>
...
export default {
...
props: ['elementName', 'module'],
data() {
return {
selected: 'Choose'
};
},
...
};
</script>
The result is like this :
I don't select anything. I click button submit, the required not working. It not display the required
I try like this :
<option value="">Choose</option>
It works. But, when accessed first time, option choose not show
How can I solve this problem?
See their example: https://v2.vuejs.org/v2/guide/forms.html#Select
It doesn't display anything because you have: selected: 'Choose' but you have no option with value="Choose". (the value is the empty string, "Choose" is just the inner text of the option element).
Try this:
<template>
<select class="form-control" :name="elementName" v-model="selected" :required="module === 'addProduct'" >
<option disabled value="">Choose</option>
<option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>
</select>
</template>
<script>
...
export default {
...
props: ['elementName', 'module'],
data() {
return {
selected: ''
};
},
...
};
</script>
Maybe I'm doing it wrong but while binding v-if to two distinct input fields it only works if the input values hasn't changed.
var app = window.app = new Vue({
el: '#admin-app',
data() {
return {
language: "en"
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.common.js"></script>
<div id="admin-app">
<select id="language" name="language" class="form-control" v-model="language">
<option value="ro">Romanian</option>
<option value="en">English</option>
</select>
<input type="text" class="form-control" value="Test RO" v-if="language == 'ro'" />
<input type="text" class="form-control" value="Test EN" v-if="language == 'en'" />
</div>
As soon as one of the input fields has changed the v-if does not seem to work anymore. Although the "language" value changes when another option is selected.
VueJS appears to be extrapolating the inline input value as needing to be bound. I suspect that the input value is bound to the language prop. As a result, you can no longer safely evaluate your if condition once a value has been changed.
A workaround to this is to give both inputs explicit models via v-model. This correctly allows for both your conditional display and your input binding.
var app = window.app = new Vue({
el: '#admin-app',
data() {
return {
language: "en",
test1: "Test RO",
test2: "Test EN"
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.common.js"></script>
<div id="admin-app">
<select id="language" name="language" class="form-control" v-model="language">
<option value="ro">Romanian</option>
<option value="en">English</option>
</select>
<input type="text" class="form-control" v-model="test1" v-if="language == 'ro'" />
<input type="text" class="form-control" v-model="test2" v-if="language == 'en'" />
</div>