5π
If you actually want to move items between arrays, you can do it this way. I cleaned code a bit to concentrate only on this.
Html:
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<select v-model="availableFacilitiesSelectedValues" multiple="multiple">
<option v-for="facility in availableFacilities" v-bind:value="facility.value">{{facility.text}}</option>
</select>
<select v-model="selectedFacilitiesSelectedValues" multiple="multiple">
<option v-for="facility in selectedFacilities" v-bind:value="facility.value">{{facility.text}}</option>
</select>
<br/>
<a @click.prevent="addFacilities" href="#">add</a>
<br/>
<a @click.prevent="removeFacilities" href="#">remove</a>
</div>
JS:
new Vue({
el: "#app",
data: {
availableFacilities: [{
value: 1,
text: 'Double (Non a/c)',
}, {
value: 2,
text: 'Premium Double (a/c)',
}, {
value: 3,
text: 'Standard Double (a/c)',
}, ],
selectedFacilities: [],
availableFacilitiesSelectedValues: [], // Facility values, selected in first control
selectedFacilitiesSelectedValues: [], // Facility values, selected in second control
},
methods: {
move(value, arrFrom, arrTo) { // Helper function to transfer facility from one array to another by 'value' property
var index = arrFrom.findIndex(function(el) {
return el.value == value;
});
var item = arrFrom[index];
arrFrom.splice(index, 1);
arrTo.push(item);
},
addFacilities() {
var selected = this.availableFacilitiesSelectedValues.slice(0);
for (var i = 0; i < selected.length; ++i) {
this.move(selected[i], this.availableFacilities, this.selectedFacilities);
}
},
removeFacilities() {
var selected = this.selectedFacilitiesSelectedValues.slice(0);
for (var i = 0; i < selected.length; ++i) {
this.move(selected[i], this.selectedFacilities, this.availableFacilities);
}
},
}
})
Working fiddle example: https://jsfiddle.net/9x0s73gk/
1π
How about
export default {
data(){
return{
facilitySelected:[],
availableFacilities: [{
value: 1,
label: 'Double (Non a/c)',
selected: false,
},
{
value: 2,
label: 'Premium Double (a/c)'
selected: false,
},
{
value: 3,
label: 'Standard Double (a/c)'
selected: false,
}
],
},
computed: {
selectedFacilities() {
return this.availableFacilities.filter(f => f.selected);
},
unselectedFacilities() {
return this.availableFacilities.filter(f => !f.selected);
},
}
},
And bind your <select>
s to 2 computed list accordingly. When add/remove is clicked you just set the selected property of the items to true/false.
By the way, what youβre trying to implement looks very much like a transfer
component. For example: http://element.eleme.io/#/en-US/component/transfer.
1π
I changed some parts in your code and then it worked.
I think the reason why it didnβt work is related to v-bind:value="facility.value"
, you bound object in first select box but integer value in second one. It made values bound by each v-model
differed in types.
fiddle
new Vue({
el: "#app",
data: {
facilitySelected1: [],
facilitySelected2: [],
availableFacilities: [{
value: 1,
text: 'Double (Non a/c)'
},
{
value: 2,
text: 'Premium Double (a/c)'
},
{
value: 3,
text: 'Standard Double (a/c)'
}
],
selectedFacilities: [],
},
methods: {
removeFacilities() {
this.selectedFacilities = this.selectedFacilities.filter(fac => !this.facilitySelected2.includes(fac));
this.availableFacilities = [...this.availableFacilities, ...this.facilitySelected2];
this.facilitySelected2 = [];
},
addFacilities() {
this.availableFacilities = this.availableFacilities.filter(fac => !this.facilitySelected1.includes(fac));
this.selectedFacilities = [...this.selectedFacilities, ...this.facilitySelected1];
this.facilitySelected1 = [];
}
}
})
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<select v-model="facilitySelected1" multiple="multiple" id="facilities" size="4" class="form-control">
<option v-for="availability in availableFacilities" :value="availability">{{availability.text}}</option>
</select>
<a @click="removeFacilities" class="btn btn-default remove_option" rel="facilities2" id="remove"><i class="fa fa-arrow-left"></i></a>
<a @click="addFacilities" class="btn btn-default add_option" rel="facilities2" id="add"><i class="fa fa-arrow-right"></i></a>
<select v-model="facilitySelected2" multiple="multiple" id="facilities2" size="4" class="form-control">
<option v-for="facility in selectedFacilities" :value="facility">{{facility.text}}</option>
</select>
</div>
1π
Check this solution I made:
https://jsfiddle.net/Lfd6j90c/2/
Iβve changed some of your code
new Vue({
el: "#app",
data: {
add: [],
remove: [],
facilitySelected: [],
availableFacilities: [{
value: 1,
text: 'Double (Non a/c)'
}, {
value: 2,
text: 'Premium Double (a/c)'
}, {
value: 3,
text: 'Standard Double (a/c)'
}]
},
methods: {
addFacilities() {
var af = this.availableFacilities;
var fs = this.facilitySelected;
this.add.forEach(function(element) {
fs.push(af[element]);
af.splice(element, 1);
});
this.availableFacilities = af;
this.facilitySelected = fs;
},
removeFacilities() {
var af = this.availableFacilities;
var fs = this.facilitySelected;
this.remove.forEach(function(element) {
af.push(fs[element]);
fs.splice(element, 1);
});
this.availableFacilities = af;
this.facilitySelected = fs;
}
}
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<div class="row">
<div class="col-xs-5">
<select v-model="add" multiple="multiple" size="4" class="form-control">
<option v-for="(item, index) in availableFacilities" v-bind:value="index">
{{ item.text }}
</option>
</select>
</div>
<div class="col-xs-2 ">
<button @click="removeFacilities" class="btn btn-default remove_option" rel="facilities2" id="remove"><</button>
<button @click="addFacilities" class="btn btn-default add_option" rel="facilities2" id="add">></button>
</div>
<div class="col-xs-5">
<select v-model="remove" multiple="multiple" size="4" class="form-control">
<option v-for="(item, index) in facilitySelected" v-bind:value="index">
{{ item.text }}
</option>
</select>
</div>
</div>
</div>