Удалить последний выбранный элемент из множественного выбора, если пользователь выбирает более 3 вариантов с помощью jquery

Мне нужно выбрать только 3 варианта из множественного выбора. Если пользователь выбирает более 3 вариантов, последний выбранный элемент должен быть заменен новым, по которому щелкнули.

У меня есть пример следующим образом:

<select multiple id='testbox'>
      <option value='1'>First Option</option>
      <option value='2'>Second Option</option>
      <option value='3'>Third Option</option>
      <option value='4'>Fourth Option</option>
      <option value='5'>Fifth Option</option>
      <option value='6'>Sixth Option</option>
      <option value='7'>Seventh Option</option>
      <option value='8'>Eighth Option</option>
      <option value='9'>Ninth Option</option>
      <option value='10'>Tenth Option</option>
    </select>

Когда пользователь выбирает

First option
Second option
Third option

Теперь он достигает максимального предела выбора 3. Если он нажмет на другой вариант, например Десятый вариант, мне нужно удалить Третий вариант и выбрать Десятый вариант.

Для этого я попробовал это, но понятия не имею, как я могу достичь своей цели

<script type="text/javascript">
    google.load("jquery", "1");

    $(document).ready(function() {
        //alert("1111");
      var last_valid_selection = null;

      $('#testbox').change(function(event) {
        if ($(this).val().length > 2) {
          alert('You can only choose 2!');
          $(this).val(last_valid_selection);
        } else {
          last_valid_selection = $(this).val();
          latest_value = $("option:selected:last",this).val()
          alert(latest_value);
        }
      });

    });
    </script>

Пожалуйста, предложите какую-нибудь идею или решение.


person Jalpesh Patel    schedule 18.07.2013    source источник


Ответы (3)


var lastOpt;
$('#testbox option').click(function () {
    lastOpt = $(this).index();
});
$('#testbox').change(function () {
    if ($('option:selected', this).length > 3) {
        $(' option:eq(' + lastOpt + ')', this).removeAttr('selected');
    }
});

JSFIDDLE

person DevlshOne    schedule 18.07.2013

Это работает довольно хорошо:

var lastSelected;

$("#testbox").change(function() {
    var countSelected = $(this).find("option:selected").length;

    if (countSelected > 3) {
        $(this).find("option[value='" + lastSelected + "']").removeAttr("selected");
    }
});

$("#testbox option").click(function() {
    lastSelected = this.value;
});

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

Демонстрация: http://jsfiddle.net/JAysB/1/

person tymeJV    schedule 18.07.2013
comment
Это не работает, если порядок выбора не является числовым последовательным. Например, выберите Восьмой, Девятый, Второй, Первый или Третий, Седьмой, Первый, Восьмой. - person DevlshOne; 18.07.2013
comment
Я просто подумал, что ОП хочет, чтобы вариант, который был ниже четвертого, стал невыбранным. - person tymeJV; 18.07.2013
comment
Если я правильно понял, он хочет, чтобы четвертый выбор заменил третий выбор, независимо от числового значения. - person DevlshOne; 18.07.2013
comment
@DevlshOne - Легко исправить, дай мне минутку :D - person tymeJV; 18.07.2013
comment
На самом деле, может быть немного сложнее, чем я думал, this.value захватывает самый ранний выбранный вариант, а не текущий выбранный... хм - person tymeJV; 18.07.2013
comment
@DevlshOne - Понятно, обновляю ответ. - person tymeJV; 18.07.2013
comment
Что делать, если два варианта имеют одинаковое значение? :) Я разработал свой, чтобы он был более защищенным от дурака. - person DevlshOne; 18.07.2013

Что ж, мне не нравится jQuery, поэтому я разработал его (fiddle), но в чистый, ванильный, легко читаемый JavaScript:

document.getElementById('testbox').selopt=new Array();
document.getElementById('testbox').onchange=function(){
    for(i=0; i<this.childNodes.length; i++)
        if(this.childNodes[i].tagName!='OPTION')
            continue;
        else{
            if(this.childNodes[i].selected &&
               this.selopt.indexOf(this.childNodes[i])<0)
                this.selopt.push(this.childNodes[i]);
        }
    if(this.selopt.length==4)
        this.selopt.splice(2,1)[0].selected=false;
}

P. S. Никаких глобальных переменных! :П

person dbanet    schedule 18.07.2013
comment
И, к вашему сведению, его можно легко изменить, чтобы отменить выбор не последнего выбранного, а наименее выбранного элемента: selopt.splice(2,1)[0].selected=false; -> selopt.splice(0,1)[0].selected=false;. - person dbanet; 18.07.2013
comment
Люблю это решение, +1 за Pure JS: D - person tymeJV; 18.07.2013