开发者

Detaching/appending select options with jquery

开发者 https://www.devze.com 2023-01-10 06:53 出处:网络
I\'m trying to set up a form with multiple dropdown lists, that will allow visitors to rank the list items.Sample form:

I'm trying to set up a form with multiple dropdown lists, that will allow visitors to rank the list items. Sample form:

<form action="" name="rankem">
  <select name="rank1" id="rank1">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
    <option value="option4">Option 4</option>
    <option value="option5">Option 5</option>
  </select>
  <select name="rank2" id="rank2">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
    <option value="option4">Option 4</option>
    <option value="option5">Option 5</option>
  </select>
  <select name="rank3" id="rank3">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
    <option value="option4">Option 4</option>
    <option value="option5">Option 5</option>
  </select>
</form>

As options are selected, I'd like to remove (detach) them from each dropdown.

The actual lists I have contain a lot more options so that people can rank the top 10 out of 32 options, so imagine the sample code above with 10 dropdowns with 32 options each.

If somebody selects 'option2' from select#rank1, I'd like option2 removed from subsequent dropdowns, and so on. If they go back to select#rank1, and change their selection to 'option4', 'option2' will need to be appended to all the dropdowns.

I've taken a look at .detach() and .append() but don't really know what I'm doing.

$("option[value="+$(this).val()+"]").detach();

I tried the above to start but it just removes the option from all dropdowns. I'm a JS/jquery noob开发者_高级运维 so any help or links in the right direction is appreciated. Thanks!


Try this line instead (for detaching the elements):

$("select:not(#"+$(this).parent().attr('id')+") option[value="+$(this).val()+"]").detach();


Have you considered enabling/disabling vs. attaching and detaching?

I'm not as quick with the code (working with a broken arm here), but the general algorithm would be this:

$(function() {
    // Respond to any value change.
    $('select').change(function() {
        var val = $(this).val();

        // Enable/disable depending on the selection.
        // Removed the each loop after seeing You's answer (+1). He has a better solution.
        $('select:not(#' + $(this).parent().id + ') option[value=' + val + ']').removeAttr('disabled');
        $('select(#' + $(this).parent().id + ') option[value=' + val + ']').attr('disabled', 'disabled');
    });
});

This has not been tested and I'm still very much learning jQuery (so I'll take feedback).


This will detach the option from each of the selects which has a rank number larger than the current select and will put it into a javascript object where the key is the parent select's id. Each time a select is changed, only its subsequent selects will be affected, not the ones higher in the chain. So if you select from rank2, it will be detached from rank3, but not from rank1. Reading your question again, I'm not certain that this is the funcationality you're looking for, but here it is anyway.

function rankIndex(id){
  return id.substr(4);
}

$(document).ready(function(){

  var removed = {};
  $('select').each(function(){
    // define each select's bin for removed elements as an object
    removed[$(this).attr('id')] = {};
  });

  $('select').change(function(){

    var $this = $(this),
        $thisId = $this.attr('id'),
        $thisRankIndex = rankIndex($thisId);

      // add each element back to selects further in the chain
    $.each(removed[$thisId], function(selectId, option){
      $('#'+selectId).append(option);
    });

    // filter the selects that are further in the chain 
    // and detach the options into the removed bin
    $('select').filter(function(i){
      return rankIndex($(this).attr('id')) > $thisRankIndex;
    }).find('option[value='+$this.val()+']').each(function(){
      removed[$thisId][$(this).closest('select').attr('id')] = $(this).detach();
    });

  });

});

Some key things to read up on to further understand what I did are the javascript object and some jQuery functions: filter(), each() (as well as jQuery.each()) and find(). Anyone, if you can, feel free to refactor this as it's a bit verbose. Hope this helps!


this works for me, but I don't know how to re-attached using the drop down menu.

$("#name1").children("optgroup[label='Test:']").removeAttr('disabled').siblings().detach("optgroup");
0

精彩评论

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

关注公众号