See the Pen jKanban Example 3 by bunatree (@bunatree) on CodePen.
click: function (el) {}, // カードが左クリックされた時に実行
context: function (el, event) {}, // カードが右クリックされた時に実行
dragEl: function (el, source) {}, // カードのドラッグが始まった時に実行
dragendEl: function (el) {}, // カードがドラッグが終わった時に実行
dropEl: function (el, target, source, sibling) {}, // カードがドロップされたときに実行
dragBoard: function (el, source) {}, // カラムのドラッグを開始した時に実行
dragendBoard: function (el) {}, // カラムのドラッグが終わった時に実行
buttonClick: function(el, boardId) {} // カード追加ボタンがクリックされた時に実行
click と dropEl を使います。click コールバックです。次のように、onKanbanItemClicked 関数が実行されるようにしました。
click: function (el) {
onKanbanItemClicked(el);
},
onKanbanItemClicked 関数は、次のとおりです。
function onKanbanItemClicked(el) {
showMessage('カード「' + el.innerText + '」が左クリックされました。');
}
el は、クリックされたカードの HTML 要素です。そのプロパティである innerText は、カードに表示されているテキストです。showMessage 関数は show-message という id を持つ HTML 要素(青緑バー)にテキストを表示します。
function showMessage(msg) {
document.getElementById('show-message').innerHTML = msg;
}
dropEl コールバックです。次のように、onKanbanItemDropped 関数が実行されるようにしました。
dropEl: function (el, target, source, sibling) {
onKanbanItemDropped(el, target, source, sibling);
},
function onKanbanItemDropped(el, target, source, sibling) {
// 移動元カラムのタイトル
const sourceTitle = source.parentNode.querySelector('header').innerText;
// 移動元カラムのID
const sourceId = source.parentNode.dataset.id;
// 移動先カラムのタイトル
const targetTitle = target.parentNode.querySelector('header').innerText;
// 移動元カラムのID
const targetId = target.parentNode.dataset.id;
// 同じカラム内の移動か、それとも異なるカラム間の移動かを判別
const sameColumn = (sourceId === targetId) ? true : false;
// カラム内 or カラム間の移動によってメッセージを変える
const alertMsg = (sameColumn) ?
'カード「' + el.innerText + '」が、カラム『' + sourceTitle + '』内で移動しました。':
'カード「' + el.innerText + '」が、カラム『' + sourceTitle + '』からカラム『' + targetTitle + '』へ移動しました。';
// メッセージを表示
showMessage(alertMsg);
// 異なるカラム間の移動なおかつ移動先カラムが「完了」の場合
// カードのステータスを「done」にする。
// 異なるカラム間の移動なおかつ移動先カラムが「完了」以外の場合
// カードのステータスを「todo」にする。
if (!sameColumn && targetTitle === '完了') {
setKanbanItemStatus(el, 'done');
} else if (!sameColumn && targetTitle !== '完了') {
setKanbanItemStatus(el, 'todo');
}
}
// 移動元カラムのID
const sourceId = source.parentNode.dataset.id;
// 移動先カラムのID
const targetId = target.parentNode.dataset.id;
source と移動先を表す target の引数はカラム本体の <div class="kanban-board"> 要素ではなく、その子である <main class="kanban-drag"> 要素だということです。source や target の親要素(<div class="kanban-board"> 要素)に data-id= 属性として挿入されているので、parentNode で 1 つ上へ DOM ツリーを登って、それから dataset.id で id の値を取得します。
// 同じカラム内の移動か、それとも異なるカラム間の移動かを判別
const sameColumn = (sourceId === targetId) ? true : false;
setKanbanItemStatus 関数を呼び出しています。
if (!sameColumn && targetTitle === '完了') {
setKanbanItemStatus(el, 'done');
} else if (!sameColumn && targetTitle !== '完了') {
setKanbanItemStatus(el, 'todo');
}
status の値は「done」になり、カードの要素 el から「todo」クラスが削除され、「done」クラスが追加されます。el から「done」クラスが削除され、「todo」クラスが追加されます。
function setKanbanItemStatus(el, status) {
// ステータスが「done」の場合は
// カードの「todo」クラスを「done」に変更する。
if (status === 'done') {
el.classList.remove('todo');
el.classList.add('done');
// ステータスが「done」以外の場合は
// カードの「done」クラスを「todo」に変更する。
} else {
el.classList.remove('done');
el.classList.add('todo');
}
}
<div class="kanban-item"> に「todo」と「done」のどちらかのクラスが追加・削除されます。class プロパティを見てわかるように、「完了」以外のカラムに表示されているカードの HTML 要素には元々「todo」クラスが付いています。
{
"id": "item-id-1",
"title": "AAA",
"class": "todo"
},
{
"id": "item-id-2",
"title": "BBB",
"class": "todo,orange",
}
/* 完了したカードのテキストを灰色にして取り消し線を入れる */
.kanban-item.done {
color: gray;
text-decoration: line-through;
background-color: whitesmoke;
}
/* 完了したカードの画像を75%モノクロにして薄く表示する */
.kanban-item.done img {
filter: grayscale(75%);
opacity: 0.5;
}
jkanban_example3_01.png
jkanban_example3_02.png
jkanban_example_3_03.png
jkanban_example_3_04.png
jkanban_eyecatch.png