Reputation: 45
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
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
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'));
})
Note that this same event handler works for both lists using a shared class.
Upvotes: 1