JavaScript

完全ガイド:jQuery.nestable.jsでドラッグ&ドロップ対応の入れ子リストを簡単に作成する方法

ウェブ開発における便利なツールの一つに、リストの順序を動的に変更できるjquery.nestable.jsがあります。
今回は、このライブラリを使って、リストタグ(liタグ)の順序をユーザーがドラッグ&ドロップで自由に変えられる機能を紹介します。さらに、変更した順序をJSON形式で出力する方法も解説します。これにより、ウェブサイトでのデータ管理やユーザーインタラクションが格段に向上します。

はじめに:jquery.nestable.jsの基本

jquery.nestable.jsは、HTMLリスト要素を入れ子(ネスト)構造で表示し、その順序をドラッグ&ドロップで編集できるようにするJavaScriptライブラリです。この機能は、タスクの優先順位を調整するToDoリストや、管理画面でのカテゴリー管理など、さまざまな場面で役立ちます。

CSSでのスタイリング

リストの見た目を整える基本的なCSSは次の通りです。.ddクラスがリストのコンテナを指し、.dd-handleクラスが各リストアイテムの「つかむ部分」を表します。この部分をマウスで掴むことで、アイテムのドラッグ&ドロップが可能になります。
liタグ一覧エリア(.nestable-lists)、json形式の出力エリア(#nestable-output)のCSS記述です。

<style>
body {
  margin: 0;
  padding: 0;
  font-size: 20px;
  line-height: 1.8em;
  text-align: center;
}
h1{
  text-align: center;
  font-size: 20px;
  line-height: 1.8em;
  padding: 15px 0;
}

.cf:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}
* html .cf {
  zoom: 1;
}
*:first-child+html .cf {
  zoom: 1;
}

/**
 * Nestable
 */
.dd {
  position: relative;
  display: block;
  margin: 0;
  padding: 0;
  width: 100%;
  list-style: none;
  font-size: 13px;
  line-height: 20px;
}
.dd-list {
  display: block;
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
}
.dd-list .dd-list {
  padding-left: 30px;
}
.dd-collapsed .dd-list {
  display: none;
}
.dd-item, .dd-placeholder {
  display: block;
  position: relative;
  margin: 0;
  padding: 0;
  min-height: 20px;
  font-size: 13px;
  line-height: 20px;
}
.dd-handle {
  display: block;
  height: 30px;
  margin: 5px 0;
  padding: 5px 10px;
  text-decoration: none;
  font-weight: bold;
  border: 1px solid #ccc;
  background: #fafafa;
  background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
  background:    -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
  background:         linear-gradient(top, #fafafa 0%, #eee 100%);
  -webkit-border-radius: 3px;
  border-radius: 3px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
}
.dd-handle:hover {
  color: #2ea8e5;
  background: #fff;
}
.dd-item > button {
  display: block;
  position: relative;
  cursor: pointer;
  float: left;
  width: 25px;
  height: 20px;
  margin: 5px 0;
  padding: 0;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
  border: 0;
  background: transparent;
  font-size: 12px;
  line-height: 1;
  text-align: center;
  font-weight: bold;
}
.dd-item > button:before {
  content: '+';
  display: block;
  position: absolute;
  width: 100%;
  text-align: center;
  text-indent: 0;
}
.dd-item > button[data-action="collapse"]:before {
  content: '-';
}
.dd-placeholder {
  margin: 5px 0;
  padding: 0;
  min-height: 30px;
  background: #f2fbff;
  border: 1px dashed #b6bcbf;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
}
.dd-dragel {
  position: absolute;
  pointer-events: none;
  z-index: 9999;
}
.dd-dragel > .dd-item .dd-handle {
  margin-top: 0;
}
.dd-dragel .dd-handle {
  -webkit-box-shadow: 2px 4px 6px 0 rgba(0,0,0,.1);
  box-shadow: 2px 4px 6px 0 rgba(0,0,0,.1);
}

/**
 * Nestable Extras
 */
.nestable-lists {
  display: block;
  clear: both;
  padding: 30px 15px;
  width: 60%;
  border: 2px solid #ddd;
  margin: 0 auto;
}
#nestable-menu {
  padding: 0;
  margin: 20px 0;
}
#nestable-output{
  width: 70%;
  line-height: 1.4em;
  padding: 10px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
}

.dd-hover > .dd-handle {
  background: #2ea8e5 !important;
}
</style>

HTMLの構造

以下のHTMLマークアップは、ドラッグ&ドロップ可能なリストと、JSON形式でのデータ出力を示しています。#nestableIDを持つdivがリストコンテナであり、#nestable-outputはリストデータの出力先です。
liタグ一覧エリア(class=”nestable-lists”)、json形式の出力エリア(id=”nestable-output”)、liタグ一覧を展開・折りたたむボタン(id=”nestable-menu”)を用意します。

<h1>jquery.nestable.jsを使ってネスト(入れ子)のliタグ一覧をドラッグ&ドロップ可能にします。<br>あわせて、liタグのdata-id値をjson形式で出力します。</h1>

    <menu id="nestable-menu">
        <button type="button" data-action="expand-all">全て展開</button>
        <button type="button" data-action="collapse-all">折りたたむ</button>
    </menu>

    <div class="cf nestable-lists">

        <div class="dd" id="nestable">
            <ol class="dd-list">
                <li class="dd-item" data-id="1">
                    <div class="dd-handle">アイテム1</div>
                </li>
                <li class="dd-item" data-id="2">
                    <div class="dd-handle">アイテム2</div>
                    <ol class="dd-list">
                        <li class="dd-item" data-id="3"><div class="dd-handle">アイテム3</div></li>
                        <li class="dd-item" data-id="4"><div class="dd-handle">アイテム4</div></li>
                        <li class="dd-item" data-id="5">
                            <div class="dd-handle">アイテム5</div>
                            <ol class="dd-list">
                                <li class="dd-item" data-id="6"><div class="dd-handle">アイテム6</div></li>
                                <li class="dd-item" data-id="7"><div class="dd-handle">アイテム7</div></li>
                                <li class="dd-item" data-id="8"><div class="dd-handle">アイテム8</div></li>
                            </ol>
                        </li>
                        <li class="dd-item" data-id="9"><div class="dd-handle">アイテム9</div></li>
                        <li class="dd-item" data-id="10"><div class="dd-handle">アイテム10</div></li>
                    </ol>
                </li>
                <li class="dd-item" data-id="11">
                    <div class="dd-handle">アイテム11</div>
                </li>
                <li class="dd-item" data-id="12">
                    <div class="dd-handle">アイテム12</div>
                </li>
            </ol>
        </div>

    </div><!--/.nestable-lists-->

<br>
<br>
<div align="center">liタグのdata-idの出力結果<br>上記liタグをドラッグすると以下の出力結果順も変わります。</div>
<textarea id="nestable-output"></textarea>

JavaScriptの記述

jquery.nestable.jsを使用してリストを初期化し、リストの変更をJSON形式で出力するJavaScriptコードは以下の通りです。
jquery-3.1.1.min.js、jquery.nestable.jsファイルを読み込みます。$(‘liタグ一覧エリア’).nestable({グループ数})でNestableプラグインをアクティブにし、「初期のシリアル化されたデータを出力」コメント箇所ではliタグのdata-id値をjson形式で出力します。$(‘展開・折りたたむボタン’).on(‘click’,~でネストしたliタグ一覧を展開・折りたたむ処理を記述してます。

<script src="jquery-3.1.1.min.js"></script>
<script src="jquery.nestable.js"></script>
<script>
$(document).ready(function()
{
    var updateOutput = function(e)
    {
        var list   = e.length ? e : $(e.target),
            output = list.data('output');
        if (window.JSON) {
            output.val(window.JSON.stringify(list.nestable('serialize')));
        } else {
            output.val('このデモには、JSON ブラウザーのサポートが必要です。');
        }
    };

    // Nestableをアクティブ
    $('#nestable').nestable({
        group: 1
    })
    .on('change', updateOutput);

    // 初期のシリアル化されたデータを出力
    updateOutput($('#nestable').data('output', $('#nestable-output')));

    $('#nestable-menu').on('click', function(e)
    {
        var target = $(e.target),
            action = target.data('action');
        if (action === 'expand-all') {
            $('.dd').nestable('expandAll');
        }
        if (action === 'collapse-all') {
            $('.dd').nestable('collapseAll');
        }
    });
});
</script>

jquery.nestable.jsを使ってネスト(入れ子)のliタグ一覧をドラッグ&ドロップ可能にするデモページ

実装したデモページは以下より確認できます。

jquery.nestable.jsを使ってネスト(入れ子)のliタグ一覧をドラッグ&ドロップ可能にするデモページ

ソース元:Nestable

Nestable

実用例と応用

この技術は、コンテンツ管理システム(CMS)、プロジェクト管理ツール、教育ツールなど、ユーザーがデータの順序を直感的に管理したい任意のアプリケーションに適用できます。特に、記事のセクションや、講義のモジュールなど、順序が重要な情報の管理に有効です。

まとめ

jquery.nestable.jsは、シンプルながら強力なライブラリで、ウェブ上でのリスト管理とインタラクションを直感的かつ効率的に行うことができます。このツールを使って、ユーザーにとってより良いウェブ体験を提供しましょう。

 

※流用される場合は自己責任でお願いします。
 デモページheadタグ内のGoogleアナリティクスタグは流用しないで下さい。