joe witt
joe witt

Reputation: 69

Use jQuery to append <li> items from one <ul> to new <ul>

I have a problem when appending one set of li items from one ul to new ul.
When I move one it is fine, but when I move two my code duplicates them.

So when I move A & B I get A A B B in the new ul instead of A B and I cannot see why.

Here is my JavaScript:

function moveItems(origin, destination){
  var highlighted = document.querySelectorAll("#leftlist .highlight");
  highlighted.forEach(function(){
    $(origin).clone(true).appendTo(destination);
    $("#leftlist .highlight").remove();

  }
  $("#moveright").click(function(){
    moveItems(".highlight", "#rightlist");
  });

Here is my HTML:

    <ul id="leftlist" class="list-group list-group-flush">
      <li class="list-group-item">a item</li>
      <li class="list-group-item">b item</li>
      <li class="list-group-item">c item</li>
      <li class="list-group-item">d item</li>
      <li class="list-group-item">e item</li>
      <li class="list-group-item">f item</li>
      <li class="list-group-item">g item</li>
      <li class="list-group-item">h item</li>
      <li class="list-group-item">i item</li>
      <li class="list-group-item">j item</li>
    </ul>
  </div>
</div>
<ul id="rightlist" class="list-group list-group-flush">
</ul>

Upvotes: 1

Views: 197

Answers (3)

Alnitak
Alnitak

Reputation: 339917

Your code logic is far too complicated - there's no need to .clone() and .remove() at all.

Appending an already attached element to a new location will automatically detach it from its existing parent.

Also, jQuery's .appendTo method will quite happily move several elements at once, avoiding the need for a .forEach call:

$('#moveright').on('click', function() {
  $('#leftlist .highlight').appendTo('#rightlist').removeClass('highlight');
});

$('#moveright').on('click', function() {
  $('#leftlist .highlight').appendTo('#rightlist').removeClass('highlight');
});
.highlight {
  color: red;
}

ul {
  display: inline-block;
  vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="moveright">
Move To Right
</button>
<div><span></span>
  <ul id="leftlist" class="list-group list-group-flush">
    <li class="list-group-item">a item</li>
    <li class="list-group-item">b item</li>
    <li class="list-group-item highlight">c item</li>
    <li class="list-group-item">d item</li>
    <li class="list-group-item">e item</li>
    <li class="list-group-item highlight">f item</li>
    <li class="list-group-item">g item</li>
    <li class="list-group-item">h item</li>
    <li class="list-group-item">i item</li>
    <li class="list-group-item">j item</li>
  </ul>
  </span><span>
<ul id="rightlist" class="list-group list-group-flush">
</ul></span>

Upvotes: 1

Someone3
Someone3

Reputation: 81

In your code, look at the part inside forEach statement. Inside the loop you're selecting all the "origin" and cloning those. This is why you see duplicate copies.

I modified this part and add some functionalities that would be similar to what you are going to implement.

leftlist is bordered by red line and rightlist is bordered by blue line.

Click one or more items in the leftlist(items in the red box) and press the button. You can see that those selected items are moved to rightlist(to the blue box).

function hightlightOnClick (e) {
  $(e.currentTarget).addClass("highlight");
}

function moveItems (origin, destination) {  
  $(origin).clone(true).appendTo(destination);
  $("#leftlist .highlight").remove();
  
  // we don't want items in the rightbox to respond to click event any more.
  $(".highlight").off("click", hightlightOnClick);  

  // detaches highlight classes from every item.
  $(".highlight").removeClass("highlight");
}

$("#leftlist .list-group-item").click(hightlightOnClick);

$("#moveright").click(function () {		
	moveItems("#leftlist .highlight", "#rightlist");
});
.highlight {
  color: red;
}

#leftlist {
  border: 1px solid red;
  min-height: 100px;
}

#rightlist {
  border: 1px solid blue;
  min-height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="moveright">
Move To Right
</button>
<ul id="leftlist" class="list-group list-group-flush">
  <li class="list-group-item">a item</li>
  <li class="list-group-item">b item</li>
  <li class="list-group-item">c item</li>
  <li class="list-group-item">d item</li>
  <li class="list-group-item">e item</li>
  <li class="list-group-item">f item</li>
  <li class="list-group-item">g item</li>
  <li class="list-group-item">h item</li>
  <li class="list-group-item">i item</li>
  <li class="list-group-item">j item</li>
</ul>

<ul id="rightlist" class="list-group list-group-flush">
</ul>

Upvotes: 0

Chirag Ravindra
Chirag Ravindra

Reputation: 4830

This might be what you are looking for:

function transferListItems($source,$destination){
  var $highlighted = $source.find('.highlight');
  $highlighted.clone(true).appendTo($destination);
}

$('#transfer').click(function(){
  transferListItems($('#list1'),$('#list2'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h5>List 1</h5>
<ul id="list1">
  <li class="highlight">One</li>
  <li>Two</li>
  <li class="highlight">Three</li>
  <li>Four</li>
  <li class="highlight">Five</li>
</ul>
<button id="transfer">Transfer</button>
<h5>List 2</h5>
<ul id="list2">
  <li>Six</li>
  <li>Seven</li>
  <li>Eight</li>
  <li>Nine</li>
  <li>Ten</li>
</ul>

Upvotes: 1

Related Questions