Javascript переместить выбранный параметр с несколькими значениями из одного списка в другой

#javascript #html #vue.js #vuejs2 #multiple-choice

Вопрос:

Я пытаюсь создать двойной список для форм, в которых есть несколько вариантов выбора. Он состоит из двух списков, в одном из которых есть параметры, которые вы можете выбрать, и в одном из них выбраны параметры. Я использую vue2 с vue-загрузкой без Jquery.

два списка, которые у меня есть, это:

       list1:[
  {
    "id": 1,
    "foo": "Test",
    "bar": 12,
    "text": "a"
  },
  {
    "id": 2,
    "foo": "ee",
    "bar": 45,
    "text": "b"
  },
  {
    "id": 3,
    "foo": "aa",
    "bar": 345,
    "text": "c"
  },
  {
    "id": 4,
    "foo": "hi",
    "bar": 56,
    "text": "d"
  },
  {
    "id": 5,
    "foo": "Shot",
    "bar": "Pew pew",
    "text": "e"
  },
  {
    "id": 6,
    "foo": "as",
    "bar": 2345,
    "text": "f"
  }
],
      list2:[
  {
    "id": 5,
    "foo": "Tsst",
    "bar": 132,
    "text": "q1"
  },
  {
    "id": 6,
    "foo": "eeee",
    "bar": "4r5",
    "text": "q2"
  }
],
 

HTML-код для каждого списка выглядит следующим образом:

 <b-row class="my-1">
    <b-col cols="5">
        <select size="30" class="form-control" id="list1" multiple>
            <option v-for="item1 in list1" v-bind:key="item1" value='{"foo":"item1.foo","bar":"item1.bar"}'>{{item1.text}}</option>
        </select>
    </b-col>
    <b-col cols="2">
        <b-col lg="4"  class="pb-2">
            <b-button class="primary" block  variant="primary" size="sm" @click="allToRight">amp;raquo;</b-button>
            <b-button class="primary" block  variant="primary" size="sm" @click="someToRight">amp;rsaquo;</b-button>
            <b-button class="primary" block  variant="primary" size="sm" @click="someToLeft">amp;lsaquo;</b-button>
            <b-button class="primary" block  variant="primary" size="sm" @click="allToLeft">amp;laquo;</b-button>
        </b-col>
    </b-col>
    <b-col cols="5">
        <select size="30" class="form-control" id="list2" multiple>
            <option v-for="item2 in list2" v-bind:key="item2" value='{"foo":"item2.foo","bar":"item2.bar"}'>{{item2.text}}</option>
        </select>
    </b-col>
</b-row>
 

Javascript, управляющий кнопками, выглядит следующим образом:

   someToRight: function() {
    var select = document.getElementById('list1').value
    if(select != ""){
      this.list2.push(select)    //does not properly push values to other list
      var del = this.list1.indexOf(select)
      this.list1.splice(del,1)
    }
  },
  someToLeft: function() {
    var select = document.getElementById('list2').value
    if(select != ""){
      this.list1.push(select)   //does not properly push values to other list
      var del = this.list2.indexOf(select)
      this.list2.splice(del,1)
    }
  },
  allToRight: function() {
    for(let i = 0; i < this.list1.length; i  ){
      this.list2.push(this.list1[i])
      this.list1.splice(i,1)
      i--
    }
  },
  allToLeft: function() {
      for(let i = 0; i < this.list2.length; i  ){
      this.list1.push(this.list2[i])
      this.list2.splice(i,1)
      i--
  }
}
 

Прямо сейчас кнопки для отправки allToLeft и allToRight работают, но кнопки для перемещения одного или нескольких выбранных элементов не работают, если я не избавлюсь от лишних данных и не создам список с одним значением вместо JSON, как ['a','b','c'] я думаю, проблема в this.list.push(select) том, что строка неправильно форматирует данные, перемещаемые из одного списка в другой.

Ответ №1:

Вы не должны получать доступ к параметрам выбора через HTML, как вы сделали здесь:

 document.getElementById('list1').value
 

во-первых, это работает не так, как вы думаете, если вы хотите получить доступ к параметрам выбора таким образом, вы можете использовать что-то вроде этого

 document.getElementById('list1').options[0].value
 

кроме того, вы всегда должны работать со своими данными, и представление будет соответствующим образом обновляться, поэтому лучшим решением будет получить доступ к вашему массиву следующим образом

  someToRight: function() {
    var select = this.list1[0];
    if(select !== ""){
      this.list2.push(select) 
      var del = this.list1.indexOf(select)
      this.list1.splice(del,1)
    }
  },
  someToLeft: function() {
    var select = this.list2[0];
    if(select !== ""){
      this.list1.push(select)  
      var del = this.list2.indexOf(select)
      this.list2.splice(del,1)
    }
  }
 

Ответ №2:

Вы можете попробовать, как в следующем фрагменте :

 new Vue({
  el: '#demo',
  data() {
    return {
      list1:[
        {"id": 1, "foo": "Test", "bar": 12, "text": "a"},
        {"id": 2, "foo": "ee", "bar": 45, "text": "b"},
        {"id": 3, "foo": "aa", "bar": 345, "text": "c"},
        {"id": 4, "foo": "hi", "bar": 56, "text": "d"},
      ],
      list2:[
        {"id": 5,"foo": "Tsst", "bar": 132, "text": "q1"},
        {"id": 6, "foo": "eeee", "bar": "4r5", "text": "q2"}
      ],
      selectedItems: [],
      key: []
    }
  },
  methods: {
    addItem(item) {
      this.list2.push(item)
      let index = this.list1.indexOf(item)
      this.list1.splice(index, 1)
    },
    removeItem(item) {
      this.list1.push(item)
      let index = this.list2.indexOf(item)
      this.list2.splice(index, 1)
    },
    allToRight() {
      this.list2 = this.list2.concat(this.list1)
      this.list1 = []
    },
    allToLeft() {
      this.list1 = this.list1.concat(this.list2)
      this.list2 = []
    }
  }
}) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="demo">
  <b-row class="my-1">
    <b-col cols="5">
      <select size="30" class="form-control" id="list1" multiple >
        <option v-for="item1 in list1" :key="item1.id" :value="item1.id" @click="addItem(item1)">{{item1.text}}</option>
      </select>
    </b-col>
    <b-col cols="2">
      <b-col lg="4"  class="pb-2">
        <b-button class="primary" block  variant="primary" size="sm" @click="allToRight">amp;raquo;</b-button>
        <b-button class="primary" block  variant="primary" size="sm" @click="allToLeft">amp;laquo;</b-button>
      </b-col>
    </b-col>
    <b-col cols="5">
      <select size="30" class="form-control" id="list2" multiple>
        <option v-for="item2 in list2" :key="item2.id" :value="item2.id" @click="removeItem(item2)">{{item2.text}}</option>
      </select>
    </b-col>
</b-row>
</div>