I am trying to make the list items (cards) sortable, but for usability improvements I want to show the user an placeholder on the old (with text "FROM") and one on the new (with text "TO") before user releases mouse (ends .sortable).
helper: 'clone',
placeholder: {
element: function(currentItem) {
return $('<li class="placeholder">FROM or TO</li>')[0];
},
update: function(container, p) {
return;
},
}
right above, you see what I have for now, but is it possible to split "FROM" and "TO"?
I made it myself. Was quite complicated to introduce a second "placeholder" on old position. See here:
If you move an li, you now have an "FROM"-Container at old-pos and and "TO"-Container on future-pos, wich will be removed after positioning.
$(function() {
var oldList, newList, item;
$(".selector").sortable({
start: function(event, ui) {
item = ui.item;
newList = oldList = ui.item.parent().parent();
var activeElem = item.index();
$(this).children().eq(activeElem).after('<li class="placeholder">From</li>');
},
stop: function(event, ui) {
//alert("Moved " + item.text() + " from " + oldList.attr('id') + " to " + newList.attr('id'));
$(".selector > li").remove(".placeholder");
},
change: function(event, ui) {
if(ui.sender) newList = ui.placeholder.parent().parent();
},
connectWith: ".selector",
helper: 'clone',
placeholder: {
element: function(currentItem) {
return $('<li class="placeholder">To</li>')[0];
},
update: function(container, p) {
return;
}
}
}).disableSelection();
});
Related
I am trying to do something very simple. I am trying to make the TRs of a table sortable with JQuery UI and also Draggable to a different div which I will use as a trash can. I have the following script. But for some reason Drag and Sort are conflicting
$("#TBL_OUTPUT").sortable({
items: 'tr:not(:first)'
});
$("#TBL_OUTPUT tr").draggable({
helper: "clone",
start: function(event, ui) {
c.tr = this;
c.helper = ui.helper;
}
});
$("#TRASHCAN").droppable({
hoverClass: "TRASH_Hover",
drop: function(event, ui) {
$(c.tr).remove();
$(c.helper).remove();
}
});
Any thoughts?
You can simply use two sortables. Like:
$("table").sortable({
items: 'tr:not(:first)',
connectWith: 'div.bin',
helper: 'clone',
start: function (e, ui) {
$('.bin').css("background-color", "red");
},
stop: function (e, ui) {
$('.bin').css("background-color", "green");
}
});
$('div.bin').sortable({
connectWith: 'table',
update: function (e, ui) {
var content = ui.item.children('td').text();
if (confirm('Delete item: ' + content + '?')) {
$('div.bin').empty();
alert('Item ' + content + ' deleted!');
} else {
alert(content + 'will stay in the bin and you can drag it back to table');
}
}
});
FIDDLE: https://jsfiddle.net/rte2by43/4/
If you want to keep droppable, this will also work:
$("#TBL_OUTPUT").sortable({
items: 'tr:not(:first)',
connectWith: '#TRASHCAN'
});
$("#TRASHCAN").droppable({
hoverClass: "TRASH_Hover",
drop: function(event, ui) {
alert($(ui.draggable).children('td').text());
}
});
I made a drag & drop system. The draggable items can be dropped in placeholders. Those placeholders are added dynamically based on the amount of draggable items.
But when I drag a draggable item between those placeholders, it doesn't get appended to it. I've tried many many things but I'm still stuck on it.
I'm afraid that I'll need to change a lot of the code, but maybe one of you has a genius idea on how to solve this.
Here's the jsfiddle
Is it possible to check wether it has been placed on a placeholder, or not?
This is my droppable function:
function dropping () {
$("li.placeholder").droppable({
accept: ".to-drag",
hoverClass: correct_placeholder,
activeClass: active_placeholder,
revert: false,
tolerance: "pointer",
drop: function (event, ui) {
var dragging = ui.draggable.clone().find("img").remove();
$(this).append(dragging).addClass("dropped");
$(this).droppable('disable');
var day = $(ui.draggable).attr('data-id');
var index = $(event.target).index();
$(this).attr("data-id", day);
$(this).attr("date-order", index);
$(this).addClass("drop-"+ index);
$(this).attr("data-content", "");
$(this).find("h1, p").remove();
var dropped = $(".dropped").length;
var original = $(".placeholder").length;
if (dropped === original) {
$("li.placeholder").removeClass(blank_placeholder);
$("#dropzone").append('<li class="placeholder ' + blank_placeholder +' " data-id="" data-order=""></li>');
init();
}
$(".remove").click(function() {
var removable = $(this).parent();
var modal = $(this).attr("data-modal");
$(".modal-"+modal).remove();
if (dropped > original) {
$(this).parent().droppable('enable')
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
$(this).parent().droppable('enable');
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
init();
});
}
});
$("li.dropped").droppable({
disabled: function (event, ui) {
disabled: true
}
});
}
I'm trying to re-order the elements of a list in a jquery sortable when it is created based on which order they are in in a list.
var CACHES = ["WayBack Machine", "Google Cache", "Coral CDN"];
var HTML = ["Google Cache", "WayBack Machine", "Coral CDN"];
$("#sortable").sortable({
stop: function(event, ui) {
console.log("New position: " + ui.item.index());
},
change: function(event, ui) {
// When the item postion is changed while dragging a item, I want it's position
console.log("New position: " + ui.item.index());
},
create: function(event, ui) {
console.log("Sortable Created");
var ul = $('#sortable');
var li = ul.children('li').get();
li.sort(function(a,b) {
$(a).attr('id')
var value = CACHES.indexOf($(a).attr('id')) < CACHES.indexOf($(b).attr('id')) ? 1 : -1
console.log(value)
return value
});
ul.append(li);
}
});
var HTML is the order that they are in in the HTML of the page. var CACHES is the order that I want to put them in. It does seem to reorder the elements, but not correctly.
http://www.w3schools.com/jsref/jsref_sort.asp
use - instead of < and ternary
var value = CACHES.indexOf($(a).attr('id')) - CACHES.indexOf($(b).attr('id'));
$("li").draggable({
helper: "clone"
});
$("#div1").droppable({
drop: function (event, ui) {
$("<p></p>").appendTo("#div1");
}
});
I have objects in a list that can be dragged and dropped into a div named div1. But when I drop one into the div i don't want to be able to drop another into it. I have tried using, for, if and while loops with a count.
Here is a full solution, it allows only one item dropped, but also, if one exists, it gets replaced on the next drop with the new one. (Usefull if someone changes their mind. Just call
refreshDragDrop(dragClassName,dropDivId);
refreshDragDrop = function(dragClassName,dropDivId) {
$( "." + dragClassName ).draggable({
connectToSortable: "#" + dropDivId,
helper: "clone",
revert: "invalid"
});
$("#" + dropDivId).droppable({
accept: '.' + dragClassName,
drop: function (event, ui) {
var $this = $(this),
maxItemsCount = 1;
if ($this.children('div').length == maxItemsCount ){
//more than one item,just replace
$(this).html($(ui.draggable).clone());
} else {
$(this).append($(ui.draggable).clone());
}
}
});
}
This should help:
drop: function (event, ui) {
var $this = $(this),
maxItemsCount = 1;
if ($this.children('li').length > maxItemsCount ){
ui.sender.draggable('cancel');
alert("To much items!");
}
}
I've a peculiar situation. I have two lists. 1 list contains all items, and 2 contains top list. Obviously items overlap, and items in the second list are marked with class clone-23 clone-25 according to which element from list 1 are they cloned from.
Example:
List 1
1 run
2 eat
3 drink
4 play
List 2 (TOP)
1 run (class clone)
2 eat (class clone)
When re-arranged data is saved to DB.
I would like to avoid refresh and re-pulling of data from DB. So I would like to sync position of elements in two lists.
So whenever user drags around item in list 1, list 2 automatically shows changed positions and vice versa.
I initiate my sortable:
// Initiate jquery ui sortable
$(".word-list").sortable({
tolerance: 'pointer',
cursor: 'move',
forcePlaceholderSize: true,
dropOnEmpty: true,
connectWith: 'ol.word-list',
//containment: "body",
//
start: function(event, ui) {
// Starting position of the word element
//ui.item.startPos = ui.item.index();
//console.dir(ui.item.startPos);
},
//
stop: function(event, ui) {
//
},
update: function(event, ui) {
//
save_word_order(this);
//
},
out: function(event, ui) {
//
},
over: function(event, ui) {
//
},
placeholder: "ui-state-highlight"
});
Clone element html:
<li data-con-id="94" data-order-id="1" data-note="" class="ui-state-default clone-94"</li>
Lists are simply:
<ol id="tabs-1" class="word-list"></ol>
<ol id="tabs-2" class="word-list"></ol>
Any thoughts?
See this fiddle for code which syncs the order of items common to both lists:
http://jsfiddle.net/Fresh/22jc2/
Note that in my example I have simplified list two's li elements by not including the clone attributes; instead I am comparing items in both list by the list item's innerText value. It should be fairly easy for you to refactor my solution to use the clone item attributes if you really need to use them.
The script which I've used to achieve the synchronisation of the order of the common list items is:
var reorderLists = function (list1, list2) {
$('#' + list1 + ' li').each(function (index) {
var sortableItemWithText = $('#' + list2 + ' li:contains(' + this.textContent + ')');
if (sortableItemWithText.length === 1) {
sortableItemWithText.appendTo('#' + list2);
return;
}
});
};
$("#sortable1, #sortable2").sortable({
update: function (event, ui) {
var parentNodeId = ui.item[0].parentNode.id;
if (parentNodeId == "sortable1") {
reorderLists("sortable1", "sortable2");
}
if (parentNodeId == "sortable2") {
reorderLists("sortable2", "sortable1");
}
}
});
$("#tabs").tabs();
Note that the syncing of the order of common list items works if you change the position of items in either list 1 or list 2.
Also note that by commenting out:
$("#tabs").tabs();
You'll be able to see the lists updating automatically when you move the list items; this makes it easier to confirm that the re-order routine is work as expected.
perhaps this can help :
See this fiddle for code which syncs the order of items common to both
lists:
http://jsfiddle.net/penjepitkertasku/6bk7B/1/
$(function() {
var dragElementID = "";
var dropElementID = "";
var dragElementItemName = "";
var allElementItemName = "";
$(".word-list").sortable({
tolerance: 'pointer',
cursor: 'move',
helper: 'clone',
//revert: 'invalid',
forcePlaceholderSize: true,
dropOnEmpty: true,
connectWith: 'ol.word-list',
start: function(e, ui){
var id = $('ol.word-list').children().index($(ui.item[0]));
var name = $('ol.word-list').children(':eq(' + id + ')').text();
dragElementItemName = name;
dragElementID = this.id;
},
stop: function(event, ui) {
var id = $('ol.word-list').children().index($(ui.item[0]));
//validate
if(dragElementID == dropElementID) { return; }
if(id == -1)return;
if(dragElementID == "tabs-1")
{
if(allElementItemName.indexOf(dragElementItemName,1) > 0) { $(this).sortable('cancel'); return; }
var elm = $(ui.item[0]).clone(true).removeClass('box ui-draggable ui-draggable-dragging').addClass('box-clone');
$('ol.word-list').children(':eq(' + id + ')').after(elm);
$(this).sortable('cancel');
}else{
ui.item.remove();
}
},
update: function(event, ui) {
//
//save_word_order(this);
//
},
out: function(event, ui) {
//
},
over: function(event, ui) {
//
dropElementID = this.id;
allElementItemName = '|' + $('#' + dropElementID + ' li').text() + '|';
},
placeholder: "ui-state-highlight"
});
});