Cody
Cody

Reputation: 168

jQuery sortable lags when hidden elements are present

I have a problem where jQuery sortable items are struggling to find their place in the sortable element if there are hidden elements present. In the following jsfiddle, there are 2 examples. In the first, there are 6 elements with 3 of them hidden (this is the sortable that feels sluggish and doesn't seem like the elements know where to place themselves). In the second, there are 6 elements with none of them hidden. They will move smoothly into place unlike the first example.

Does anyone know why this could be happening? It seems like it's probably a css problem, but I'm not sure where. I have a larger problem much like this at work but tried to simplify the code to a jsfiddle.

http://jsfiddle.net/e234g/4/

<div class="sortable leftPanels">
    <div class="panel hide">panel 1</div>
    <div class="panel hide">panel 2</div>
    <div class="panel hide">panel 3</div>
    <div class="panel">panel 4</div>
    <div class="panel">panel 5</div>
    <div class="panel">panel 6</div>
</div>
<br /><br />
<div class="sortable leftPanels">
    <div class="panel">panel 1</div>
    <div class="panel">panel 2</div>
    <div class="panel">panel 3</div>
    <div class="panel">panel 4</div>
    <div class="panel">panel 5</div>
    <div class="panel">panel 6</div>
</div>
.panel{
    background-color:#eee;
    display:inline-block;
    margin:5px;
}

.sortable{
    padding: 10px;
    padding-top:15px;
    background-color:#999;
    list-style-type: none;
    height:50px;
}

.panel-placeholder{
    background-color:#333;
    display:inline-block;
}
.hide{
    display:none;
}
$(".sortable").sortable({
    placeholder: 'panel-placeholder',
    start: (event, ui) ->
        $('.panel-placeholder').width(ui.item.width()).height(ui.item.height())            
}).disableSelection();

Thanks for the help

Upvotes: 0

Views: 1502

Answers (2)

Markus B
Markus B

Reputation: 83

For anyone stumbling upon this question, and OP's own answer 10 years later, there is a better solution available:

Simply add items: '> .your-sortable-elements:visible' to the settings of your sortable. Replace "your-sortable-elements" with the class that you have attached to each of the "sortable()" containers children (the elements that are sorted).

A full example might look like this:

$(container).sortable({
    axis: 'x',
    helper: 'clone',
    tolerance: 'pointer',
    items: '> .your-sortable-elements:visible',
}) // Make container draggable

Upvotes: 0

Cody
Cody

Reputation: 168

I seem to have solved the problem with a workaround to not have to use display:none. Create this hidden class and add or remove it to toggle visibility.

.hidden {
    width:0px !important;
    overflow:hidden;
    visibility:hidden;
    display: block !important;
}

If you are using .toggle() or in my case .fadeToggle() It will automatically set display to none. To fix this, you can do something like the following to fix it. Keep in mind .toggle() will put display in higher css specificity so you will need to override it in the hidden class.

panelVisible = viewModel.panelIsVisible(panelName)
currentlyVisible = $(element).is(":visible") and $(element).css('visibility') is 'visible'

unless panelVisible is currentlyVisible
  if not currentlyVisible
    $(element).removeClass('panel-hidden')
  $(element).fadeToggle panelVisible, () => 
    if not panelVisible
      $(element).addClass('panel-hidden')

Upvotes: 1

Related Questions