PHPackages                             pan/ui-nested-sortable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. pan/ui-nested-sortable

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

pan/ui-nested-sortable
======================

263JavaScript

Since Jun 18Pushed 13y ago5 watchersCompare

[ Source](https://github.com/PANmedia/ui-nested-sortable)[ Packagist](https://packagist.org/packages/pan/ui-nested-sortable)[ RSS](/packages/pan-ui-nested-sortable/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

nestedSortable jQuery plugin
============================

[](#nestedsortable-jquery-plugin)

**nestedSortable** is a jQuery plugin that extends jQuery Sortable UI functionalities to nested lists.
*Note: Version 2.0 is published in branch '2.0alpha' and is available for testing. At the moment it has only been tested in Firefox and Chrome, if you work with IE feel free to give it a shot and let me know if something goes wrong.*

What's new in version 2.0
-------------------------

[](#whats-new-in-version-20)

The biggest change is that your nested list can now behave as a tree with expand/collapse funcionality. Simply set `isTree` to **true** in the options and you are good to go! Check the [demo](http://mjsarfatti.com/sandbox/nestedSortable) out to see what can be done with nestedSortable and a little CSS. (Note that all **nestedSortable** does is to assign/remove classes on the fly)
Also:

- **isAllowed** function finally works as expected, see the docs below
- Fixed: a small bug in the **protectRoot** function
- Changed: no drop zone will appear at all if you try to nest an item under another one that has the *no-nesting* class.
- Added: **doNotClear** option to prevent the plugin from deleting empty lists

Features
--------

[](#features)

- Designed to work seamlessly with the [nested](http://articles.sitepoint.com/article/hierarchical-data-database "A Sitepoint tutorial on PHP, MYSQL and nested sets") [set](http://en.wikipedia.org/wiki/Nested_set_model "Wikipedia article on nested sets") model (have a look at the `toArray` method)
- Items can be sorted in their own list, moved across the tree, or nested under other items.
- Sublists are created and deleted on the fly
- All jQuery Sortable options, events and methods are available
- It is possible to define elements that will not accept a new nested item/list and a maximum depth for nested items
- The root level can be protected

Usage
-----

[](#usage)

```

	Some content

		Some content

			Some sub-item content
			Some sub-item content

	Some content

```

```
	$(document).ready(function(){

		$('.sortable').nestedSortable({
			handle: 'div',
			items: 'li',
			toleranceElement: '> div'
		});

	});

```

Please note: every `` must have either one or two direct children, the first one being a container element (such as `` in the above example), and the (optional) second one being the nested list. The container element has to be set as the 'toleranceElement' in the options, and this, or one of its children, as the 'handle'.

Also, the default list type is ``.

*This is the bare minimum to have a working nestedSortable. Check the [demo](http://mjsarfatti.com/sandbox/nestedSortable) out to see what can be accomplished with a little more.*

Custom Options
--------------

[](#custom-options)

 doNotClear (2.0) Set this to true if you don't want empty lists to be removed. Default: **false** expandOnHover (2.0) How long (in ms) to wait before expanding a collapsed node (useful only if `isTree: true`). Default: **700** isAllowed (function) You can specify a custom function to verify if a drop location is allowed. Default: **function (placeholder, placeholderParent, currentItem) { return true; }** isTree (2.0) Set this to true if you want to use the new tree functionality. Default: **false** listType The list type used (ordered or unordered). Default: **ol** maxLevels The maximum depth of nested items the list can accept. If set to '0' the levels are unlimited. Default: 0 protectRoot Whether to protect the root level (i.e. root items can be sorted but not nested, sub-items cannot become root items). Default: **false** rootID The id given to the root element (set this to whatever suits your data structure). Default: **null** rtl Set this to true if you have a right-to-left page. Default: **false** startCollapsed (2.0) Set this to true if you want the plugin to collapse the tree on page load. Default: **false** tabSize How far right or left (in pixels) the item has to travel in order to be nested or to be sent outside its current list. Default: **20**Custom Classes (you will set them in the options as well)
---------------------------------------------------------

[](#custom-classes-you-will-set-them-in-the-options-as-well)

 branchClass (2.0) Given to all items that have children. Default: **mjs-nestedSortable-branch** collapsedClass (2.0) Given to branches that are collapsed. It will be switched to **expandedClass** when hovering for more then **expandOnHover** ms. Default: **mjs-nestedSortable-collapsed** disableNestingClass Given to items that will not accept children. Default: **mjs-nestedSortable-no-nesting** errorClass Given to the placeholder in case of error. Default: **mjs-nestedSortable-error** expandedClass (2.0) Given to branches that are expanded. Default: **mjs-nestedSortable-expanded** hoveringClass (2.0) Given to collapsed branches when dragging an item over them. Default: **mjs-nestedSortable-hovering** leafClass (2.0) Given to items that do not have children. Default: **mjs-nestedSortable-leaf**Custom Methods
--------------

[](#custom-methods)

 serialize Serializes the nested list into a string like **setName\[item1Id\]=parentId&amp;setName\[item2Id\]=parentId**, reading from each item's id formatted as 'setName\_itemId' (where itemId is a number). It accepts the same options as the original Sortable method (**key**, **attribute** and **expression**). toArray Builds an array where each element is in the form: ```
setName[n] =>
{
	'item_id': itemId,
	'parent_id': parentId,
	'depth': depth,
	'left': left,
	'right': right,
}
```

 It accepts the same options as the original Sortable method (**attribute** and **expression**) plus the custom **startDepthCount**, that sets the starting depth number (default is 0). toHierarchy Builds a hierarchical object in the form: ```
'0' ...
	'id' => itemId
'1' ...
	'id' => itemId
	'children' ...
		'0' ...
			'id' => itemId
		'1' ...
			'id' => itemId
'2' ...
	'id' => itemId
```

 Similarly to `toArray`, it accepts **attribute** and **expression** options.Known Bugs
----------

[](#known-bugs)

*nestedSortable* doesn't work properly with connected draggables, because of the way Draggable simulates Sortable `mouseStart` and `mouseStop` events. This bug might or might not be fixed some time in the future (it's not specific to this plugin).

Requirements
------------

[](#requirements)

jQuery UI Sortable 1.10+ (might work with 1.9, but not tested)

Browser Compatibility
---------------------

[](#browser-compatibility)

Tested with: Firefox, Chrome
**NOTE: This is still an alpha version, please test thoroughly in whichever version of IE you target**

License
-------

[](#license)

This work is licensed under the MIT License.
Which means you can do pretty much whatever you want with it.

Nonetheless if this plugin saved you money, saved you time or saved your life please take a moment to think about the work I've been doing for you and consider sharing a bit of your joy with me. Your donation, however small, will be greatly appreciated.
Thank you.

[Donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=RSJEW3N9PRMYY&lc=IT&item_name=Manuele%20Sarfatti&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)

###  Health Score

23

—

LowBetter than 26% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 87.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/134799?v=4)[David Neilsen](/maintainers/Petah)[@Petah](https://github.com/Petah)

---

Top Contributors

[![mjsarfatti](https://avatars.githubusercontent.com/u/736316?v=4)](https://github.com/mjsarfatti "mjsarfatti (51 commits)")[![Bananattack](https://avatars.githubusercontent.com/u/95647?v=4)](https://github.com/Bananattack "Bananattack (2 commits)")[![danielevans](https://avatars.githubusercontent.com/u/419699?v=4)](https://github.com/danielevans "danielevans (2 commits)")[![levacic](https://avatars.githubusercontent.com/u/1636354?v=4)](https://github.com/levacic "levacic (1 commits)")[![vcarel](https://avatars.githubusercontent.com/u/1541093?v=4)](https://github.com/vcarel "vcarel (1 commits)")[![vsn4ik](https://avatars.githubusercontent.com/u/3757319?v=4)](https://github.com/vsn4ik "vsn4ik (1 commits)")

### Embed Badge

![Health badge](/badges/pan-ui-nested-sortable/health.svg)

```
[![Health](https://phpackages.com/badges/pan-ui-nested-sortable/health.svg)](https://phpackages.com/packages/pan-ui-nested-sortable)
```

###  Alternatives

[comocode/laravel-ab

Blade level AB tests for Laravel 5

3139.4k](/packages/comocode-laravel-ab)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
