Javascript将具有多个值的选定选项从一个列表移动到另一个列表

Posted

技术标签:

【中文标题】Javascript将具有多个值的选定选项从一个列表移动到另一个列表【英文标题】:Javascript move selected option with multiple values from one list to another 【发布时间】:2021-11-12 01:00:24 【问题描述】:

我正在尝试为有多个选择的表单创建一个双重列表框。这包括两个列表,其中一个包含您可以从中选择的选项,另一个是已选择的选项。我正在使用带有 vue-bootstrap 的 vue2 而没有 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">&raquo;</b-button>
            <b-button class="primary" block  variant="primary" size="sm" @click="someToRight">&rsaquo;</b-button>
            <b-button class="primary" block  variant="primary" size="sm" @click="someToLeft">&lsaquo;</b-button>
            <b-button class="primary" block  variant="primary" size="sm" @click="allToLeft">&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】:

你可以尝试如下 sn-p :

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">&raquo;</b-button>
        <b-button class="primary" block  variant="primary" size="sm" @click="allToLeft">&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>

【讨论】:

以上是关于Javascript将具有多个值的选定选项从一个列表移动到另一个列表的主要内容,如果未能解决你的问题,请参考以下文章

使用 JavaScript,如何在具有多个值的日期列的表中突出显示“今天”的每个日期

jQuery创建具有选定属性和值的对象

CI - 帮助插入多个选择表单,每个表单都有多个选定选项

从单个表中检索具有不同值的同一列的多个输出时的性能问题

如何将具有多个值的列加载到表中的单独行中

如何对具有多个值的多个列求和