Search code examples
jqueryjquery-ui-draggablejquery-ui-droppable

JQuery draggable mouse cursor offset


I have draggable list elements which I'm able to drag into another list (in fact is not a list but a tree based on omnifaces / primefaces).

Problem:

I need to drag from the second list to second list (reodering element).

For this between each element of the list I have a droppable with height = 0px that I modify to 20px when my draggable overlap at this level no problem, the concern comes from the fact that when I resize the droppable, the mouse cursor shift from the draggable.

This being quite difficult to explain below picture illustrating the problem

enter image description here

I have tested the option cursorAt with no success if anyone have a suggestion where this shifting might come from


Solution

  • Use the following minimal jQuery and CSS and you should be good to go.

    $("#second-list").sortable({
      axis: "y",
      handle: '.sortable-handle',
    });
    
    $(".removeNode").on("click", function() {
      $(this).closest("li").remove();
    });
    /* QuickReset */ * {margin: 0; box-sizing: border-box;}
    
    .sortable {
      list-style: none;
      padding: 0;
    }
    
    .sortable li {
      display: flex;
      align-items: center;
      padding: 0.5rem;
      box-shadow: 0 1px 5px -2px rgba(0, 0, 0, 0.4);
      margin: 0.5em 0;
    }
    
    .sortable-handle {
      padding: 0.3em 0.5em;
      margin-right: 0.5em;
      cursor: ns-resize;
      color: #888;
      transition: color 0.3s, transform 0.3s;
    }
    
    .sortable-handle::before {
      content: "⋮⋮";
    }
    
    .sortable-handle:hover {
      color: #863da6;
      transform: scale(1.2);
    }
    
    .removeNode {
      margin-left: auto;
      cursor: pointer;
      user-select: none;
      border-radius: 50%;
      background: #eee;
      border: 0;
      width: 2em;
      height: 2em;
      transition: background 0.3s, transform 0.3s;
    }
    
    .removeNode:hover {
      background: #fe0306;
      color: #fff;
      transform: scale(1.2);
    }
    
    .removeNode::after {
      content: "✕"
    }
    
    .sortable li.ui-sortable-helper {
      background: #fff;
      box-shadow: inset 4px 0 0 #863da6, 0 0.1rem 0.5rem rgba(0, 0, 0, 0.3);
    }
    
    .sortable li.ui-sortable-placeholder {
      visibility: visible !important;
      background: #f0eefc;
      outline: 2px dashed #863da6;
      outline-offset: -4px;
      box-shadow: none;
    }
    <ul id="second-list" class="sortable">
      <li><span class="sortable-handle"></span> Boolean Field 1 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
      <li><span class="sortable-handle"></span> Boolean Field 2 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
      <li><span class="sortable-handle"></span> Boolean Field 3 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
      <li><span class="sortable-handle"></span> Boolean Field 4 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
      <li><span class="sortable-handle"></span> Boolean Field 5 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
      <li><span class="sortable-handle"></span> Boolean Field 6 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
      <li><span class="sortable-handle"></span> Boolean Field 7 <button class="removeNode" type="button" aria-label="Remove node"></button></li>
    </ul>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>