はじめに
※本当はチェックボックスを選択した時に、子ノードを disabled にしたかったのですが、
そういうオプションがないので実装できませんでした . . .
(ツリーをまるごと disabled にすることは可能)
そこで今回はその代用として、dynatreeで以下のような動きを実装する方法を記載します。
実装する挙動
チェックボックス:選択時
→・子ノードのチェックボックスを全て外す
→・子ノードのチェックボックスを選択できないようにする(フォントの色は変化しない)
チェックボックス:選択解除時
→・子ノードのチェックボックスを選択できるようにする
(チェックボックスは全て外れたまま)
※チェックボックス:選択時に子ノードのチェックボックスを全てONにしたい場合は、selectMode: 3
とすればOKです。
実装する(onSelect)
ソースコードの全体像はこのページの末尾に記載します。
ここではツリーの構成を示す children オプションと、チェックボックスを押したときの動きを制御する onSelect オプションに関してのみ抜粋して記載します。
// children ここでツリーのノードを初期化することができます。
children: [
// title 表示名を指定します。
{title: "ファイル1"},
// isFolder フォルダかどうか指定します。
{title: "フォルダ", isFolder: true,
children: [
{title: "子ファイル1"},
{title: "子ファイル2"}
]
},
{title: "ファイル2",
children: [
{title: "子ファイル3"},
{title: "子ファイル4"}
]
}
],
// onSelect チェックボックスを選択または選択解除した時の処理を書きます。
// 第1引数(flag): 選択ならtrue、選択解除ならfalse
// 第2引数(dtnode): 選んだノードの情報
onSelect: function(flag, dtnode) {
// 選択時(→ flag = true)
if (flag) {
// visit 全ての子ノードに対して処理を実行します
dtnode.visit(function(childNode) {
// 子ノードを選択解除します
childNode.select(false);
// 子ノードを選択不可にします
childNode.data.unselectable = true;
});
}
// 選択解除時(→ flag = false)
else {
dtnode.visit(function(childNode) {
// 子ノードを選択可に戻します
childNode.data.unselectable = false;
});
}
}
補足
◆ 使用したコマンドに関して
今回使用した、onSelect , node.visit , node.select , node.data.unselectable 等に関しては、後述のマニュアルに説明が載っているので、ご参照ください。
コマンド | マニュアル内の記載場所 |
---|---|
onSelect | 4.1 Tree options / 5.3 Handling selection events |
node.visit | 8.3 DynaTreeNode class members |
node.select | 8.3 DynaTreeNode class members |
node.data.unselectable | 4.2.1 Node options / 8.3 DynaTreeNode class members の Attribute 'data' |
node.data.~ だけ補足しておくと、
node.data.~ とすることで、childrenで設定できるオプション(title や isFolder など)の値を参照できます。
ただし、変更するオプションによっては、node.render() によってノードを再描画する必要があります。(今回は必要なし)
// 例1. チェックボックス選択時、子ノードの名称変更(title)
...
// 選択時(→ flag = true)
if(flag) {
dtnode.visit(function(childNode) {
// 子ファイル名を「hoge」に変更
childNode.data.title = "hoge";
// 子ノードを再描画
childNode.render();
});
}
...
// 例2. チェックボックス選択時、 ファイルアイコン → フォルダアイコンに変更(isFolder)
...
// 選択時(→ flag = true)
if(flag) {
// 選択したノード(dtnode)を「 isFolder: true 」に設定
dtnode.data.isFolder = true;
// 選択したノードを再描画
dtnode.render();
}
...
◆ dynatree の参考資料
dynatreeの仕様に関しては色々調べた中では、マニュアルが一番丁寧かつ詳しく説明されていたので、
まずはそちらに目を通してみることをお勧めします。
また、古いバージョンのマニュアルより新しいバージョンのマニュアルの方が、情報に漏れがなくより分かりやすい内容になっているので、
ネットで(古い)マニュアルのページを見るよりも、新しいバージョンのマニュアルをダウンロードすることをお勧めします。
(扱っているdynatreeのバージョンが古い場合、使えない機能があるかもしれないのでご注意ください)
新しいバージョンのマニュアルは https://github.com/mar10/dynatree で、Code > Download ZIP
で dynatree-master.zip をダウンロードして、zipファイル内の
dynatree-master\doc\dynatree-doc.html を開けば見ることができます。
◆ソースコード全体
ソースコードはこちらから拝借しました。(一部変更)
<html><head>
<meta charset="utf-8">
<link href="css/skin-vista/ui.dynatree.css" rel="stylesheet" type="text/css" id="skinSheet">
<style type="text/css">
<!--body {width: 400px;}-->
</style>
</head>
<body>
<h5>Dynatreeのサンプルです。</h5>
<div id="tree"></div>
<script type="text/javascript" src="js/jquery-3.5.1.js"></script>
<script type="text/javascript" src="js/jquery-ui.custom.js"></script>
<script type="text/javascript" src="js/jquery.dynatree.js"></script>
<script>
var tree = $("#tree").dynatree({
// children ここでツリーのノードを初期化することができます。
children: [
// title 表示名を指定します。
{title: "ファイル1"},
// isFolder フォルダかどうか指定します。
{title: "フォルダ", isFolder: true,
children: [
{title: "子ファイル1"},
{title: "子ファイル2"}
]
},
{title: "ファイル2",
children: [
{title: "子ファイル3"},
{title: "子ファイル4"}
]
}
],
// checkbox チェックボックスの表示非表示を指定します。
checkbox: true,
// selectMode チェックボックスの選択形式を指定します。 1:単一, 2:複数, 3:複数で親選択時、子も全選択される
selectMode: 2,
// ◆◆◆◆◆ 今回の実装部分: ここから ↓↓ ◆◆◆◆◆
// onSelect チェックボックスを選択または選択解除した時の処理を書きます。
// (第1引数(flag): 選択ならtrue、選択解除ならfalse; 第2引数(dtnode): 選んだノードの情報)
onSelect: function(flag, dtnode) {
// 選択時(→ flag = true)
if (flag) {
// visit 全ての子ノードに対して処理を実行します
dtnode.visit(function(childNode) {
// 子ノードを選択解除します
childNode.select(false);
// 子ノードを選択不可にします
childNode.data.unselectable = true;
});
}
// 選択解除時(→ flag = false)
else {
dtnode.visit(function(childNode) {
// 子ノードを選択可に戻します
childNode.data.unselectable = false;
});
}
}
// ◆◆◆◆◆ 今回の実装部分: ここまで ↑↑ ◆◆◆◆◆
});
</script>
</body></html>