【问题标题】:How can I get the last selected value in a ListBox with jQuery?如何使用 jQuery 获取 ListBox 中最后选择的值?
【发布时间】:2009-10-21 13:14:40
【问题描述】:

我有一个列表框,我必须将其选择限制为最多 5 个项目。如果选择了第 6 项,我想“取消选择”它。

但是,我在查找最后一个选定项目并“取消选择”它时遇到了一些问题。最后选择的项目是 $("#mySelect option:last")...

如何获取列表框的选中项??

谢谢!!!

【问题讨论】:

  • 这确实是一个比乍看起来更复杂的问题。这实际上是一个很好的问题。谢谢你挑战我的大脑。

标签: jquery listbox


【解决方案1】:

这会做到这一点,尽管有一个短暂的“闪光”选择(您可能希望<span> 出现在<select> 下方,以表示已达到最大选择)。

$('#mySelect').click(function(e) {
  if ($('option:selected',this).length > 5) {    
     $(e.target).removeAttr('selected');  
  }
});

我将把它作为练习留给您,让您也可以使用键盘选择性。

这是Working Demo

编辑:

好吧,我承认这不是我第一次因为没有在 IE 中测试答案而被刺痛(IE 中的<select> 元素似乎有很多问题),但在这里是我在 IE 6 和 Firefox 3.5.3 中测试过的一个灵活的解决方案,它适用于这两个版本。我已经将它包装在一个插件中,以防你需要在多个页面上使用它

(function($) {

$.fn.maxLimitSelect = function(max) {

  if (!max || !/^\d+$/.test(max)) return this;

  return this.each(function() {

    $(this).bind("click change keypress",{ max: max },function(event) {

      var options = $('option', this);
      var max = event.data.max;
      var selected = $('option:selected', this);
      var indexes;

      if (selected.length === max) {  
       indexes = $.map(options, function(e, i) { 
                   if(e.selected) return i; 
                 }); 
       $.data(this, "indexes", indexes);
      }
      else if (selected.length > max) {
       indexes = $.data(this, "indexes");
       options
         .removeAttr('selected')
         .each(function() { 
           var $this = $(this);
           if ($.inArray($this.prevAll().length, indexes) !== -1) {  
             $this.attr('selected','selected');
           }
         });   
      } 
    });
  });
}

})(jQuery);

然后使用,很简单

$('#mySelect').maxLimitSelect(5);

传入可以选择的最大项目数。这适用于测试的 IE 和 Firefox 版本中的键和鼠标选择,但有趣的是,IE 6 似乎不支持 Ctrl 按住和 Space 来选择多个项目,但是确实允许按住 Shift 来选择一些连续的项目。该插件确实将其限制为传入的最大值。

这是一个Working Demo

【讨论】:

  • 哇...我们在 3 秒内发布了或多或少完全相同的解决方案。
  • “结合我们的力量,我们是...... jQuery 船长!”
  • 大声笑...我喜欢那个节目。必须结合什么魔法戒指才能成为 jQuery 队长?
  • 我的原始代码中有一些错误。他们是通过查看你的来修复的。哦,好吧……至少我们中的一个 jQuery 船长。
  • 选择器环、插件环、实用程序环、事件环、ajax 环和可能回调环。当然,选择器环是最强大的,但它并不真正属于 jQuery 船长,他是从 Super Sizzle Man 那里借来的 :)
【解决方案2】:

选择器的 :last 部分将选择选择列表中的“最后一个”物理项(与是否选择无关)。

AFAIK,您需要遍历选项,并测试每个选项是否被选中(以获取您的计数)或使用 :selected 伪选择器。

//Or as noted by @peirix you can try to get it with :selected.
//Note that this will just clear the last (by rendered order) selection...
//not the "last" option that was selected.

if($("#mySelect option:selected").size() >= 6){
  $("#mySelect option:selected:last").attr('selected', null);
}

更新:

哇,这比我想象的要复杂!...下面是一个经过测试的有效示例...它可能更干净,但我会把它留给其他人来破解 ;-)

<script>
  $('#mySelect').bind('change', function(){
    if($("#mySelect option:selected").size() == 5){
      //5 picked, (re)store them...
      var sel = [];
      $("#mySelect option").each(function(i){
        if($(this).attr('selected')){
          sel[i] = true;
        } else {
          sel[i] = false;
        }
      });
      $(this).data('selectedIndexes',sel);
    } else if($("#mySelect option:selected").size() >= 6){
      //too many reset to orig...
      $("#mySelect option").each(function(i){
        if($(this).parent().data('selectedIndexes')[i]){
          $(this).attr('selected', 'selected');
        } else {
          $(this).attr('selected', '');
        }
      });
    }
  });
</script>

示例 HTML:

<select id="mySelect" multiple="multiple" size="12">
  <option value="a">aaaaaaaaaaaa</option>
  <option value="b">bbbbbbbbbbbb</option>
  <option value="c">cccccccccccc</option>
  <option value="d">dddddddddddd</option>
  <option value="e">eeeeeeeeeeee</option>
  <option value="f">ffffffffffff</option>
  <option value="g">gggggggggggg</option>
  <option value="h">hhhhhhhhhhhh</option>
  <option value="i">iiiiiiiiiiii</option>
  <option value="j">jjjjjjjjjjjj</option>
  <option value="k">kkkkkkkkkkkk</option>
  <option value="l">llllllllllll</option>
</select>

【讨论】:

  • $("#mySelect option:selected:last").val(); --> 这不会得到最后一个选择的项目,而是最后一个物理选择的项目。这个我已经试过了,嘿嘿这是第一个想到的,但它也不起作用
  • @AndreMiranda - 正确。如果希望删除最后的物理选择,则需要挂钩 onchange 事件,并保留对先前选择的选项的某种记录。
  • 感谢您的回答 scunliffe.. 我会表现出一些警觉...现在我的生活会更轻松...呵呵
  • 是的,我尝试了绑定到 onchange 的启发式尝试,并在选择元素上使用 .data() 存储选择...但它似乎比应有的复杂得多。稍后当我让它工作时我会发布代码,但我没有时间 ATM 来完全调试它。 :-(
【解决方案3】:

这基本上会监听任何被点击的选项。如果一个被点击,脚本会检查总共有多少选项被选中(包括刚刚点击的那个)。如果选择的选项数量超过 5 个,则最近点击的项目将变为“取消选择”。

$("#mySelect").click(function() {
    var num_selected = $('#mySelect option:selected').length;
    if(num_selected > 5) {
        $(e.target).removeAttr('selected');
    }
});

如果您想让人们知道他们的选项刚刚被取消选中的原因,您可以这样做:

$("#mySelect").click(function(e) {
    var num_selected = $('#mySelect option:selected').length;
    if(num_selected > 5) {
        $(e.target).removeAttr('selected');
        alert('You are limited to 5 options at a time...');
    }
});

希望对你有用。这段代码的灵感来自 peirix。

【讨论】:

    【解决方案4】:

    你必须得到最后一个吗?你不能只计算有多少被选中然后阻止进一步的选择吗?

    此函数将检查给定的 SELECT 元素是否包含少于 “最大”选择的选项。

    function checkLimits( list, maximum ) {
        var options = list.options;
        var size = options.length;
        var numSelected = 0;
    
        for( var i = 0; i < size; ++i ) {
            if( options[ i ].selected ) ++numSelected;
        }
        if( numSelected > maximum ) {
            alert( 'You have selected more than ' + maximum + ' options.\n' +
                'Please deselect ' + ( numSelected - maximum ) + ' option(s) then
                try again.' );
            return false;
        }
        return true;
    }
    

    要直接从表单的 onsubmit 事件调用它,您可以这样做:

    <select ... onsubmit="return checkLimits(this.listName, 2)">
    

    您可以对其进行 jQueryify 处理,但这应该可以帮助您入门。取自http://bytes.com/topic/javascript/answers/93760-please-help-limit-number-selections-multiple-select-list-box#post316514

    【讨论】:

    • 嗨,科里!我已经可以计算选定的选项,但我避免发出一些警告说用户应该取消选择 xx 选项。我试图通过取消选择最后一个选定的项目(不是最后一个选定的物理项目)来完成更自动化的事情
    • 我想我还是会发出警报......这比让一些 jquery 的头脑烧毁更实用
    【解决方案5】:

    这应该可以解决问题:

    $("#mySelect option:checked:last").val(); //or not
    

    对 Cory Larson 的回答稍作改写:

    $("#mySelect option").mousedown(function() {
       if ($("#mySelect :checked").length > 5) {
          return false;
       }
       return true;
    });
    

    当达到最大数量时,这不会让用户检查另一个选项。您可能会向用户写一些内容,说明已达到最大数量。

    【讨论】:

      【解决方案6】:

      这似乎在我做的一个小测试页面上工作:

      $('#mySelect option:selected:gt(4)').removeAttr('selected')
      

      【讨论】:

        【解决方案7】:

        $('#mySelect option:selected').length; 似乎不适用于 IE。不过在 Chrome 中运行良好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多