【JQuery】エクスプローラーのようなフォルダーツリーを作ってみる(その2)
おはようございます。
少し間が空きましたが、引き続きエクスプローラー風ツリーのサンプルです。
今回はドラッグアンドドロップでフォルダ移動できるようにしてみました。
スポンサーリンク
画面の修正
基本的に大した修正はしていません。
- 説明文の変更
- JQuery-UIの読み込み
- CSSスタイルの追加
といった感じ。
CSS
css/style.css
次のスタイルを追加
/** * ドラッグヘルパー */ .helper { border : 2px solid gray; opacity : 1; background-color: #FFFFFF; margin: 15px; } .helper > i.fa-check { color: green; }
html
sampleTree.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>サンプルツリー</title> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css"> <link rel="stylesheet" href="css/style.css"> </head> <body class="hold-transition fixed skin-blue-light sidebar-mini "> <div class="wrapper" > <div style="margin: 20px;"> <pre> ツリーのサンプル 矢印をシングルクリックでフォルダの開閉、その他の部分はダブルクリックで開閉します。 フォルダをドラッグアンドドロップで移動できます。 </pre> </div> <div> <ul class="tree" data-widget="tree"> <li> <div> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fas fa-angle-right"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">フォルダー1</span> </div> <ul style="display:none;"> <li> <div class="selected"> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー1-1</span> </div> </li> <li> <div> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fas fa-angle-right"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー1-2</span> </div> <ul style="display:none;"> <li> <div class="selected"> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー1-2-1</span> </div> </li> <li> <div> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー1-2-2</span> </div> </li> </ul> </li> </ul> </li> <li> <div> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fas fa-angle-right"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">フォルダー2</span> </div> <ul style="display:none;"> <li> <div class="selected"> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー2-1</span> </div> </li> <li> <div> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー2-2</span> </div> </li> <li> <div> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー2-3</span> </div> </li> <li> <div> <span><i class="fa-none"></i></span> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">サブフォルダー2-4</span> </div> </li> </ul> </li> <li> <div> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">フォルダー3</span> </div> </li> <li> <div> <span><i class="fa-none"></i></span> <span class="tree-icon-arrow"><i class="fa-none"></i></span> <span class="tree-icon-folder"><i class="far fa-folder"></i></span> <span class="tree-title">フォルダー4</span> </div> </li> </ul> </div> </div> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> <script src="js/sampleTree.js"></script> </body> </html>
スクリプト
javascript
script/sampleTree.js
次の処理を追加。
// フォルダーをドラッグ可能に var dragable = $(".tree div").draggable({ axis: "auto" , opacity: 1 , cursor: "move" , cursorAt: { top: 10, left: 50 } , helper: function( event ) { var target = $(event.currentTarget).find(".tree-title").text(); return $( "<div class='helper' style='padding:5px 10px;'><i class='fa fa-check'></i>" + target + "</div>" ); } }); // ドロップ可能エリアの指定 $(".tree div").droppable({ accept: ".tree div", drop: function( event, ui ) { var target = ui.draggable.parent("li"); var parentDir = target.parent("ul"); var dest = $(event.target).parent("li"); var subDir = $(event.target).next(); var from_hierarchy = ui.draggable.parents("ul").length; var to_hierarchy = $(event.target).parents("ul").length + 1; // インデントの調整 if (from_hierarchy < to_hierarchy) { // 下階層への移動 target.find("div").each(function(index, element) { for (let i = 0; i < (to_hierarchy - from_hierarchy); i++) { $(this).prepend("<span><i class='fa-none'></i></span>"); } }); } else { // 上階層への移動 target.find("div").each(function(index, element) { for (let i = 0; i < (from_hierarchy - to_hierarchy); i++) { if ($(this).find("span").length > 0) { $(this).find("span").get(0).remove(); } } }); } // フォルダ移動 if (subDir.length > 0) { // サブフォルダが存在する場合はそのまま追加 subDir.append(target); } else { // サブフォルダが存在しない場合は要素を追加 dest.find(".tree-icon-arrow").children("i").toggleClass("fas fa-angle-down fa-none"); dest.find(".tree-icon-folder").children("i").toggleClass("fa-folder fa-folder-open"); dest.append(target); target.wrap("<ul></ul>") } // 移動元のフォルダが空になった場合 if (parentDir.children("li").length == 0) { var div = parentDir.prev(); div.find(".tree-icon-arrow").children("i").toggleClass("fas fa-angle-down fa-none"); div.find(".tree-icon-folder").children("i").toggleClass("fa-folder fa-folder-open") parentDir.remove(); } } });
サンプルイメージ
フォルダー3をドラッグしているところ。
フォルダー4へ、フォルダー3が移動しました。
元々サブフォルダーがないフォルダーでしたが、フォルダーイメージと展開しているアイコンもちゃんとなってます。
サブフォルダーありフォルダーの移動。
問題なく移動できました。
まとめ
今回は JQuery-UI の Draggable、Droppable 機能を利用しました。
JQuery便利ですね。
これを自力で実装しようと思ったらなかなかに大変だと思います。
次回はもしかしたら、移動できるフォルダかどうかの判定なんかをやってみようかなと。
何かのお役に立てれば。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません