Reputation: 2736
I have created a dashboard grid in BS and want to be able to drag the tiles around using Sortable - this in itself works fine but the behaviour is really unpredictable.
I have a 6 x 4 grid and, for example, if I move an item from row 2 to row 1, then the item moves into place correctly but the item it is replacing jumps down to row 2 and everything else moves down a row so I now end up with 6 x 5 grid.
Further, in most cases, I am not actually able to move items directly into row 2 so I need to then start moving all the other tiles around each of which also have similar issues to above making it worse again.
The code I am using for sortable is:
$(function() {
$(".sortable-heading").sortable({
connectWith: '.heading-sortable',
items: '.panel',
helper: 'original',
cursor: 'move',
handle: '.panel-title, [data-action=move]',
revert: 100,
grid: [ 10, 10 ],
delay: 150,
containment: '#home-dash',
forceHelperSize: true,
opacity: 0.7,
placeholder: 'sortable-placeholder',
forcePlaceholderSize: true,
tolerance: 'pointer',
start: function(e, ui){
ui.placeholder.height(ui.item.outerHeight());
}
});
});
Rather than posting all the HTML code, I have created a fiddle showing this in action.
If you move the red panel into the top row you will see the behaviour of adding an additional row and if you then try to drag the blue panel into the now second row it is not able to be done easily.
https://jsfiddle.net/mk3whz43/2/
Upvotes: 1
Views: 3292
Reputation: 1
you can use it like this
<!doctype HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Sortable - Display as grid</title>
<link
rel="stylesheet"href="//code.jquery.com/ui/1.13.2/themes/base/jquery-
ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#sortable { list-style-type: none; margin: 0; padding: 0; width:
450px; }
#sortable li { margin: 3px 3px 3px 0; padding: 1px; float: left;
width: 100px; height: 90px; font-size: 4em; text-align: center; }
</style>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<script>
$( function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
} );
</script>
</head>
<body>
<ul id="sortable">
<li class="ui-state-default">1</li>
<li class="ui-state-default">2</li>
<li class="ui-state-default">3</li>
<li class="ui-state-default">4</li>
<li class="ui-state-default">5</li>
<li class="ui-state-default">6</li>
<li class="ui-state-default">7</li>
<li class="ui-state-default">8</li>
<li class="ui-state-default">9</li>
<li class="ui-state-default">10</li>
<li class="ui-state-default">11</li>
<li class="ui-state-default">12</li>
</ul>
</body>
</html>
Upvotes: 0
Reputation: 232
bhttoan,
That is expected behavior. As you are adding one more col-xs-2. so, the last item will be pushed to next line. To solve this you need to have one single div with class row for all (4x6=24 items). Then your structure is retained.
Upvotes: 0
Reputation: 2668
I think the html structure is too complex for it to work with your current code. When you're moving an item, it is being appended/prepended to the parent div
of the item that it should be swapping with, thus breaking the structure of the content.
What you'll need to do is store the parent div
of the item you want to sort in a variable and on an update, .append
the target item to this div
. You'll still see the "jumping" when you initiate the sort, but the actual sorting of items will work.
Here's the updated code (I've added comments in code to explain what I've done):
$(function() {
var startParent;
$(".sortable-heading").sortable({
connectWith: '.heading-sortable',
items: '.panel',
helper: 'original',
cursor: 'move',
handle: '.panel-title, [data-action=move]',
revert: 100,
grid: [10, 10],
delay: 150,
containment: '#home-dash',
forceHelperSize: true,
opacity: 0.7,
placeholder: 'sortable-placeholder',
forcePlaceholderSize: true,
tolerance: 'pointer',
start: function(e, ui) {
ui.placeholder.height(ui.item.outerHeight());
//Store the parent in a variable as we will be appending the target item to this in the "update" event.
startParent = $(ui.item).closest('.col-xs-2');
},
update: function(e, ui) {
//When an item is swapped, it may have been added before the existing item or after it.
//Check if the contents of the "next" item is not undefined. If it is undefined, it means
//the item was inserted before the existing item.
if ($(ui.item).next()[0] !== undefined) {
//next() is the existing item.
startParent.append($(ui.item).next());
} else {
startParent.append($(ui.item).prev());
}
}
});
});
Upvotes: 0