Как переключить выбор опции в multi-select с помощью jQuery?

у меня есть стандартный select multiple поле ввода HTML, например:

<select multiple="multiple" size="5" id="mysel" name="countries"> 
    <option value="2">Afghanistan</option> 
    <option value="4">Aland</option> 
</select>

поскольку это multi-select, чтобы выбрать более одного значения, вы должны удерживать CTRL key и выберите любые дополнительные элементы. Однако то, чего я хочу достичь, это:

  1. щелчок по НЕВЫБРАННОМУ параметру выбирает его
  2. выберите опцию отмене выбора его.

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

Я еще не смогла реализовать. Псевдокод должен выглядеть примерно так.

  1. поймать событие click.
  2. Проверьте, был ли элемент, который был нажат, не выбран, а затем выберите его
  3. или если был выбран элемент, который был нажат, а затем отменить выбор он.

Как я должен это реализовать?

7 ответов


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

$("select[multiple] option").mousedown(function(){
   var $self = $(this);

   if ($self.prop("selected"))
          $self.prop("selected", false);
   else
       $self.prop("selected", true);

   return false;
});

В старых версиях jQuery, где prop() недоступно:

$("select[multiple] option").mousedown(function(){
   var $self = $(this);

   if ($self.attr("selected"))
          $self.attr("selected", "");
   else
       $self.attr("selected", "selected");

   return false;
});

вы правы в своем желании изменить поведение по умолчанию для выбора нескольких полей ввода. Они, как правило, негативно влияют на пользовательский опыт, поскольку цель не ясно выражена, и пользователи могут не понимать, как их правильно использовать.

перепрофилирование мульти-выбора тоже неправильно. Если вы рассматриваете возможность использования select multiple, вам может потребоваться рефакторинг вашего дизайна. Возможно, вы можете использовать флажки вместо этого?

вот статья о тема: http://www.ryancramer.com/journal/entries/select_multiple/


Я только что попробовал это решение, и выбранный ответ не работал для Jquery 1.9.1

ответ Оскара выглядел намного лучше, но он смешал свойства с атрибутами и не работает, если вы выбираете, де-Выберите, а затем попробуйте выбрать еще раз, поскольку он помещает выбор в непригодное состояние

Я нашел правильный ответ для меня был следующий

$("select[multiple] option").mousedown(function () {
       if ($(this).prop("selected"))
           $(this).prop("selected", false);
       else
           $(this).prop("selected", true);
       return false;    });

надеюсь, это поможет другим ;)


другой вариант без JQuery:

var multiSelect = {};

function init() {      
  var s = document.getElementsByTagName('select');
  for (var i = 0; i < s.length; i++) {
    if (s[i].multiple) {
      var n = s[i].name;
      multiSelect[n] = [];
      for (var j = 0; j < s[i].options.length; j++) {
        multiSelect[n][j] = s[i].options[j].selected;
      }
      s[i].onclick = changeMultiSelect;
    }
  }
}

function changeMultiSelect() {
  var n = this.name;
  for (var i=0; i < this.options.length; i++) {
    if (this.options[i].selected) {
      multiSelect[n][i] = !multiSelect[n][i];
    }
    this.options[i].selected = multiSelect[n][i];
  }
}

window.onload = init;

вероятно, некоторые исправления приходят с новыми версиями jQuery:

$("select[multiple] option").mousedown(function(){
    var $self = $(this);

    if ($self.attr("selected")){
        $self.removeAttr("selected");
    } else {
        $self.attr("selected", "selected");
    }
    return false;
});

Javascript (без jquery):

var select = document.getElementById('mysel');
select.addEventListener('mousedown', function(e){
    var opt = e.target;
    if (opt.selected){
        opt.removeAttribute('selected');
        opt.selected = false;
    } else {
        opt.setAttribute('selected', '');
        opt.selected = true;
    }
    e.preventDefault();
});

Я вижу, что большинство ответов выше связывают событие с опцией вместо select. Если мой выбор имеет 1000 параметров, то он свяжет 1000 событий, это повлияет на производительность?

из-за этого я решил не привязывать мое событие в опции.


использование jQuery 1.9.1 код javascript:

   $("select[multiple] option").mousedown(function () {
       var $self = $(this);
       if ($self.prop("selected"))
           $self.removeAttr("selected");
       else
           $self.attr("selected", "selected");
       return false;
   });