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.
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'
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");
};
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;
};