1

Dynamic Sortable

Codepen Version

Description


I have a problem with a dynamic sortable list, which elements should also be sortable. The problem is, that each element in the list is dynamic, as it will be cloned from a template div and appended to document.

Issue


Currently the blocks (.pb-row) are sortable just as expected.
But the nested sortable for the dynamically added widgets (.builder-row-content) doesn`t work.

Only nested nodes in the first block will be draggable and are very buggy. Also i can drag them outside of the row.

Nodes from additionally added Blocks are not draggable at all.

Also i receive this message in the console

cannot call methods on sortable prior to initialization; attempted to call method 'refresh'

Code


Html to run the sortable:

 <div class="pb-rows"> // Wrapper of all Blocks
   <div class="pb-row" name="pb-row"> // each Block
      <div class="builder-row-header">
          <span class="row-btn pb-handle fas fa-sort"></span>
           <div>Block</div>
           <span onclick="handleRemoveClick(this)" class="row-btn row-btn-right pb-remove fas fa-trash"></span>
       </div>
       <div class="pb-container">
          <div class="builder-row-content">
            // nested sortable widgets will appear here
          </div>
       </div>
   </div>
   // more .pb-rows will appear here
 </div>

Attempt for jQuery sortable list:

// jQuery Sorting Lib
jQuery(".pb-rows").sortable({
  handle: ".pb-handle",
  cursor: "grabbing",
});

// jQuery Sorting Lib
jQuery(".builder-row-content").sortable({
  connectWith: '.pb-rows
  handle: ".pb-handle-widget",
  cursor: "grabbing",
});

Attempted solution which doesnt work:

const handleAddClick = e => {
  e.preventDefault();
  ...
  jQuery(".builder-row-content").sortable("refresh");
};

Screenshot


Screenshot of implementation

4
  • A runnable example would be nice. As this is quite a specific problem. Commented Jun 17, 2019 at 9:29
  • ok i will setup a github repo for that :) Commented Jun 17, 2019 at 9:56
  • A codesandbox.io would probably be better as we can then run it in browser :) Commented Jun 17, 2019 at 10:27
  • I created a codepen version for it: codepen.io/pbahr/pen/VJaRay Commented Jun 17, 2019 at 11:14

1 Answer 1

1

You need to reinitialize sortable onto dynamically added elements, so:

Wrap your sortable events in a function

// Sorting
function enableSort() {
  // jQuery Sorting Lib
  $(".pb-rows").sortable({
    handle: ".pb-handle",
    cursor: "grabbing"
  });

  // jQuery Sorting Lib
  $(".builder-row-content").sortable({
    handle: ".pb-handle-widget",
    cursor: "grabbing"
  });
} enableSort();

Then call the function in pbCreateNode.

const pbCreateNode = (type, props, html) => {
  enableSort();
  let element = document.createElement(type);
  props &&
    props.forEach(prop => {
      let key = Object.keys(prop)[0];
      let value = prop[key];
      element.setAttribute(key, value);
    });
  html && (element.innerHTML = html);
  return element;
};

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.