Sortable List View With jQuery - treeSortable

File Size: 15.2 KB
Views Total: 9529
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Sortable List View With jQuery - treeSortable

A minimal sortable tree jQuery plugin that enables the user to reorder items in a list tree via drag and drop. Based on jQuery UI's sortable function.

How to use it:

1. Load the necessary jQuery and jQuery UI in the document.

<link rel="stylesheet" href="/path/to/cdn/jquery-ui.css" />
<script src="/path/to/cdn/jquery-ui.min.js"></script>
<script src="/path/to/cdn/jquery.slim.min.js"></script>

2. Load the jQuery treeSortable plugin's script right before the closing body tag.

<script src="./js/treeSortable.js"></script>

3. Create an empty ul element for the sortable tree:

<ul id="tree"></ul>

4. Define your own tree data in a JS array:

const data = [
  {
    id: 1,
    parent_id: 0,
    title: "Branch 1",
    level: 1,
  },
  {
    id: 2,
    parent_id: 1,
    title: "Branch 1",
    level: 2,
  },
  {
    id: 3,
    parent_id: 1,
    title: "Branch 3",
    level: 2,
  },
  // ...
];

5. Initialize the sortable tree and done:

const sortable = new TreeSortable();

const $tree = $("#tree");
const $content = data.map(sortable.createBranch);
$tree.html($content);

sortable.run();

6. You can also insert static tree data into the tree as follows:

<ul id="tree">
  <li class="tree-branch branch-level-1">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 1</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
  <li class="tree-branch branch-level-2">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 2</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
  <li class="tree-branch branch-level-2">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 3</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
  <li class="tree-branch branch-level-3">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 4</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
  <li class="tree-branch branch-level-3">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 5</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
  <li class="tree-branch branch-level-2">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 6</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
  <li class="tree-branch branch-level-1">
    <div class="contents">
      <div class="branch-drag-handler">
        <span class="branch-title">Branch 7</span>
      </div>
    </div>
    <div class="children-bus"></div>
  </li>
</ul>

7. Here are the example CSS styles for the sortable tree. Feel free to override them to create your own tree styles.

.tree-branch .branch-editor {
  display: none;
}

#tree,
#tree-level-1 {
  padding: 0.1em 0;
  list-style: none;
  margin: 0;
}

.tree-branch,
.tree-branch {
  margin-bottom: 0;
  position: relative;
  user-select: none;
}

.tree-branch > .contents .branch-wrapper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: #fff;
  border: 1px solid #fff;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.15);
  border-radius: 3px;
  min-height: 20px;
  max-width: 450px;
  width: 100%;
  position: relative;
  padding: 10px 15px;
  height: auto;
  gap: 12px;

  line-height: 2.3076923;
  overflow: hidden;
  word-wrap: break-word;
}

.tree-branch > .contents .branch-wrapper .left-sidebar {
  display: flex;
  gap: 12px;
  align-items: center;
  max-width: 280px;
  width: 100%;
}

.right-sidebar {
  opacity: 0;
  transition: 0.3s;
}

.branch-wrapper:hover .right-sidebar {
  opacity: 1;
}

.tree-branch > .contents .branch-wrapper .left-sidebar {
  cursor: pointer;
}

.tree-branch > .contents {
  clear: both;
  line-height: 1.5;
  position: relative;
  margin: 10px 0 0;
}

.contents .branch-drag-handler {
  cursor: move;
}

.branch-drag-handler .icon {
  color: #504e4e;
  margin-right: 5px;
}

.sortable-placeholder {
  border: 1px dashed rgb(63, 63, 63);
  height: 35px;
  max-width: 450px;
  width: 100%;
  margin-top: 10px;
}

.tree-branch.ui-sortable-helper .contents {
  margin-top: 0;
}

.tree-branch.ui-sortable-helper .children-bus .contents {
  margin-top: 10px;
}

.tree-branch .children-bus:empty {
  display: none;
}

.branch-level-1 {
  margin-left: 0px;
}
.branch-level-2 {
  margin-left: 30px;
}
.branch-level-3 {
  margin-left: 60px;
}
.branch-level-4 {
  margin-left: 90px;
}
.branch-level-5 {
  margin-left: 120px;
}
.branch-level-6 {
  margin-left: 150px;
}
.branch-level-7 {
  margin-left: 180px;
}
.branch-level-8 {
  margin-left: 210px;
}
.branch-level-9 {
  margin-left: 240px;
}
.branch-level-10 {
  margin-left: 270px;
}

.branch-level-1 .children-bus {
  margin-left: 0px;
}
.branch-level-2 .children-bus {
  margin-left: -30px;
}
.branch-level-3 .children-bus {
  margin-left: -60px;
}
.branch-level-4 .children-bus {
  margin-left: -90px;
}
.branch-level-5 .children-bus {
  margin-left: -120px;
}
.branch-level-6 .children-bus {
  margin-left: -150px;
}
.branch-level-7 .children-bus {
  margin-left: -180px;
}
.branch-level-8 .children-bus {
  margin-left: -210px;
}
.branch-level-9 .children-bus {
  margin-left: -240px;
}
.branch-level-10 .children-bus {
  margin-left: -270px;
}

.branch-path {
  display: block;
  position: absolute;
  width: 30px;
  height: 98px;
  bottom: 50%;
  left: -12px;
  border: 2px solid #565656;
  border-top: 0;
  border-right: 0;
  padding: 4px 0 0;
  padding-top: 3px;
  border-bottom-left-radius: 6px;
  z-index: -1;
}

8. Default plugin options.

const sortable = new TreeSortable({

  // the Depth of a child branch
  depth: 30,

  // default selectors
  treeSelector: "#tree",
  branchSelector: ".tree-branch",
  branchPathSelector: ".branch-path",
  dragHandlerSelector: ".branch-drag-handler",
  placeholderName: "sortable-placeholder",
  childrenBusSelector: ".children-bus",
  levelPrefix: "branch-level",

  // max number of levels
  maxLevel: 10,

  // default data attributes
  dataAttributes: {
    id: "id",
    parent: "parent",
    level: "level",
  },
  
});

9. Fire an event after the tree has been sorted.

sortable.onSortCompleted(async (event, ui) => {
  // do something
});

10. API methods.

// add child branch
$('.add').addChildBranch();

// add sibling branch
$('.add').addSiblingBranch();

// remove a branch
$('.remove').removeBranch();

Changelog:

2022-10-11

  • Fix the remove branch problem with branch path height

2022-10-08

  • Update the library, make this library more instance specific

2022-09-10

  • Fix a minor bug of variable not found

2022-08-03

  • Fix data attributes issues on branch creation

2022-04-16

  • Add new treeSortable implementation with functional way

2021-02-09

  • JS update

This awesome jQuery plugin is developed by ahamed. For more Advanced Usages, please check the demo page or visit the official website.