根据两个父选项的索引值对子选项进行排序(仅限Javascript)



我试图创建一个双列表框使用只有香草Javascript没有JQuery或JS包,用于学习。

当用户双击一个Option时,该Option追加到另一个父Select (boxB),并从原始父Select (boxA)中删除,反之亦然。Option元素具有数字升序的数据索引属性。如何根据索引值维护选项的数字顺序,而不管它们附加哪个父Select ?

<!-- HTML -->
<select id="ctst1" class="form-control form-control-sm" size="8" multiple>
    <option data-index="1" value="CPT">CPT</option>
    <option data-index="2" value="SST">SST</option>
    <option data-index="3" value="EDTA">EDTA</option>
    <option data-index="4" value="PAXgene">PAXgene</option>
    <option data-index="5" value="NP SWB">NP SWB</option>
    <option data-index="6" value="OP SWB">OP SWB</option>
    <option data-index="7" value="RCTL SWB">RCTL SWB</option>
    <option data-index="8" value="Self NS">Self NS</option>
</select>
<select id="ctst2" class="form-control form-control-sm" size="8" multiple></select>
// Javascript
const dataFrame = {
    "selCollTubeSampTypes": [
        ["CPT", "CPT"],
        ["SST", "SST"],
        ["EDTA", "EDTA"],
        ["PAXgene", "PAXgene"],
        ["NP SWB", "NP SWB"],
        ["OP SWB", "OP SWB"],
        ["RCTL SWB", "RCTL SWB"],
        ["Self NS", "Self NS"]
    ]
};
function dualListBox(qryId1, qryId2, dataset) {
    const boxA = document.getElementById(qryId1);
    const boxB = document.getElementById(qryId2);
    // Populate avail box with data
    for (let i = 0; i < dataset.length; i++) {
        const eleOption = document.createElement("option");
        eleOption.dataset.index = i + 1; // Adds data-index value to Option node
        if (dataset[i][0] === "") {
            eleOption.textContent = dataset[i][1];
        } else {
            eleOption.value = dataset[i][0];
            eleOption.textContent = dataset[i][1];
        };
        boxA.appendChild(eleOption);
    };
    // When option in Box A is double-clicked, move it to Box B
    boxA.addEventListener("dblclick", e => {
        let eTargetOpt = e.target.closest("option");
        if (!eTargetOpt) return;
        if (!boxA.contains(eTargetOpt)) return;
        if (eTargetOpt) {
            boxB.appendChild(eTargetOpt);
            boxB.selectedIndex = "-1";
            boxA.removeChild(eTargetOpt);
        };
        e.stopPropagation();
    }, false);
    // When option in Box B is double-clicked, move it to Box A
    boxB.addEventListener("dblclick", e => {
        let eTargetOpt = e.target.closest("option");
        if (!eTargetOpt) return;
        if (!boxB.contains(eTargetOpt)) return;
        if (eTargetOpt) {
            boxA.appendChild(eTargetOpt);
            boxA.selectedIndex = "-1";
            boxB.removeChild(eTargetOpt);
        };
        e.stopPropagation();
    }, false);
dualListBox("ctst1", "ctst2", dataFrame.selCollTubeSampTypes);

由于您基本上对两个选择使用相同的逻辑,因此我将其合并为一个函数。而不是使用ID,这可能是有问题的,我们可以使用一个单一的className,并依靠基本的JS来确定哪个是哪个。排序机制(您最初的问题)的工作原理是将所有选项元素放入数组中,按数据集对数组进行排序。索引,然后重新填充选择元素。一组逻辑适用于两个盒子

const dataFrame = {
  "selCollTubeSampTypes": [
    ["CPT", "CPT"],
    ["SST", "SST"],
    ["EDTA", "EDTA"],
    ["PAXgene", "PAXgene"],
    ["NP SWB", "NP SWB"],
    ["OP SWB", "OP SWB"],
    ["RCTL SWB", "RCTL SWB"],
    ["Self NS", "Self NS"]
  ]
};
const dualListBox = (className, dataset) => {
  let boxSet = document.querySelectorAll(`.${className}`);
  dataset.forEach((item, i) => {
    let val = item[0] != "" ? item[0] : item[1];
    boxSet[0].innerHTML += `<option value="${val}" data-index="${i}">${item[1]}</option>`;
  })
  boxSet.forEach(myBox => myBox.addEventListener("dblclick", e => {
    let eTargetOpt = e.target.closest("option");
    if (!eTargetOpt) return;
    let targBox = myBox == boxSet[0] ? boxSet[1] : boxSet[0]
    if (eTargetOpt) {
      let targOptions = [...targBox.querySelectorAll('option')];
      targBox.innerHTML = '';
      myBox.removeChild(eTargetOpt);
      targOptions.push(eTargetOpt);
      targOptions.sort((a, b) => a.dataset.index - b.dataset.index)
      targOptions.forEach(opt => targBox.appendChild(opt))
    }
    e.stopPropagation();
  }, false));
}
dualListBox("box-set", dataFrame.selCollTubeSampTypes);
<select class="form-control form-control-sm box-set" size="8" multiple></select>
<select class="form-control form-control-sm box-set" size="8" multiple></select>

相关内容

  • 没有找到相关文章