问题排序选择选项

时间:2019-10-28 15:38:19

标签: javascript jquery

链接的片段只是我正在做的一个粗略示例,但将演示我遇到的问题。我有两个选择框,可以在它们之间转移项目。我需要跟踪某个项目何时从其原始框移出,以便稍后在以后通过ajax调用提交更改时进行,因为我不想在传输中包括整个列表,仅需要什么。 (我的真实数据是更大的列表)

为了跟踪,我使用了一个数据属性“ data-changed”。为了帮助反映更新时标记的内容,我在该特定选项上切换了一个类。这一切都很好,花花公子。我的问题是当我尝试在这些列表上实施排序时。这些选项按预期进行了排序,但似乎在此过程中丢失了其data属性,这破坏了其他内容。我不知道如何解决这个问题。

https://jsfiddle.net/bnLfhpq4/

$('#btnSubmit').click(function(e) {
  e.preventDefault();

  var arr = new Array();

  // get options from active list
  var options = $('#activeList option');
  options.each(function(i, o) {
    if ($(o).data('changed') == "yes") {
      var skill = {
        id: $(o).val(),
        active: 0
      }
      arr.push(skill);
    }
  });


  // get options from inactive list
  var options = $('#inactiveList option');
  options.each(function(i, o) {
    if ($(o).data('changed') == "yes") {
      var skill = {
        id: $(o).val(),
        active: 1
      }
      arr.push(skill);
    }
  });

  console.log(arr);
});


$('#btn_in').click(function() {
  var options = $('#activeList option:selected');

  options.each(function(i, o) {
    var c = $(o).data('changed');
    if (c == "yes") {
      $(o).data('changed', 'no');
      $(o).removeClass('flagged');
    } else {
      $(o).data('changed', 'yes');
      $(o).addClass('flagged');
    }
  });

  $('#inactiveList').append(options);

  //sortOptions('#inactiveList');

});




$('#btn_out').click(function() {
  var options = $('#inactiveList option:selected');

  options.each(function(i, o) {
    var c = $(o).data('changed');
    if (c == "yes") {
      $(o).data('changed', 'no');
      $(o).removeClass('flagged');
    } else {
      $(o).data('changed', 'yes');
      $(o).addClass('flagged');
    }
  });

  $('#activeList').append(options);
  sortOptions('#activeList');

});





function sortOptions(selector) {
  var options = $(selector + ' option');

  options.sort(function(a, b) {
    if (a.text > b.text) return 1;
    if (a.text < b.text) return -1;
    return 0;
  });

  $(selector).empty().append(options);


}
.superSelect {
  min-height: 200px;
}

.buttons {
  display: inline-block
}

.flagged {
  color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple id="activeList" class="superSelect">
  <option value="t1" data-changed="no">Option 1</option>
  <option value="t2" data-changed="no">Option 2</option>
  <option value="t3" data-changed="no">Option 3</option>
  <option value="t4" data-changed="no">Option 4</option>
</select>

<div class="buttons">
  <button id="btn_in">>>></button><br/><br/>
  <button id="btn_out"><<<</button>
</div>


<select multiple id="inactiveList" class="superSelect">
  <option value="x1" data-changed="no">Thingy 1</option>
  <option value="x2" data-changed="no">Thingy 2</option>
  <option value="x3" data-changed="no">Thingy 3</option>
  <option value="x4" data-changed="no">Thingy 4</option>
</select>

<br/>

<button id="btnSubmit">Submit</button>

1 个答案:

答案 0 :(得分:2)

  1. 已经给出了一个很好的解释,说明为什么不将data-属性和data()混合使用in this answer。因此,将所有内容更改为使用.attr('data-changed'),它将起作用。

    之所以没有排序功能,是因为当通过empty()从DOM中删除该节点时,jQuery内部存储的数据与DOM节点之间的关联显然丢失了。通过append()

  2. 您不需要使用额外的类来可视化已更改的选项。只需在CSS中使用属性选择器[data-changed="yes"]
  3. 每个按钮单击事件的两个回调几乎相同,只是交换的列表ID不同。我将代码重构为使用单个功能,并在列表之间动态切换。
  4. 尽管这仅可能是您在此演示中创建的代码中的情况,而并非在您实际的应用程序中是这种情况:避免使用<>字符(在按钮标签中)而不对其进行编码作为HTML实体&lt; / &gt;。尽管所有主流浏览器都应将按钮呈现得很好,但是客户端的解析器可能会感到困惑并导致某些显示问题。

$('#btnSubmit').click(function(e) {
  e.preventDefault();

  var arr = new Array();

  // get options from active list
  var options = $('#activeList option');
  options.each(function(i, o) {
    if ($(o).data('changed') == "yes") {
      var skill = {
        id: $(o).val(),
        active: 0
      }
      arr.push(skill);
    }
  });


  // get options from inactive list
  var options = $('#inactiveList option');
  options.each(function(i, o) {
    if ($(o).data('changed') == "yes") {
      var skill = {
        id: $(o).val(),
        active: 1
      }
      arr.push(skill);
    }
  });

  console.log(arr);
});


$activeList = $('#activeList');
$inactiveList = $('#inactiveList');

function moveOptions() {
  var $otherList = this === $activeList ? $inactiveList : $activeList;
  var options = $('option:selected', this);

  options.each(function(i, o) {
    var c = $(o).data('changed');
    if (c == "yes") {
      $(o).attr('data-changed', 'no');
    } else {
      $(o).attr('data-changed', 'yes');
    }
  });

  $otherList.append(options);
  sortOptions($otherList);
}

$('#btn_in').click(moveOptions.bind($activeList));
$('#btn_out').click(moveOptions.bind($inactiveList));

function sortOptions(list) {
  var options = $('option', list);

  options.sort(function(a, b) {
    if (a.text > b.text) return 1;
    if (a.text < b.text) return -1;
    return 0;
  });

  list.empty().append(options);


}
.superSelect {
  min-height: 200px;
}

.buttons {
  display: inline-block
}

[data-changed="yes"] {
  color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple id="activeList" class="superSelect">
  <option value="t1" data-changed="no">Option 1</option>
  <option value="t2" data-changed="no">Option 2</option>
  <option value="t3" data-changed="no">Option 3</option>
  <option value="t4" data-changed="no">Option 4</option>
</select>

<div class="buttons">
  <button id="btn_in">&gt;&gt;&gt;</button><br/><br/>
  <button id="btn_out">&lt;&lt;&lt;</button>
</div>


<select multiple id="inactiveList" class="superSelect">
  <option value="x1" data-changed="no">Thingy 1</option>
  <option value="x2" data-changed="no">Thingy 2</option>
  <option value="x3" data-changed="no">Thingy 3</option>
  <option value="x4" data-changed="no">Thingy 4</option>
</select>

<br/>

<button id="btnSubmit">Submit</button>