Reputation: 59271
I have a jQuery UI Sortable list. The sortable items also have a click event attached. Is there a way to prevent the click event from firing after I drag an item?
$().ready( function () {
$('#my_sortable').sortable({
update: function() { console.log('update') },
delay: 30
});
$('#my_sortable li').click(function () {
console.log('click');
});
});
#my_sortable li {
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
Upvotes: 66
Views: 34340
Reputation: 151
If you for some reason don't want to use the helper:'clone'
trick, this worked for me. It cancels the click event on an item that is dragged. jQuery adds the class ui-sortable-helper
to the dragged element.
$('.draggable').click(clickCancelonDrop);
function clickCancelonDrop(event) {
var cls = $(this).attr('class');
if (cls.match('ui-sortable-helper'))
return event.stopImmediatePropagation() || false;
}
Upvotes: 3
Reputation: 2521
$('.menu_group tbody a').click(function(){
link = $(this).attr('href');
window.location.href = link;
});
This solution seems to be working for me. Now i can click on clickables inside sortable elements.
Note: ".menu_group tbody"
is .sortable();
Upvotes: -1
Reputation: 517
Thanks to Elte Hupkus;
helper: 'clone'
I have implemented the same and a sample is shown below.
$(document).ready(function() {
$("#MenuListStyle").sortable({
helper:'clone',
revert:true
}).disableSelection();
});
Upvotes: 1
Reputation: 2978
I had the same problem and since my sortable items contained three or four clickable items (and the number was variable) binding/unbinding them on the fly didn't really seem an option. However, by incident I specified the
helper : 'clone'
option, which behaved identically to the original sortable in terms of interface but apparently does not fire click events on the dragged item and thus solves the problem. It's as much a hack as anything else, but at least it's short and easy..
Upvotes: 144
Reputation: 157
We can also use a flag on the stop event that and check that flag on the click event.
var isSortableCalled = false;
$('#my_sortable').sortable({
stop: function(event, ui){
isSortableCalled = true;
},
update: function() { console.log('update') },
delay: 30
});
$('#my_sortable li').click(function () {
if(!isSortableCalled){
console.log('click');
}
isSortableCalled = false;
});
Upvotes: 2
Reputation: 954
$('.selector').draggable({
stop: function(event, ui) {
// event.toElement is the element that was responsible
// for triggering this event. The handle, in case of a draggable.
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
}
});
This works because "one-listeners" are fired before "normal" listeners. So if a one-listener stops propagation, it will never reach your previously set listeners.
Upvotes: 2
Reputation: 3311
One solution is to use live() instead of normal binding, but Elte Hupkes solution rocks!!!!
Upvotes: 0
Reputation: 19
Easier, use a var to know when the element is being sorted...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
$().ready( function () {
$('#my_sortable').sortable({
start: function() {
sorting = true;
},
update: function() {
console.log('update');
sorting = false;
},
delay: 30
});
$('#my_sortable li').click(function () {
if (typeof(sorting) == "undefined" || !sorting) {
console.log('click');
}
});
});
</script>
<style type="text/css" media="screen">
#my_sortable li {
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
}
</style>
</head>
<body>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
</body>
</html>
Upvotes: 1
Reputation: 549
If you have a reference to the click event for your li, you can unbind it in the sortable update method then use Event/one to rebind it. The event propagation can be stopped before you rebind, preventing your original click handler from firing.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
var myClick = function () {
console.log('click');
};
$().ready( function () {
$('#my_sortable').sortable({
update: function(event, ui) {
ui.item.unbind("click");
ui.item.one("click", function (event) {
console.log("one-time-click");
event.stopImmediatePropagation();
$(this).click(myClick);
});
console.log('update') },
delay: 30
});
$('#my_sortable li').click(myClick);
});
</script>
<style type="text/css" media="screen">
#my_sortable li {
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
}
</style>
</head>
<body>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
</body>
</html>
Upvotes: 13
Reputation: 1511
The answer by mercilor worked for me a couple of caveats. The click event was actually on the handle element rather than the sorted item itself. Unfortunately the ui object, doesn't give you a reference to the handle in the update event (feature request to jquery ui?). So I had to get the handle myself. Also, I had to call preventDefault as well to stop the click action.
update: function(ev, ui) {
var handle = $(ui.item).find('h3');
handle.unbind("click");
handle.one("click", function (event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).click(clickHandler);
});
// other update code ...
Upvotes: 1