开发者

How can I get the last selected value in a ListBox with jQuery?

I have a listbox and I must limit its selection up to 5 items. If a 6th item is selected, I want to "deselect" it.

But, I'm having some pr开发者_开发知识库oblems on finding the last selected item and "deselect" it. And the last item selected it's necessary the $("#mySelect option:last")...

How can I get the selected item of a listbox??

Thanks!!!


This will do it, although there is a brief "flash" of selection (you might want ot have a <span> show up underneath the <select> to say something like Maximum selection reached).

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

I'll leave it as an exercise for you to get it working with keyboard selectivity too.

Here's a Working Demo

EDIT:

Ok, I'll admit that this is not the first time that I have been stung by also not testing an answer in IE too (there seem to be a lot of problems with <select> elements in IE), but here is a flexible solution that I have tested in IE 6 and Firefox 3.5.3 and it works in both. I've wrapped it in a plugin, in case you need this on more than one page

(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);

Then to use, it's simply

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

passing in the maximum number of items that can be selected. This works with key and mouse selections in both IE and Firefox versions tested although interestingly, IE 6 doesn't appear to support the Ctrl hold and Space to select multiple items, but does allow holding Shift to select a number of contiguous items. The plugin does limit this to the passed in max.

Here's a Working Demo


the :last part of your selector will select the "last" physical item in the select list (it doesn't relate to whether it is selected or not).

AFAIK, you need to iterate over the options, and test if each is selected (to get your count) or use the :selected pseudo selector.

//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);
}

UPDATE:

Wow, this was more complex than I thought!... below is a tested example that works... it could likely be cleaner, but I'll leave that to others to hack ;-)

<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>

sample 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>


This will basically listen for any options that get clicked. If one gets clicked, the script checks to see how many total options are selected (including the one just clicked on). If the number of selected options is more than 5, the most-recently-clicked item will become "deselected".

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

If you'd like to let people know why their option just became deselected, you can do this:

$("#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...');
    }
});

Hope that works out for you. This code was inspired by peirix.


Do you have to get the last one? Can't you just count how many are selected and then prevent further selections?

This function will check that the given SELECT element contains fewer than 'maximum' selected options.

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;
}

To call it directly from a form's onsubmit event, you could do:

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

You could jQueryify it, but this should get you started. Taken from http://bytes.com/topic/javascript/answers/93760-please-help-limit-number-selections-multiple-select-list-box#post316514


This should do the trick:

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

A small re-write of Cory Larson's answer:

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

This will just not let the user check another option when the maximum number has been reached. And you could probably write out something to the user explaining that the maximum number has been reached.


This seems to work on a little test page I did:

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


$('#mySelect option:selected').length; doesn't seem to work on IE. Works well in Chrome though.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜