Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nhayder's avatar
Level 13

Moving items between 2 multiple select elements with our id

I'm trying to integrate shipping zones (country to state) where a user can load a country states from json object to display list of states on a multiple select html element.

// my countries to states json array
{
   "name": "United States",
   "iso3": "USA",
   "iso2": "US",
   "states": [
       {
           "name": "Alabama",
           "state_code": "AL"
       },
       {
           "name": "Alaska",
           "state_code": "AK"
       },
       ...
   ]
},{
   "name": "Uruguay",
   "iso3": "URY",
   "iso2": "UY",
   "states": [
       {
           "name": "Artigas Department",
           "state_code": "AR"
       },
       ...

on same page i have 2 multiple select html where user can select multiple items from states to add them to selected shipping zones list.

// List of states in a country
  <select multiple v-model="selected" @dblclick="addState">
    <option v-for="(state, index) in states">{{state.name}}</option>
    </option>
  </select>

// this is the selected shipping states
  <select multiple v-model="selected_zones" @dblclick="removeState">
    <option v-for="zone in zones">
      {{ zone }}
    </option>
  </select>

to programatically move clicked items i have this function

addState() {
    if(!this.selected.length) return;
    for(let i=this.selected.length;i>0;i--) {
      let idx = this.states.indexOf(this.selected[i-1]);
      this.states.splice(idx, 1);
      this.selected_zones.push(this.selected[i-1]);
      this.selected.pop();
    }
  },

As a result i can see that only last element in the states array is getting moved to selected_zones object regardless which item is getting click on the states array.

is there is any way to correct this issue, i need the user to be able to move click items not last item in state object.

Any ideas

0 likes
5 replies
vincent15000's avatar

What do you have in your condole if you add console.log(this.selected); at the beginning of the addState() method ?

1 like
Ben Taylor's avatar

Does this work?


addState() {
	this.selected.forEach((state) => {
		this.states.splice(this.states.indexOf(state) , 1)
		this.selected_zones.push(state);
	})
	this.selected = []
  },
2 likes
nhayder's avatar
Level 13

@Ben Taylor the code your provided works but apart from the splice portion of it, using your code i'm getting almost the same result, the app is pushing the correct data but splicing the last items in the states array, where is should be replaced with what the user has selected?

I have made some changes the code and will post the updated comp below

1 like
nhayder's avatar
Level 13

i have made some changes to my component, this is my entire component

<template>

<div>

    // this gets a list of countries on change
    <select v-model="location" @change="getStates()">
        <option v-for="(country, index) in countries" :key="country.id"
            :value="country.code" v-text="country.en">
        </option>
    </select>
    <div class="flex -mx-2">
        <select multiple v-model="selected" @dblclick="addStates">
            <option v-for="(state, index) in states">
                {{stateName(state)}}
            </option>
        </select>
        <div class="flex-column">
            <a @click.stop="addStates()"></a>
            <a @click.stop="removeStates()"></a>
        </div>
        <select multiple v-model="putback" @dblclick="removeStates">
            <option v-for="(move, index) in moved">
               {{move}}
            </option>
        </select>
    </div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
    name: 'zone-manager',
    mounted(){
        this.$store.state.trans;
        this.$store.state.countries;
        this.$store.state.zones;
        this.$store.state.states;
    },
    data () {
          return {
            location    :   '',
            name        :   '',
            isDisabled  :   false,
            errors      :   [],
            selected    :   [],
            moved       :   [],
            putback     :   []
        }
    },

    computed:{
        ...mapState(['trans', 'countries', 'zones', 'states']),
    },
    methods: {
        addStates() {
            console.log(this.states);
            this.selected.forEach((state) => {
                this.states.splice(this.states.indexOf(state) , 1)
                this.moved.push(state);
            })
            this.selected = []
        },
        stateName : function(object){
            return object.state_code+' - '+ object.name;
        },
        removeStates(){
            //????
        },

        getStates(){
            this.selected = [];
            this.$store.dispatch('getStates', [this.location]);
        },

    }

}
    
</script>

snapshots from my screen https://prnt.sc/0C6_whyHULUI https://prnt.sc/7Pzw9SGDFkgr

1 like

Please or to participate in this conversation.