Implementing Drag-and-Drop Sorting for Custom Menus with Knockout-Sortable

The key implementation involves adding sortable bindings to menu containers. Here's the essential HTML structure:

<div class="row">
    <div class="col-lg-12 full-width" id="leftMenus">
        <div class="col-lg-12">
            <div class="dd" id="ddMenus" data-bind="if:MenuItems">
                <ol class="dd-list" data-bind="sortable:{template: 'menuTemplate', data: MenuItems, afterMove: $root.handleDrop }">
                </ol>
            </div>
        </div>
    </div>
</div>

<script id="menuTemplate" type="text/html">
    <li class="dd-item lv1">
        <div class="dd-handle">
            <span class="pull-right">
                <i class="fa fa-plus" data-bind="click:$root.addMenuItem"></i>   
                <i class="fa fa-times" data-bind="click:$root.deleteItem"></i>  
                <i class="fa fa-pencil" data-bind="click:$root.editItem"></i>
            </span>
            <span>
                <span class="label label-info"><i class="fa" data-bind="css:$root.getIconClass(type)"></i></span>
                <span data-bind="text:title,click:$root.editItem" style="margin-left:10px;"></span>
            </span>
        </div>
        <!-- ko if:$data.children -->
        <ol class="dd-list" data-bind="sortable:{template: 'submenuTemplate', data: $data.children, afterMove: $root.handleDrop }">
        </ol>
        <!-- /ko -->
    </li>
</script>

Important implemantation details:

  • sortable binding: Enables drag-and-drop functionality for the menu items
  • afterMove event: Triggered when an item is dropped after dragging

The drop event handler manages data refresh:

this.handleDrop = function() {
    self.updateMenuData();
};

this.updateMenuData = function(menuData) {
    var menuItems = menuData || ko.mapping.toJS(self.MenuItems());
    self.MenuItems([]);
    self.MenuItems(menuItems);
};

This approach ensures the UI updates correctly after drag operations by refreshing the underlying data.

The knockout-sortable library automatically updates observableArrays during drag operations, making it ideal for implementing sortable interfaces. The library requires:

  • Knockout 2.0+
  • jQuery
  • jQuery UI

Official examples demonstrate various use cases including simple lists, connected lists, draggable elements, and complex arrangements like seating charts.

Tags: knockout-sortable drag-and-drop KnockoutJS jquery-ui Sorting

Posted on Wed, 19 Aug 2026 16:56:14 +0000 by Plakhotnik