jQuery sortable tables get squeezed when row positions swapped - javascript

I have ui-sortable table implemented with jquery-ui. The rows can be dragged to swap positions. All works fine, but when the row is dragged, all the remaining rows in a table get squeezed to 1/5 size (columns overlapping).
here's the code that invokes the sortable script on the table:
$(document).ready(function () {
var fixHelper = function (e, ui) {
ui.children().each(function () {
$(this).width($(this).width());
});
return ui;
};
$("tbody.sortable").sortable({
helper: fixHelper,
connectWith: "tbody.sortable",
containment: "parent",
dropOnEmpty: true,
cancel: "tr.sort-disabled",
receive: function (event, ui) {
ui.item.find("input[type='hidden']").val(this.id);
sortableDummyRowsUpdate();
}
});
});
When the dragged row is released to the new position, the table returns to normal. But while dragging everything looks awful

Related

Change items style when moving elements in jquery-ui sortable

I have two columns, that are jquery-ui sortable. In the left column are choosen items, in the right are all not choosen. You can move items (li elements) between both. Each element can be either in the left one or in the right column. The first element in the left column (choosen) is not sortable and cant be moved (name ID). Elements in the left column have different style as elements in the right column, also in the left column each li element is on self line, but in the right column they are floated.
Here is an image of that:
Everything is working fine, but when user is moving element between columns, I need the element change its style (while is moving = left mouse button is down), when is over left or right column. By changing its style I mean, when f.e. I start to move element Telefón from left to right, when I will be over right column, this element should change its background color to gray and display not in the whole line, but only in its width and ad versa.
Working demo
I cant figure out, how this can be done. Thanks.
You can add this to your sortable options:
over: function (event, ui) {
if ($(ui.item).closest("ul").hasClass("interested")) {
$(ui.item).detach().appendTo("#categories-source");
$(ui.item).css("width", "initial");
} else {
$(ui.item).detach().appendTo("#categories-chosen");
$(ui.item).css("width", "210px");
$(ui.item).css("height", "initial");
}
}
It puts dragged element in proper ul depending if previous one had class interested.
Update
Also set proper dimensions to the dragged element (because left list is one per line).
Fiddle
Since you are using jQuery UI, you can take advantage of droppable widget. This features two callback, over and out. Change CSS properties of draggable element whenever it is over or out droppable area.
See it working here.
$(".columns_all").droppable({
over: function (event, ui) {
ui.helper.css("background-color", "lightblue");
},
out: function (event, ui) {
ui.helper.css("background-color", "");
}
});
Update
As requested, here is a code for two-way dragging.
elwidth = $(".columns_selected li").width(); // used to set element width
// left to right
$(".columns_all").droppable({
over: function (event, ui) {
ui.helper.css({
"background-color": "lightblue",
width: "auto"
});
},
out: function (event, ui) {
ui.helper.css({
"background-color": "",
width: elwidth
});
},
drop: function (event, ui) {
ui.helper.css({
"background-color": "#ccc"
});
}
});
// right to left
$(".columns_selected").droppable({
over: function (event, ui) {
ui.helper.css({
"background-color": "red",
width: elwidth
});
},
out: function (event, ui) {
ui.helper.css({
"background-color": "",
width: "auto"
});
},
drop: function (event, ui) {
ui.helper.css({
"background-color": "#74ce9c"
});
}
});
Updated fiddle.

Jquery Sortable on table rows run function on change

I have a script that counts the number of rows in a table and assigns a value attribute to an input field. I am adding the draggable plugin Sortable to table rows, what would be the best way to run this script then on document ready, and on change. The first part works, but i am not getting alerted when the table rows change.
this is now my revised code:
function countRows(){
var i = 0;
$('#offices td input').each(function(){
$(this).attr("value", ++i);
});
}
$(document).ready(countRows);
// Sortable rows
$('.sorted_table').sortable({
containerSelector: 'table',
itemPath: '> tbody',
itemSelector: 'tr',
placeholder: '<tr class="placeholder"/>'
})
$('.sorted_table').children("tbody").sortable({
stop: function (event, ui) {
countRows(); // re-number rows after sorting
}
});
Assuming you are using jQuery UI Sortable:
$('.sorted_table').children("tbody").sortable({
stop: function (event, ui) {
countRows(); // re-number rows after sorting
}
});
jsFiddle demo here: http://jsfiddle.net/7vmf1c4L/

Draggable connected to sortable

I want to be able to drag items from one Infragistics DataGrid to another, while the items in the Destination grid are also sortable.
Unfortunately, I cannot use jsfiddle because I cannot use the infragistics controls there.
$("[id*=sourceGrid] [id*=dataTbl] tbody tr").draggable({
helper: "clone",
revert: "invalid",
connectToSortable: '[id*=destination]'
});
$("[id*=destinationGrid]").sortable({
cursor: 'move',
helper: fixHelperModified,
revert: true,
items: "[id*=container] [id*=dataTbl] tbody tr:not(.placeholder)",
receive: function (event, ui) {
var grid = $IG.WebDataGrid.find("destinationGrid");
$sentence = $(ui.item).find("td").eq(0).html();
var row = new Array(Math.floor((Math.random() * 100) + 1), $sentence, $order);
grid.get_rows().add(row);
}
});
The problem is: When I drop items from the sourceGrid to the destinationGrid, I don't want the draggable to be placed into the new Grid - I only want to use the receive function to create a new row in the grid with the values from the draggable element. Right now, I get both - the newly created gridRow and the dropped item. How can I prevent that?
You can catch the copied item in the beforeStop event.
var newItem;
$(".list").sortable({
connectWith: ".list",
beforeStop: function (event, ui) {
newItem = ui.item;
},
receive: function(event,ui) {
$(newItem).doSomething();
}
});​
Reference and credit to this answer: https://stackoverflow.com/a/5864644/3523694

How to prevent child sortables from cloning

I have three sortable list boxes, one grey and two yellow. I can drag and clone child sortable li's into the bottom yellow lists no problem.
The problem is that once the child clone li's from the grey list box are placed into the yellow list boxes, you can no longer drag/shift them within the containing yellow list box or to the adjacent yellow list box. They just clone continuously when you attempt to drag them elsewhere.
I would like to drag and clone sortables from the grey list box into the yellow boxes and have the cloned child li's be able to drag and move within the yellow lists boxes without cloning.
How can I prevent the child li's from cloning. Any help would be much appreciated. Thanks.
http://jsfiddle.net/equiroga/96hJj/
$(function() {
$(".sortable").sortable(
{
helper : "clone",
connectWith : ".sortable",
start : function(event,ui)
{
$(ui.item).show();
clone = $(ui.item).clone();
before = $(ui.item).prev();
position = $(ui.item).index();
},
beforeStop : function(event, ui)
{
if($(ui.item).closest('ul#sortable1').length>0)
$(this).sortable('cancel');
},
stop : function(event, ui)
{
if (position == 0) $("#sortable1").prepend(clone);
else before.after(clone);
}
});
$(".sortable").sortable();
});
You can set a particular behavior for the first list and a different for the others, the others can't interact with the first using a coonectWith selector with :not selector.
Code:
$(function () {
$("#sortable1").sortable({
helper: "clone",
connectWith: ".sortable",
start: function (event, ui) {
$(ui.item).show();
clone = $(ui.item).clone();
before = $(ui.item).prev();
position = $(ui.item).index();
},
beforeStop: function (event, ui) {
if ($(ui.item).closest('ul#sortable1').length > 0) $(this).sortable('cancel');
},
stop: function (event, ui) {
if (position == 0) $("#sortable1").prepend(clone);
else before.after(clone);
}
});
$(".sortable").sortable({connectWith: ".sortable:not('#sortable1')"});
});
Demo: http://jsfiddle.net/IrvinDominin/923VG/

Sort multiple selected items in jQuery sortable?

I'm trying to select more than one item in a jQuery sortable set and then move the selected items around together.
Here's my weak beginning of an attempt to make it work. And here's the code:
HTML:
<div class="container">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
<div>five</div>
</div>
JS:
$('.container div').draggable({
connectToSortable: '.container',
//How do I drag all selected items?
helper: function(e, ui) {
return $('.selected');
}
});
$('.container').sortable({
axis: 'y',
//How do I sort all selected items?
helper: function(e, ui) {
return $('.selected');
}
});
$('.container div').live('click', function(e) {
$(this).toggleClass('selected');
});
CSS:
body{background-color:#012;font-family:sans-serif;text-align:center;}
div{margin:5px 0;padding:1em;}
.container{width:52%;margin:1in auto;background-color:#555;border-radius:.5em;box-shadow:0 0 20px black;}
.container div{background-color:#333;color:#aaa;border:1px solid #777;background-color:#333;color:#aaa;border-radius:.25em;cursor:default;height:1em;}
.container div:hover{background-color:#383838;color:#ccc;}
.selected{background-color:#36a !important;border-color:#036 !important;color:#fff !important;font-weight:bolder;}
I don't know if I'm headed in the right direction or not. I can't find an example of this anywhere online. Just lots of related questions. Does anyone know how?
For example, if I've selected items 4 and 5 out of a list of 6. I want to be able to drag 4 and 5 to the top of the set to get this order - 4 5 1 2 3 6 - Or if I selected 5 and 1 and drag them to the bottom - 2 3 4 6 1 5
This seems to work with the multisortable plugin. Code below. Or see jsFiddle.
// ctrl + click to select multiple
$('.container').multisortable({
stop: function(e, ui) {
var $group = $('.ui-multisort-grouped').not(ui.item);
$group.clone().insertAfter($(ui.item));
$group.each(function() {
$(this).removeClass('ui-multisort-grouped');
});
$group.remove();
}
});
But what if multisortable breaks with future jQuery versions?
Modifying my answer here (according to your HTML and CSS) :
Select items to sort
Create a custom helper
Hide the selected items until sort is done
Resize the helper and placeholder according to the selection
Manually detach selected items from the current position and attach them to the new position after sort
Show the hidden items (undo step 3) after step5
$(function () {
$('.container').on('click', 'div', function () {
$(this).toggleClass('selected');
});
$(".container").sortable({
revert: true,
helper: function (e, item) {
if (!item.hasClass('selected')) item.addClass('selected');
var elements = $('.selected').not('.ui-sortable-placeholder').clone();
var helper = $('<div/>');
item.siblings('.selected').addClass('hidden');
return helper.append(elements);
},
start: function (e, ui) {
var elements = ui.item.siblings('.selected.hidden').not('.ui-sortable-placeholder');
ui.item.data('items', elements);
var len = ui.helper.children().length;
var currentHeight = ui.helper.height()
var itemHeight = ui.item.height() + 32; // 32 = 16x2 padding
ui.helper.height(currentHeight + (len * itemHeight))
ui.placeholder.height((len * itemHeight))
},
receive: function (e, ui) {
ui.item.before(ui.item.data('items'));
},
stop: function (e, ui) {
ui.item.siblings('.selected').removeClass('hidden');
$('.selected').removeClass('selected');
}
});
});
Updated Fiddle

Categories