I have a vue2 app which I need to pre-select a dropdown but for the life of me, I can't figure it out.
I have looked and tried everything in:
How to preselect current value in a select created with v-repeat in Vue.js
Normal HTML
<select ref="courierList" id="courierList" class="form-control" v-model="shippingDetails.selectedCourier" #change="selectedCourierDd">
<option :value="courier.name" v-for="(courier, i) in couriers" :key="i">
{{ courier.name }}
</option>
</select>
data() {
return {
couriers: [],
.... OTHER DATA ITEMS
}
},
beforeMount() {
this.fetchCouriers();
},
fetchCouriers() {
axios.get('/couriers')
.then((response) => {
this.couriers = response.data.couriers;
.... OTHER CODE
Tried code > 1
Adding the below to the option
selected="{{ courier.name === preselectedCourierName ? 'true' : 'false' }}">
also tied without the true/false
Tried code > 2
Adding the below to the option
v-bind:selected="courier === preselectedCourierName"
and the below
data() {
return {
.... OTHER DATA ITEMS
preselectedCourier: [],
preselectedCourierName: ''
}
fetchCouriers() {
axios.get('/couriers')
.then((response) => {
this.couriers = response.data.couriers;
.... OTHER CODE
console.log('couriers', this.couriers[0])
this.preselectedCourier = this.couriers[0];
this.preselectedCourierName = this.preselectedCourier.name;
console.log('preselectedCourier', this.preselectedCourier)
console.log('preselectedCourierName', this.preselectedCourierName)
gives
Tried code > 3
<option :value="courier.name" v-for="(courier, i) in couriers" :key="i" :selected="courier.name === 'APC'">
no errors but dropdown still not pre-selected
The fix is in the mounted hook set the v-model of the select
<select v-model="shippingDetails.selectedCourier">
mounted() {
this.shippingDetails.selectedCourier = 'APC';
}
Give me exactly what i wanted
Related
I have a set of results in my Vue app. I want to be able to sort them alphabetically after I have searched. I then want them to return to the state before I clicked 'alphabetically' also. In my case its relevancy.
Relevancy is how it loads and before I choose 'Alphabetically'
The alphabetical option works fine but when I change it back to 'relevancy' it doesnt do anything and I dont understand why. To me it should just be 'return this.results();'
Can anyone help please?
<select
class="form-control col-4 col-lg-5"
v-model="sortatoz"
#change="sortItems"
id="sortby"
aria-label="sortby"
>
<option disabled value="" selected>Select</option>
<option value="alphabetically">Alphabetically</option>
<option value="relevance">Relevance</option>
</select>
//sort drop down
sortItems() {
if (this.sortatoz === "alphabetically") {
return this.results.sort((a, b) =>
a.title > b.title ? 1 : -1
);
} else {
return this.results();
}
},
So first of all, you copy your original set into a data variable you going to show inside your HTML.
So whenever you sort, you use this copied variable to sort.
But whenever you want relevance again, you just copy the original again in the copied variable.
new Vue({
el: '#app',
data: {
list: ['A', 'C', 'B'],
copiedList: []
},
mounted () {
this.unsort()
},
methods: {
sort() {
this.copiedList = [...this.list].sort((a, b) =>
a > b ? 1 : -1
);
},
unsort() {
this.copiedList = [...this.list]
}
}
})
<div id="app">
<button #click="sort">Sort</button>
<button #click="unsort">Unsort</button>
<div v-for="element in copiedList">
<div> {{ element }} </div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
I have the following form:
This is the edit form.
As you can see I have a multiple select. I need to bind the values from the server to the select.
Here is structure of my objects from the server.
1) All elements for the multiple select:
2) Particular objects, that I want to see selected. As you can see, there's an additional field called 'pivot'.
As a result, I would like to see the following when I open my form:
I have tried something like this, but without success:
<div class="form-group">
<label for="bk">Связанные бк</label>
<select class="form-control form-control-sm" id="bk" v-model="formFields.applicationBk" multiple>
<option v-for="bk in allBk" v-if="applicationBk.find(x => x.id === bk.id) 'selected'" >
{{ bk.name }}
</option>
</select>
Here is full js code:
<script>
import { EventBus } from '../../app';
export default {
name: "ApplicationEdit",
props: ['applicationId', 'name', 'offer', 'bundleId', 'isBlackMode', 'applicationBk', 'allBk'],
mounted: function(){
console.log(this.applicationBk)
},
methods:{
submit: function (e) {
window.axios.post('/application/edit/' + this.applicationId, this.formFields)
.then(res => {
console.log('Сохранил!');
$('#applicationEdit' + this.applicationId).modal('hide');
EventBus.$emit('reloadApplicationsTable');
}).catch(err => {
if(err.response.status === 422){
this.errors = err.response.data.errors || [];
}
//console.error('Ошибка сохранения приложения. Описание: ');
console.error(err)
});
}
},
data(){
return {
formFields: {
applicationId: this.applicationId,
applicationBk: this.applicationBk,
name: this.name,
offer: this.offer,
bundle_id: this.bundleId,
giraffe: this.isBlackMode,
bk: this.applicationBk,
},
errors: []
}
}
}
You might consider using your loop as you have but using v-model to an array of the selected values. Here is vue's example of this: https://v2.vuejs.org/v2/guide/forms.html#Select
I have a vue component that is meant to create a select list with all available options. The save method puts the saved value into a vuex store. The available fields are generated using a computed property on the component that calls the vuex getter for the list.
In the component, there's a v-for with a v-if that checks that the select item isn't already being used by another component (by looking at a mapped property on the list item object).
Testing this, everything seems to be working as expected, the vuex store gets the list, it accepts the update, and once a save is called, the destination field is marked as mapped and that mapped property is visible in the vuex debug panel.
However, the other select lists on the page don't get updated to reflect the (now shorter) list of available options.
Once the select item is selected in another instance of the component, I'd expect the other components to drop that select option- but it appears the v-if is not re-evaluated after the initial load of the component?
Sorry, here's the basic component:
<template>
<div class="row">
<div class="col-4">
{{ item.source_id }}
</div>
<div class="col-8">
<select v-model="destination" class="form-control form-control-sm">
<option v-for="dest in destinationFields" v-if="shouldShow(dest)" v-bind:value="dest.id">{{ dest.id }} - {{ dest.label }} ({{ dest.dataType }})</option>
</select>
</div>
</div>
</template>
<script>
export default {
props: ['item'],
data() {
return {
destination: ''
}
},
methods: {
shouldShow: function(dest) {
if (this.hideDestination && (!dest.hasOwnProperty('mapped') || dest.id === this.destination)) {
return true
} else if (!this.hideDestination) {
return true
}
return false
}
},
computed: {
destinationFields: function() {
return this.$store.getters.visibleDestination
},
hideDestination: function() {
return this.$store.getters.hideMappedDestinations // boolean
}
}
}
I think a better approach would be to already filter the data inside of your computed function as follows:
computed: {
destinationFields: function() {
return this.$store.getters.visibleDestination()
.filter(dest => !dest.hasOwnProperty('mapped') || dest.id === this.destination)
},
hideDestination: function() {
return this.$store.getters.hideMappedDestinations // boolean
}
}
You would also have to change your template to:
<select v-model="destination" class="form-control form-control-sm">
<option v-for="dest in destinationFields" v-bind:value="dest.id">{{ dest.id }} - {{ dest.label }} ({{ dest.dataType }})</option>
</select>
I have an object that contains user names in this structure:
clients: {
1: {
first_name:"John"
last_name:"Doe"
middle_name:"A"
},
2: {
first_name:"Jenny"
last_name:"Doe"
},
}
I want to loop though them in a select input as options
<option v-for="(value, client, index) in clients" :value="">{{ value }}</option>
I came until here, but I couldn't figure out how to organize the string properly. Maybe, is there a way to parse it in computed properties so I can have room to put code?
If I could use something like this, I think it would work, but couldn't figure out how to do it like this either.
computed:{
clientNameOptions() {
for (const key of Object.keys(this.clients)) {
return `<option value="` + this.clients[key].first_name + ' ' + this.clients[key].middle_name + ' ' +
this.clients[key].last_name + `"></option>`
}
}
}
What is the proper way of achieving it?
This is primarily a guess at what you want, but you could build your options using a computed property.
console.clear()
new Vue({
el:"#app",
data:{
clients: {
1: {
first_name:"John",
last_name:"Doe",
middle_name:"A"
},
2: {
first_name:"Jenny",
last_name:"Doe"
},
},
selectedClient: null
},
computed:{
options(){
return Object.keys(this.clients).map(k => {
let o = this.clients[k]
return `${o.first_name} ${o.middle_name ? o.middle_name : ''} ${o.last_name}`
})
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="app">
<select v-model="selectedClient">
<option v-for="option in options" :value="option">{{option}}</option>
</select>
<hr>
Selected: {{selectedClient}}
</div>
My vue component is like this :
<template>
<select class="form-control" v-model="selectedProvince"="level === 'province'" v-model="selectedProvince"="level === 'city'">
<option value="">Choose</option>
<option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>
</select>
</template>
<script>
export default {
props: ['level'],
data() {
return {
selectedProvince: '',
selectedCity: '',
};
},
...
};
</script>
Select provinces and cities have 1 select. It is differentiated by level. I want to add condition
If level = province, it will run v-model = "selectedProvince"
If level = city, it will run v-model = "selectedCity"
I tried like the code above, but from the writing, it seems it is still wrong
How can I do it correctly?
Setting aside the issue that it seems odd that you would have two separate types of information in the same select, you would probably want to derive your values using computed values instead of what you're trying.
data(){
return {
selectedOption: null,
level: "province"
}
},
computed:{
selectedProvice(){
if (this.level === "province")
return this.selectedOption
else
return null
},
selectedCity(){
if (this.level === "city"
return this.selectedOption
else
return null
}
}
Then use selectedOption for your model.
<select class="form-control" v-model="selectedOption">