Reputation: 155
I'm using jQuery UI draggable function. The full code is more complicated so I just created a simple test scenario to troubleshoot the bug here: Fiddle
There are two sections "top" and "content". There is a yellow button in the "top" section which is draggable.
When I drag the yellow button at the top and drop it to the gray "content" area, it will show this in the gray content:
Yellow Box 1 Item 1 Item 2 Item 3 Add New Item (button)
When I click on the "Add New Item" button, "Item 4" text will be added under Item 3 text. When I click on the "Add New Item" button again, "Item 5" text will be added under Item 4 text and so on...
It is work as expected. However, the problem arises when I do another dragging of the yellow button at the top and drop it in the gray area, which I will have something like this:
Yellow Box 1 Item 1 Item 2 Item 3 Item 4 Item 5 Add New Item
Yellow Box 2 Item 1 Item 2 Item 3 Add New Item
So when I go back and every time I click on the Add New Item button under Yellow Box 1, it adds TWO new items for every click instead of just one (it will add Item 6 and Item 7 under Item 5) which is not what I wanted.
I tried to cancel event bubbling and some other things but somehow it didn't work. When I isolated the same scenario without using the jQuery UI draggable function, then it behaves as expect. So I guess the bug is related to how I implemented the draggable function. Thank you for your help.
Here is the code:
$(function() {
$('#content').sortable({
placeholder: 'ui-state-highlight'
});
$(".top-icon").draggable({
connectToSortable: '#content',
helper: myHelper,
stop: handleDragStop
});
function myHelper(event) {
return $(this).clone();
}
var i = 1;
function handleDragStop(event, ui) {
var current_text = '<div class="color-box"><b>Yellow Box ' + i + '</b>'
+ '<div class="yellow-content">'
+ '<div class="item">Item 1</div>'
+ '<div class="item">Item 2</div>'
+ '<div class="item">Item 3</div>'
+ '<div class="add-item">Add New Item</div>'
+ '</div>'
+ '</div>';
$('#content .top-icon').after(current_text);
i++;
var $new_insert_item = $('#content .top-icon').next();
$('#content .top-icon').remove(); // remove the clone .top-icon inside #content
console.log('hi');
// when click on Add New Item button
$('.color-box').on('click', '.add-item', function() {
var $this = $(this);
var item_count = $this.siblings('.item').length + 1;
console.log (item_count);
var str_item = '';
str_item = '<div class="item">Item ' + item_count + '</div>';
$(str_item).insertBefore($this);
});
}
// end of handleDragStop
});
Upvotes: 3
Views: 352
Reputation: 123739
Issue is that, binding the click event inside the handleDragStop
binds events to the existing already dragged item as well so the existing dragged items gets the click event added up by 1 during each drag. So instead bind the event outside and have the event bound to #content
(if this is the container that exist in DOM even before the first drag) to be delegated.
$('#content').on('click', '.add-item', function () {
var $this = $(this);
var item_count = $this.siblings('.item').length + 1;
console.log(item_count);
var str_item = '';
str_item = '<div class="item">Item ' + item_count + '</div>';
$(str_item).insertBefore($this);
});
Upvotes: 2