Giter Club home page Giter Club logo

treesortable's Introduction

Tree Sortable

A drag and drop list item sorting and level changing library.

treeSortableBanner

Motivation

The jQuery-ui's sortable plugin allows us to sort items vertically or horizontally. But sometimes we need some items to make a child of another item and also need to sort a parent with all of the children items. This is the reason why I've created this library for managing the parent-children relationship of list items and fully by drag and drop.

Installation

Download the required files from the Github. Use the treeSortable.js and treeSortable.css files to your project. You also need to use jQuery and jQuery-ui libraries.

In the <head> tag use the css files.

<link href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<link href="/path/to/treeSortable.css" rel="stylesheet" />

Before the </body> tag

<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="/path/to/treeSortable.js"></script>

Usage

Create a ul element with some ID attribute.

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

Then generate an array of object with the exact structure defined below. In the data structure the ordering is important, the tree will be rendered according to this order.

const data = [
	{
		id: 1,
		level: 1,
		parent_id: 0,
		title: 'Branch 1'
	},
	{
		id: 2,
		level: 2,
		parent_id: 1,
		title: 'Branch 2'
	},
	.
	.
	.
]

Now we are gonna create an instance of the tree sortable. And we can pass an options object as the constructor of the TreeSortable.

const sortable = new TreeSortable({
	treeSelector: '#tree'
});

Now create the HTML content of the tree from the data we've declared earlier, and append the $content to the <ul> element.

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

Finally, run the sortable for making it interactive.

sortable.run();

Change sortable options

You can pass customized options to the sortable while instantiating the function. All the options has the default values.

Options

Option Default Description
treeSortable #tree The tree root ID selector. If you change the root selector then you have to update the CSS as per requirements.
branchSelector .tree-branch The tree branch class selector. This need to be applied at the li element of the tree.
branchPathSelector .branch-path The left side path indication element's class selector.
dragHandlerSelector .branch-drag-handler The drag element. This element is responsible for enabling the dragging features of the branch.
placeholderName sortable-placeholder The placeholder name. This is for jquery-ui sortable. Note that there is no dot(.) or hash(#). See the jquery-ui sortable library.
childrenBusSelector .children-bus The children bus selector. This element is responsible for carrying the children on sorting a parent element.
levelPrefix branch-level This prefix is added to the li element and create a level class. For example, for the level 1 branch the class would be .branch-level-1
maxLevel 10 The maximum level the tree could go. For example, if you set the maxLevel to 2 then the branch could have maximum .branch-level-2.
depth 30 The Depth of a child branch. If you change the depth then you have to update the CSS of the .branch-level-X classes. See the treeSortable.css for more references.

For updating the options you could do-

const sortable = new TreeSortable({
	treeSelector: '#someUlId',
	branchSelector: '.some-branch-class-name',
	depth: 20,
	...
})

Note: If you change the class selectors like branchSelector, branchPathSelector etc then you have to take care of the CSS design accordingly.

Event

After each reorder or level change an event is fired for further operations.

sortable.onSortCompleted(function(event, ui) {
	// here the `event` is the sortable event.
	// The `ui` is the jquery-ui's ui object.
	// You can use the `ui.item`, `ui.helper` and so on.
	// See https://api.jqueryui.com/sortable/
});

You can perform async operations here as well. make the callback function asynchronous in that case.

sortable.onSortCompleted(async function(event, ui) {
	await updateDatabaseAsync();
});

Add child, Add sibling, delete branch.

There are some functions provided to the library for adding child branch, sibling branch or delete branches recursively. The sortable instance provides you an event listener that gives you the ability to attach any event listener for a specific instance. This is basically a wrapper function of the original jQuery's event listener but this is more TreeSortable instance specific.

sortable.addListener('click', '.add-child', function (event, instance) {
	event.preventDefault();
	instance.addChildBranch($(event.target));
});

For adding sibling-

sortable.addListener('click', '.add-child', function (event, instance) {
	event.preventDefault();
	instance.addSiblingBranch($(event.target));
});

For deleting branch-

sortable.addListener('click', '.remove-branch', function (event, instance) {
	event.preventDefault();

	const confirm = window.confirm('Are you sure you want to delete this branch?');
	if (!confirm) {
			return;
	}
	instance.removeBranch($(this));
});

Contribution

If you find any issues please raise issue on github. Also if you want to contribute the plugin then create a PR. This library is fully functional if your data structure satisfied the described situation. But this may not be perfect for some other situation. If you need any customization then ping me on [email protected].

treesortable's People

Contributors

ahamed avatar karamelikli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

treesortable's Issues

The tree structure breaks when the parents and childs are not in ascending order.

In my project, I am using this plugin but when I integrated the tree structure data with my database such that the data is also saved in the MySQL database to save the id, parent, level, title and return me the saved tree structure when I reload the page but when I refresh the page the tree structure breaks, It is because now the parent and child are not one after another in a structured format from top to bottom , i.e random for every branch and not in ascending order.

The data structure should be in ascending order of the parents and childs otherwise the tree breaks !!!
But it's not possible because parents, childs and siblings of the tree is created randomly and when we drag and drop the tree structure will differ, hence the tree breaks .

Possible to get user input before creating a new branch ?

Hello,

The implementation is so perfect for me, except

When I click on either of the Add button, is there any way to edit the name of the created branch ?
Possibly like, even after creating a branch, place an edit button too along with the three and once we click it an event for it,
where we can possible use modals or something.

P.S: I am not a full-on JS developer, so can't work on this idea.

Any help is much appreciated. Thanks.

onSortCompleted triggered for every list on page

If you use two (or more) sortables on one page and e.g. use this code.

<ul id="tree1"></ul>
<ul id="tree2"></ul>

The Script looks like this.

(document).ready(function () {

    const data1 = [
        { id: 1, parent_id: 0, title: 'Europe', level: 1 },
        { id: 2, parent_id: 1, title: 'Asia', level: 2 },
        { id: 3, parent_id: 1, title: 'Africa', level: 2 },
    ];

    const data2 = [
        { id: 1, parent_id: 0, title: 'Ohio', level: 1 },
        { id: 2, parent_id: 1, title: 'Texas', level: 2 },
        { id: 3, parent_id: 1, title: 'California', level: 2 },
    ];

    const sortable1 = new TreeSortable();
    const $tree1 = $('#tree1');
    const $content1 = data1.map(sortable1.createBranch);
    $tree1.html($content1);

    sortable1.options = {
        depth: 30,
        treeSelector: '#tree1',
        branchSelector: '.tree-branch',
        branchPathSelector: '.branch-path',
        dragHandlerSelector: '.branch-drag-handler',
        placeholderName: 'sortable-placeholder',
        childrenBusSelector: '.children-bus',
        levelPrefix: 'branch-level',
        maxLevel: 10,
        dataAttributes: {
            id: 'id',
            parent: 'parent',
            level: 'level'
        },
    }

    sortable1.run();

    sortable1.onSortCompleted(function(event, ui) {
        console.log('continents');
    });

    const sortable2 = new TreeSortable();
    const $tree2 = $('#tree2');
    const $content2 = data2.map(sortable2.createBranch);
    $tree2.html($content2);

    sortable2.options = {
        depth: 30,
        treeSelector: '#tree2',
        branchSelector: '.tree-branch',
        branchPathSelector: '.branch-path',
        dragHandlerSelector: '.branch-drag-handler',
        placeholderName: 'sortable-placeholder',
        childrenBusSelector: '.children-bus',
        levelPrefix: 'branch-level',
        maxLevel: 10,
        dataAttributes: {
            id: 'id',
            parent: 'parent',
            level: 'level'
        },
    }

    sortable2.run();

    sortable2.onSortCompleted(function(event, ui) {
        console.log( 'States');
    });
});

Both lists are shown, can be nested and sorted.

When you complete sorting one of these lists all onSortCompleted() on that site are triggered. If you sort #tree2 only sortable2.onSortCompleted() should be triggered.

how I can get the JSON data from UI

Hello Sajeeb!

Could you tell me how I can get the JSON data?

Without this way, I can't use this.

Looking forward to your reply

Best regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.