Vue.js Change previuos value back to default when switching between options - vue.js

I have an dropdown with multiple options.All options has display variable .By default it is set to available .If i select an option the display value changes to assigned name..I would like to change the previous selected display value back to available when i switch between options.
<div>
<label class="label">Student Name</label>
</div>
<div>
<select class="input"
:class="{ 'placeholder': studentNameInput === 0 }"
v-model="studentNameInput"
#change= "verify('studentName')">
<option v-for="(student, index) in students"
v-if="student.display=== 'available' || student.display === 'studentName'"
:key="index"
:value="index">
{{ student.name }}
</option>
</select>
</div>
**Method**
verify(val){
if (val === 'studentName') {
this.studentName = this.students[this.studentNameInput].id;
this.students[this.studentNameInput].display = 'studentName';
}
}

You can use a watcher on your v-model to retrieve the oldValue and set it's display to available when switching to a newValue
watch: {
studentNameInput: function (newValue, oldValue) {
this.students[oldValue].display = 'available'
}
}

Related

Show/hide next input field based on dropdown selection

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>

Vue JS - Display option 2 of select menu after it is disabled

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

how to validate two dropdowns depends upon selection?

I have two Dropdowns first dropdown 1 to 23 hours and the second dropdown also 1 to 23 hours.
If I select the first Dropdown is 4.the second drop-down is higher than the first dropdown selected value. how to do that
This is the solution for your concern. I have used the form if you are not used form then remove it and take the normal angular control.
HTML
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group">
<select formControlName="firstDropdown" class="form-control" (change)="firstDropDownChange($event)">
<option *ngFor="let value of values" [value]="value">
<span>{{ value }}</span>
</option>
</select>
<select formControlName="secondDropdown" class="form-control" (change)="secondDropDownChange($event)">
<option *ngFor="let value of values1" [value]="value">
<span>{{ value }}</span>
</option>
</select>
</div>
<button class="btn btn-primary" type="submit" [disabled]="!form.valid">
Submit
</button>
</form>
TS
values: any = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23];
values1: any = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23];
firstDropdown: any = 1;
secondDropdown: any = 1;
form: FormGroup;
constructor() {
this.form = new FormGroup({
firstDropdown: new FormControl(1),
secondDropdown: new FormControl(1),
});
}
firstDropDownChange(event) {
this.values1 = this.values.filter(
(data) => parseInt(event.target.value) <= data
);
console.log(this.values1);
this.form.controls['secondDropdown'].setValue(parseInt(this.values1[0]));
}
secondDropDownChange(event) {}
submit() {}

Populate text value when option selected from dropdown in vue

I have a vue app and new to vue. I have a dropdown which is populated via an axios endpoint. This returns 2 items. What I'm trying to do is, if 'APC' is selected, then populate a text value with an attribute value returned in my array but this is where I may be overthinking.
My thinking is that I need to iterate over the items again but if a condition is met display the value.
Below is my whole page code
<template>
<div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="courierList">Courier <span class="text-danger">*</span></label>
<div class="col-sm-7 shipping-options">
<select id="courierList" class="form-control" v-model="selectedCourier">
<option value='courierDefault'>Please select a courier</option>
<option :value="courier.name.toLowerCase()" v-for="(courier, index) in couriers" :key="courier.index">
{{ courier.name }}
</option>
</select>
</div>
</div>
<span v-if="selectedCourier != 'courierDefault'">
<div class="form-group row">
<b class="col-sm-3" for="cutOff">Order cut-off</b>
<div class="col-sm-7 shipping-options" v-for="(cutOff, index) in couriers" :key="cutOff.index">
{{ cutOff.cut_off }}
</div>
</div>
</span>
</div>
</template>
<script>
export default {
name: 'CourierSelect',
data() {
return {
couriers: [],
selectedCourier: 'courierDefault'
}
},
mounted() {
this.fetchCouriers();
},
methods: {
fetchCouriers() {
axios.get('/CHANGED_FOR_SECURITY')
.then((response) => {
this.couriers = response.data.couriers;
console.log('axios_couriers', this.couriers)
})
.catch((error) => {
VueEvent.$emit('show-error-modal', 'cartFethchCouriers');
console.log(error);
});
}
}
}
</script>
My console.log for 'axios_couriers' gives
Then when I select 'APC' my page displays as
But what I need is for the 'cut_off' value (displayed in the console screenshot) for the 'APC' Array object to display only. The value should be 16:30
Is there a way to do this as a Computed prop or something?
As you suggested a computed should indeed work.
One way would be:
currentCutOff() {
return this.couriers.find(c => c.name == this.selectedCourier).cut_off;
}
This tries to find the courier from your array which equals the name of the currently selectedCourier.
There is a much simplier solution with vuejs data binding.
Check this code:
const vm = new Vue({
el: '#app',
data() {
return {
items: [{
id: 1,
name: 'AAA',
time: '14:00'
},
{
id: 2,
name: 'BBB',
time: '18:00'
}
],
selected: null
}
}
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.min.js"></script>
<div id="app">
<select v-model="selected">
<option disabled value="null">Please select one</option>
<option v-for="item in items" v-bind:value="item">
{{ item.name }}
</option>
</select>
<div>Selected: {{ selected? selected.time : 'nothing selected' }}</div>
</div>

Vue v-for loop binding attribute

I'm trying to figure out how to do this in vue, I'm stuck trying to bind the value of the "selected" in the options.
In the simplified code below, I get exactly what I want, but only for the first product. It binds correctly with the first computed property:
<template>
<div>
<div v-for="index in 2" :key="index">
<select>
<option :selected="product1 === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="product1 === product.name"
>{{product.name}}</option>
</select>
</div>
</div>
</template>
<script>
// chosen products come from vuex store
computed: {
product1() {
return store.state.product1;
},
product2() {
return store.state.product2;
},
}
</script>
But then how can I change this to be automatic in the v-for loop, probably using the index?
What I need is actually a loop that will render this:
<template>
<div>
<select>
<option :selected="product1 === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="product1 === product.name"
>{{product.name}}
</option>
</select>
<select>
<option :selected="product2 === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="product2 === product.name"
>{{product.name}}
</option>
</select>
</div>
</template>
I've tried using something like:
:selected="`product${index}` === product.name"
but that gives a string, not the computed property value...
you can pass parameter to your computed property:
<template>
<div>
<div v-for="index in 2" :key="index">
<select>
<option :selected="getProduct(index) === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="getProduct(index) === product.name"
>{{product.name}}</option>
<script>
// chosen products come from vuex store
computed: {
getProduct() {
return index=>
store.state['product'+index];
},
}
</script>
You can put the selected products in an array and then access it by index:
computed: {
selectedProducts () {
return [store.state.product1, store.state.product2];
}
}
And then you can do :selected="selectedProducts[index] === product.name".