Gnesh
Gnesh

Reputation: 45

Adding and removing items from list to list jquery

I need to add and remove items from one list to another on click. Here is fiddle

Idea is that on "Add" button click <li>Item</li> goes to second list on first place and that on "Remove" button click <li>Item</li> goes to first list on first place.

I want option that I can click several times on buttons and move items from list to list.

Html:

<ul id="listOne">
    <li>Item 1 <button type="submit" id="add">Add</button></li>
    <li>Item 2 <button type="submit" id="add">Add</button></li>
    <li>Item 3 <button type="submit" id="add">Add</button></li>
</ul>

<ul id="listTwo">
    <li>Item 4 <button type="submit" id="remove">Remove</button></li>
    <li>Item 5 <button type="submit" id="remove">Remove</button></li>
    <li>Item 6 <button type="submit" id="remove">Remove</button></li>
</ul>

Jquery: (I have low-knowledge)

function moveItems(origin, dest) {
  $(origin).find('li').appendTo(dest);
}
$('#add').click(function () {
    moveItems('#listOne', '#listTwo');
});

$('#remove').on('click', function () {
    moveItems('#listTwo', '#listOne');
});

Upvotes: 0

Views: 3033

Answers (2)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

You had duplicate IDs which will not work. Most browsers can only see the first instance of an ID as they use a fast lookup table with only one element per key stored. Use classes instead or look for another pattern to match like "LI button" etc

You can change it to move the closest LI to the button clicked.

Using delegated events means that dynamic additions are no problem. They listen at an ancestor element for the click event`.

function moveItems(origin, dest) {
  $(origin).closest("li").appendTo(dest);
}
$(document).on('click', '.add', function () {
    moveItems(this, '#listTwo');
});

$(document).on('click', '.remove', function () {
    moveItems(this, '#listOne');
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/r7j3odyy/4/

Note: your current logic only allows the items to be moved one from a list to the other list once. You will need to rework it if you want it to be able to move them back (with appropriate button text).

You could therefore do something like this:

function moveItems(origin, dest, text) {
  $(origin).text(text).closest("li").appendTo(dest);
}
$('#listOne').on('click', 'button', function () {
    moveItems(this, '#listTwo', 'Remove');
});

$('#listTwo').on('click', 'button', function () {
    moveItems(this, '#listOne', 'Add');
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/r7j3odyy/6/

This version uses delegated events on the lists, that match the button clicked at event time. The code always supplies the new button text (although there are many way to do this).

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337560

You can simplify the logic by appending the li element to the ul which it currently not a child of. You can also set the text of the button by reading a data attribute on the parent list you're appending to. Finally note that having the same id repeated in the scope of a document is invalid, and you should use classes to group elements instead. Try this:

<ul id="listOne" class="list" data-button-text="Add">
    <li>Item 1
        <button type="button">Add</button>
    </li>
    <li>Item 2
        <button type="button">Add</button>
    </li>
    <li>Item 3
        <button type="button">Add</button>
    </li>
</ul>

<ul id="listTwo" class="list" data-button-text="Remove">
    <li>Item 4
        <button type="button">Remove</button>
    </li>
    <li>Item 5
        <button type="button">Remove</button>
    </li>
    <li>Item 6
        <button type="button">Remove</button>
    </li>
</ul>
$('.list button').click(function() {
    var $list = $(this).closest('.list');
    var $targetList = $('.list').not($list)
    $(this).closest('li').appendTo($targetList);
    $(this).text($targetList.data('button-text'));
})

Example fiddle

Note that this same event handler works for both lists using a shared class.

Upvotes: 1

Related Questions