Выбор варианта сортировки - PullRequest
0 голосов
/ 28 октября 2019

Связанный фрагмент - всего лишь грубый пример того, что я делаю, но продемонстрирует проблему, с которой я столкнулся. У меня есть два поля выбора, между которыми я могу передавать элементы. Мне нужно отследить, когда элемент переместился из своего исходного поля, когда я отправляю изменения через вызов ajax позже, потому что я не хочу включать в передачу весь список, только то, что необходимо. (мои настоящие данные - гораздо большие списки)

Чтобы отслеживать, я использую атрибут данных «data-change». И чтобы помочь отразить то, что помечено для обновления, я переключаю класс для этой конкретной опции. Это все работает отлично и денди. Моя проблема, когда я пытаюсь реализовать сортировку в этих списках. Опции сортируются, как и ожидалось, но похоже, что в процессе они теряют свой атрибут данных, что нарушает другие функции. Я не могу понять, как это исправить.

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 Ответ

2 голосов
/ 28 октября 2019
  1. Очень хорошее объяснение, почему бы не смешивать data- атрибуты и data() уже было дано в этом ответе . Поэтому измените все на использование .attr('data-changed'), и оно будет работать.

    Причина, по которой это работало без функциональности упорядочения, заключается в том, что связь между данными, которые jQuery хранит внутри, и узлом DOM, очевидно, теряется, когдаузел удаляется из DOM через empty() и повторно добавляется через append().

  2. Вам не нужно использовать дополнительный класс для визуализации измененных опций. Просто используйте селектор атрибута [data-changed="yes"] в вашем CSS.
  3. Два обратных вызова каждого события нажатия кнопки были практически идентичны, отличаясь только заменяемыми идентификаторами списка. Я реорганизовал код для использования одной функции и динамического переключения между списками.
  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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...