When I am dragging and dropping an item, following code using sortupdate gets triggered
$('#sortable').sortable().bind('sortupdate', function (event, ui) {
debugger;
//Triggered when the user stopped sorting and the DOM position has changed.
});
BUT
start, update, stop, change events are not getting triggered
That is,
$('#sortable').sortable({
start: function(event, ui) {
//
},
change: function(event, ui) {
//
},
update: function(event, ui) {
//
}
});
My goal is to find the original and dropped position of an item.
EDIT (for clear understanding):
In short,
$('#sortable').sortable().bind('sortupdate' ..... is working(triggered)
$('#sortable').sortable().bind('start' ..... is not working(not triggered)
$('#sortable').sortable().bind('change' ..... is not working(not triggered)
$('#sortable').sortable().bind('update' ..... is not working(not triggered)
$('#sortable').sortable().bind('sort' ..... is not working(not triggered)
If possible to get the values of old and new position with sortupdate event alone, then also it is ok..My ultimate goal is to find the position of both old and new for an item.
all this event are prefixed with sort so instead of start it becomes sortstart
i have created a fiddle where it will give the message of item moved from and to have a check at
http://jsfiddle.net/p2gethgh/
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
var from,to;
$("#sortable").on("sortstart",function(event,ui){
from = $(this).children().index(ui.item);
});
$('#sortable').on('sortdeactivate',function(event,ui) {
to = $(this).children().index(ui.item);
alert(ui.item.text()+' moved from '+(from + 1)+' to '+(to + 1));
});
This is the correct way to bind event to jquery sortable
$( ".selector" ).sortable({
start: function( event, ui ) {}
});
OR
$( ".selector" ).on( "sortstart", function( event, ui ) {} );
Related
I am using jQuery Sortable to allow users to drag and drop elements on the page. When a user drags a div I need to get the updated order of the list and pass it to the back end. So far I've tried:
$( function() {
$( "#sortable" ).sortable({
axis: 'y',
stop: function (event, ui) {
var data = $(this).sortable('serialize');
alert(data);
$.ajax({
data: oData,
type: 'POST',
url: '/url/here'
});
}
});
$( "#sortable" ).disableSelection();
} );
but this makes the animation really not smooth and alerts no data. How do I get a position list every time a user drags and drops a div?
JSFIDDLE
There's a refreshPositions() function you can use that returns a object representing the sortable item. You can then obtain the updated list of children by making a call to .children() on that object.
Save the positions to a variable in the stop event, which is triggered after you have finished sorting.
I've updated your function to include the stop event:
$("#sortable").sortable({
stop: function(ev, ui) {
//Get the updated positions by calling refreshPositions and then .children on the resulting object.
var children = $('#sortable').sortable('refreshPositions').children();
console.log('Positions: ');
//Loopp through each item in the children array and print out the text.
$.each(children, function() {
console.log($(this).text().trim());
});
}
});
Updated Fiddle
Instead, use the toArray() method, detailed here: http://api.jqueryui.com/sortable/#method-toArray
I'm now developing a website that can drag elements and drop into a table cells (each cell has its "ID")
Now I can drag and drop the element to the cells but I want to know
How to get the ID of table cell where I dropped the element?
here's the picture's concept.
Suppose that cell's ID are the combination of row and column number.
At first you need to rename yours IDs because one ID can't start with a number. You neet at lest one letter, example "ID11" "ID12" ...
Than what are the Cells? div? Td? Input?
Can you a jsfiddle ?
-Edit.
you need something like thise:
jsfiddle
you must only change your skript to:
$(function() {
$("#draggable").draggable({ snap: ".drop"});
$(".drop").droppable({
drop: function(event, ui){
console.log("Dropped to" + $(".drop").attr("id"));
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
Here is the working fiddle.
Try something like this:
$(function() {
$("#draggable").draggable({ snap: ".drop"});
$(".drop").droppable({
drop: function(event, ui){
console.log($(this).attr('id'));
}
});
});
Check this fiddle.
First you need to enable the table cells to be dragged to by defining ondragover event callback. In the fiddle:
box.ondragover = function (evt) { evt.preventDefault(); };
preventDefault ensures that the browser does not set a dropdown lock on the element.
Then you simply play around with the event data, like this:
box.ondrop = function (evt) { droppedTo.innerHTML = evt.toElement.id; };
toElement holds reference to the element that you drop on, and you can get all the data you need from it, including id.
You need to change your script like this
$(function () {
$("#draggable").draggable({
snap: ".drop"
});
$(".drop").droppable({
drop: function (event, ui) {
alert($(this).attr("id"));
console.log("Dropped to " + $(this).attr("id"));
}
});
});
Change from $(".drop").attr("id") to $(this).attr("id") to get the id of the element that you are dropping into :)
Example http://jsfiddle.net/81ja79Ls/4/
I will simplify my explanation so you get what I am doing. I have two div's and I set up portlets as shown here, however I am dynamically injecting my portlets, no big problem there.
<div id="mainallapplicant" class="myrow"></div>
<div id="contingent_right" class="myrow"></div>
Here is the JavaScript
$( ".myrow" ).sortable({
connectWith: ".myrow",
revert: true,
beforeStop: function( event, ui ) {}
});
I am trying to allow a maximum of only one droppable into mainallapplicant. If there is one already there, I will show a confirmation dialog and depending on the answer, I cancel the drop or move out the existing item and replace it with the new item. I tried the following but I am getting nowhere.
$( ".myrow" ).sortable({
connectWith: ".myrow",
revert: true,
start: function(event, ui) {
if ($(this).prev().find(".portlet").length == 1) {
ui.sender.draggable("cancel");
}
},
stop: function(event, ui) {
if ($(this).prev().find(".portlet").length == 1) {
ui.item.remove();
// Show an error...
}
}
});
You can use start to get the current count of portlet elements, then use stop to do the checking
Also notice I added class names to each div to allow only one div to have a maximum of 1 portlet
$(document).ready(function () {
$.count = 0;
$(".myrow").sortable({
connectWith: ".myrow",
revert: true,
start: function () {
$.count = $(".myrow").has(".portlet").length;
console.log("Start " + $.count);
},
stop: function (event, ui) {
if ($(ui.item).parent(".myrow").hasClass("left")) {
if ($.count == 2) {
$(".myrow").sortable("cancel");
}
}
}
});
});
DEMO: http://jsfiddle.net/Ue4dq/
What I'm trying to do is combine two projects:
One is an example of draggable and sortable list-items
The other is jEditable, which I'm using to make the list-items editable
Now I was able to append the edit class to the existing list items in the first link without any trouble. When I go to create a new draggable item (a clone) and move it to the sortable list, I want it to take on the css class of the older items. I have tried adding code to the draggable's stop event and the sortable's receive event with no luck. It's the original's style that changes, not the clone's.
receive: function(event, ui) {
alert("dropped item ID: " + ui.item.attr('id'));
$("#draggable").attr('class', 'edit');
}
stop: function() {
if ( !$( "#draggable" ).hasClass( "ui-state-hover" ) ) {
$( "#draggable" ).removeClass( "ui-state-highlight" );
$( "#draggable" ).addClass( "ui-state-default" );
$( "#draggable" ).addClass( "edit" );
}
}
How can I achieve this?
JSFiddle is here
You can actually utilize the ui in your sortable event stop. Here short definition of them:
ui.
helper: The jQuery object representing the helper being sorted
item: The jQuery object representing the current dragged element
offset: The current absolute position of the helper represented as { top, left }
position: The current position of the helper represented as { top, left }
originalPosition: The original position of the element represented as { top, left }
sender: The sortable that the item comes from if moving from one sortable to another
So you need to use stop event and change the ui.item style like this:
$(ui.item).attr('class', 'ui-state-default edit');
And you have to re-initiate the editable like this:
$(document).ready(function() {
initEditable();
});
function initEditable(){
$('.edit').editable('http://www.example.com/save.php', {
indicator : 'Saving...',
tooltip : 'Click to edit...'
});
$('.edit_area').editable('http://www.example.com/save.php', {
type : 'textarea',
cancel : 'Cancel',
submit : 'OK',
indicator : '<img src="img/indicator.gif">',
tooltip : 'Click to edit...'
});
}
$(function() {
$( "#sortable" ).sortable({
revert: true,
update: function() {
var orders = [];
$.each($(this).children(), function(i, item) {
orders.push($(item).data("x"));
});
$("#info").text("Order: " + orders.join(","));
},
stop: function(event, ui) {
$(ui.item).attr('class', 'ui-state-default edit');
initEditable();
}
});
});
See modified code here: http://jsfiddle.net/xvsMh/1/
Your events are correct, but as you realized, #draggable is the original item, not the cloned one. One way to get your cloned item would be to search for an item with identical classes in the sortable list. So instead of using:
$("#draggable").attr('class', 'edit');
you use:
$('#sortable .ui-draggable')
.removeClass('ui-state-highlight ui-draggable')
.addClass('ui-state-default edit');
Demo at JSFiddle
I have a simple code example # http://jsbin.com/ukiwo3/edit
It has 2 connected lists and a load of bound events. I'm hopeful I've missed something simple as based on http://jqueryui.com/demos/sortable/ Events I think I should see all these events fired when I drag and reorder a question li. At the moment only sort logs to the console.
Can anyone tell me whats wrong and how to get the rest to fire?
Thanks,
Denis
The events are named differently when binding, for example sortstart instead of start. Look at the list of events on the demo page for a full list of what your binds should be.
Overall, it should look like this:
$( ".questions" ).bind( "sortstop", function(event, ui) {
console.log("stop event");
});
$( ".questions" ).bind( "sortstart", function(event, ui) {
console.log("start event");
});
$( ".questions" ).bind( "sortchange", function(event, ui) {
console.log("change event");
});
$( ".questions" ).bind( "sort", function(event, ui) {
console.log("sort event");
});
$( ".questions" ).bind( "sortremove", function(event, ui) {
console.log("remove event");
});
$( ".questions" ).bind( "sortout", function(event, ui) {
console.log("out event");
});
$( ".questions" ).bind( "sortover", function(event, ui) {
console.log("over event");
});
$( ".questions" ).bind( "sortupdate", function(event, ui) {
console.log("update event");
});
(not optimized, just showing event names)
I did this and I see the stop event get triggered:
$('.questions').sortable({
axis: 'y',
connectWith: ".questions",
placeholder: "question-highlight",
stop:function(event, ui) {
console.log("stop event");
}
});
It seems to me those 'events' are not accessible via bind.