8

I've created this fiddle, it allows the user to click on either art or video, dynamically populating the the second listbox with the list associated with those selections. There are two buttons, one to add the selection to the box, the other which removes the selection.

What I would like to do is prevent the user from adding some that has already been added. The value of the options will all be Guids. Bonus points if you can modify the fiddle to use Guid instead of ints.

I've tried this:

$.each($("#SelectBox2 option:selected"), function (i, ob) {
    if (i == $(this).val()) {

    } else {
        inHTML += '<option value="' + $(this).val() + '">' + $(this).text() + '</option>';
    }
});

I would like to enable the user to remove the selected items from the list.

Thanks,

UPDATE Just letting you guys know what the solution is that I came up with, I got the bonus points because i added GUID to it in a really smart way :) fiddle, I also tidied up the html to make it look nice and neat.

MAJOR UPDATE A massive thanks to everyone who has contributed to this question, I have taken on board everyones comments and fiddles and have generated this >> fiddle <<

Callum Linington
  • 14,213
  • 12
  • 75
  • 154
  • 1
    Can you not simply remove the selected item from the array when clicking add. When clicking "back" just add it in again. – Dave Hogan Mar 21 '13 at 13:42
  • but what category do you add it into? you will never know unless you use a complex object for the value instead of just a guid – Callum Linington Mar 21 '13 at 13:45
  • @DaveHogan please see my latest fiddle in the question, take on board what you said about removing from an array and putting it back, in fact I went a step further, and just said whether to display it or not :) – Callum Linington Mar 22 '13 at 12:01

9 Answers9

12

I think you would want to do something like this: Check if value is in select list with JQuery.

Modifying your code to something like this should work:

$("#SelectBox2 option:selected").each(function () {
    var optionVal = $(this).val();
    var exists = false;
    $('#SelectedItems option').each(function(){
        if (this.value == optionVal) {
            exists = true;
        }
    });

    if(!exists) {
        inHTML += '<option value="' + $(this).val() + '">' + $(this).text() + '</option>';
    }
});

Removing selected items would look like this:

$('#remove').click(function () {
    $("#SelectedItems option:selected").remove();
});
Community
  • 1
  • 1
OptimizedQuery
  • 1,262
  • 11
  • 21
3

If you want to dynamically add and delete rows seamlessly try this way

http://jsfiddle.net/WX4Nw/

Adding a pointer to the selecteditems list as a data attrib to the root item key will help you control so that you can easily manage add/remove.

Snippet from fiddle:-

$('#SelectBox').change(function () {
        var str = "",
            inHTML = "",
            key = $('#SelectBox').val(),
            items;
        items = $(this).val() == 'art' ? artItems : vidItems;
        $.each(items, function (i, ob) {
            if($('#SelectedItems option[value="' + i + '"][data-key="' + key + '"]').length == 0)
                inHTML += '<option value="' + i + '" data-key="' + key + '">' + ob + '</option>';
        });
        $("#SelectBox2").empty().append(inHTML);
    });

 $('#add').click(function () {
        var itemsToAdd = [];
        $("#SelectBox2 option:selected").each(function () {
            var optionVal = $(this).val();
            var key = $(this).data('key');
            if ($('#SelectedItems option[value="' + optionVal + '"][data-key="' + key + '"]').length == 0)                     {
                itemsToAdd.push($(this).removeAttr('selected'));
            }
        });
        $("#SelectedItems").append(itemsToAdd);
    });
PSL
  • 123,204
  • 21
  • 253
  • 243
2

Try:

$(function () {
    var artItems = ["Art 1", "Art 2", "Art 3", "Art 4", "Art 5", "Art 6"];
    var vidItems = ["Video 1", "Video 2", "Video 3", "Video 4", "Video 5", "Video 6"];
    $('#SelectBox').change(function () {
        var str = "",
            inHTML = "",
            items;
        items = $(this).val() == 'art' ? artItems : vidItems;
        $.each(items, function (i, ob) {
            inHTML += '<option value="' + i + '">' + ob + '</option>';
        });
        $("#SelectBox2").empty().append(inHTML);
    });

    $('#SelectBox2').change(function () {
        $("#selectedValues").text($(this).val() + ';' + $("#SelectBox").val());
        $('#hidden1').val($(this).val());
    });

    $('#add').click(function () {
        inHTML = "";
        $("#SelectBox2 option:selected").each(function () {
            if ($("#SelectedItems option[value=" + $(this).val() + "]").length == 0) {
                inHTML += '<option value="' + $(this).val() + '">' + $(this).text() + '</option>';
            }
        });
        $("#SelectedItems").append(inHTML);
    });

    $('#remove').click(function () {
        $('#SelectedItems option:selected').remove();
    });
});

Fiddle here

darshanags
  • 2,519
  • 1
  • 13
  • 19
1

Ok to fix your add function just add the following if condition::

if($("#SelectedItems option:contains("+$(this).text()+")").length<=0)                
   inHTML += '<option value="' + $(this).text() + '">' + $(this).text() + '</option>';

to remove items::

$('#remove').click(function () {
    $("#SelectedItems option:selected").each(function () {
       $(this).remove();
    });
});

here is the example after i updated it jsfiddle

ebram khalil
  • 8,252
  • 7
  • 42
  • 60
1

Have a look at this solution:- Using the data attribute to keep track of the items parent list selector and avoiding a loop with the help of this selector and data attribute.

http://jsfiddle.net/pramodsankar007/rMpBv/

 $('#add').click(function () {
        var itemsToAdd = [];
        $("#SelectBox2 option:selected").each(function () {
            var optionVal = $(this).val();
            var key = $(this).data('key');
           if($('#SelectedItems option[value="' + optionVal + '"][data-key="' + key +'"]').length == 0)
           {
                 itemsToAdd.push($(this).removeAttr('selected').clone(true));
           }
        });
        $("#SelectedItems").append(itemsToAdd);
    });
});
PSL
  • 123,204
  • 21
  • 253
  • 243
  • Thats cool, all it needs now is to implement the transfer of the selected item from the 2 listbox to the selected item listbox, and then back again – Callum Linington Mar 21 '13 at 15:18
  • yes that will be easliy possible since you have the data-key in your selected items list, you can remove them before appending in your change event. And remove clone while adding. – PSL Mar 21 '13 at 15:40
  • its a little confusing to me, so if you demonstrate that would be excellent – Callum Linington Mar 21 '13 at 16:26
0

SEE THE LINK

write if condition as

 if($("#SelectedItems option:contains("+$(this).val()+")").length<=0)                
   inHTML += '<option value="' + $(this).val() + '">' + $(this).text() + '</option>';

Then add

$('#remove').click(function(){

  $('#SelectedItems  :selected').each(function(i, selected) {
    $(this).remove();
});
});
PSR
  • 39,804
  • 41
  • 111
  • 151
0

try this if you want to prevent the user from adding an option that already exists

  $("#SelectBox2 option:selected").each(function () {
            if(  $("#SelectedItems option[value='"+$(this).val()+"']").length <=0)
            inHTML += '<option value="' + $(this).val() + '">' + $(this).text() + '</option>';

        })

http://jsfiddle.net/j2ctG/8/

Updated the fiddle for remove also.

DVM
  • 1,229
  • 3
  • 16
  • 22
0

Get existing list of options, check if those you're adding already exist, if not, add them:

http://jsfiddle.net/bZXs4/

$('#add').click(function () {
     var inHTML = "";
     var $opts = $('#SelectedItems').find('option'); 

     $("#SelectBox2 option:selected").each(function () {
         var allowItemToBeAdded = true;
         var selectedVal = $(this).val();
         $opts.each(function(index, element){
             if($(this).val() === selectedVal){
                 allowItemToBeAdded = false;
             }
         });

         if(allowItemToBeAdded){
             inHTML += '<option value="' + selectedVal + '">' + $(this).text() + '</option>';
         }
     });

     if(inHTML !== ''){
         $("#SelectedItems").append(inHTML);
     }
 });
lee_mcmullen
  • 2,801
  • 32
  • 39
0

Really Clean and Simple (works great and only a few lines):

        $("#icon_move_right").click(function(){
            $("#available_groups option:selected").each(function(){ 
                available_group = $(this).val();
                $("#assigned_groups").append("<option value='" + available_group + "'>" + available_group + "</option>");
            });
            $("#available_groups option:selected").remove()
        });

        $("#icon_move_left").click(function(){
            $("#assigned_groups option:selected").each(function(){ 
                assigned_group = $(this).val();
                $("#available_groups").append("<option value='" + assigned_group + "'>" + assigned_group + "</option>");
            });
            $("#assigned_groups option:selected").remove()
        });

        $("#icon_move_right_all").click(function(){
            $("#available_groups option").each(function(){ 
                available_group = $(this).val();
                $("#assigned_groups").append("<option value='" + available_group + "'>" + available_group + "</option>");
            });
            $("#available_groups option").remove()
        });

        $("#icon_move_left_all").click(function(){
            $("#assigned_groups option").each(function(){ 
                assigned_group = $(this).val();
                $("#available_groups").append("<option value='" + assigned_group + "'>" + assigned_group + "</option>");
            });
            $("#assigned_groups option").remove()
        });
gunslingor
  • 1,358
  • 12
  • 34