Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!-- ここにメッセージが表示される -->
<div id="show-message">&nbsp;</div>

<!-- ここにカンバンが表示される -->
<div id="kanban-canvas"></div>
              
            
!

CSS

              
                html, body {
  font-family: sans-serif;
}

/* カードの設定 */
.kanban-item .text-red {
  color: crimson;
}
.kanban-item .text-bold {
  font-weight: bold;
}
.kanban-item.orange {
  color: white;
  background-color: darkorange;
}
.kanban-item .item-body img {
  width: 100%;
}
.kanban-item .item-body {
  max-height: 240px;
  overflow: hidden;
}
/* メッセージ表示欄 */
#show-message {
  margin: 0 1% 1rem 1%;
  padding: 0.5rem;
  color: white;
  background-color: mediumturquoise;
}
/* 完了したカードのテキストを灰色にして取り消し線を入れる */
.kanban-item.done {
  color: gray;
  text-decoration: line-through;
  background-color: whitesmoke;
}
/* 完了したカードの画像を75%モノクロにして薄く表示する */
.kanban-item.done img {
  filter: grayscale(75%);
  opacity: 0.5;
}
/* カラムのタイトルの色 */
.kanban-board header {
  color: white;
  background-color: gray;
}
.kanban-board header.red {
  background-color: crimson;
}
.kanban-board header.blue {
  background-color: royalblue;
}
.kanban-board header.green {
  background-color: green;
}
              
            
!

JS

              
                // カンバンに表示されるカラムやカードを定義
const dataContent = [
  {
    "id": "column-id-1",
    "title": "準備中",
    "class": "red,waiting",
    "item": [
      {
        "id": "item-id-1",
        "title": "AAA",
        "class": "todo"
      },
      {
        "id": "item-id-2",
        "title": "BBB",
        "class": "todo,orange",
      }
    ]
  },
  {
    "id": "column-id-2",
    "title": "実行中",
    "class": "blue,in-progress",
    "item": [
      {
        "id": "item-id-3",
        "title": "<div class='item-title'>CCC</div><div class='item-body'><img src='https://i.imgur.com/b1dGytP.jpeg' /></div>",
        "class": "todo"
      }
    ]
  },
  {
    "id": "column-id-3",
    "title": "完了",
    "class": "green,completed",
    "item": [
      {
        "id": "item-id-4",
        "title": "DDD",
        "class": "done"
      },
      {
        "id": "item-id-5",
        "title": "EEE",
        "class": "done"
      }
    ]
  }
];

// ここで jKanban を実行する
const kanban = new jKanban({
  element: '#kanban-canvas',  // カンバンを表示する場所のID
  boards: dataContent,        // カンバンに表示されるカラムやカードのデータ
  gutter: '16px',             // カンバンの余白
  widthBoard: '250px',        // カラムの幅 (responsivePercentageの「true」設定により無視される)
  responsivePercentage: true, // trueを選択時はカラム幅は%で指定され、gutterとwidthBoardの設定は不要
  dragItems: true,            // trueを選択時はカードをドラッグ可能
  dragBoards: true,           // カラムをドラッグ可能にするかどうか

  // コールバック
  click: function (el) {
    // カードが左クリックされた時に実行
    onKanbanItemClicked(el);
  },
  context: function (el, event) {
    // カードが右クリックされた時に実行
  },
  dragEl: function (el, source) {
    // カードのドラッグが始まった時に実行
  },
  dragendEl: function (el) {
    // カードがドラッグが終わった時に実行
  },
  dropEl: function (el, target, source, sibling) {
    // カードがドロップされたときに実行
    onKanbanItemDropped(el, target, source, sibling);
  },
  dragBoard: function (el, source) {
    // カラムのドラッグを開始した時に実行
  },
  dragendBoard: function (el) {
    // カラムのドラッグが終わった時に実行
  },
  buttonClick: function(el, boardId) {
    // ボタンがクリックされた時に実行
  }
});

function onKanbanItemClicked(el) {
  showMessage('カード「' + el.innerText + '」が左クリックされました。');
}

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');
  }

}

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');
  }
}

function showMessage(msg) {
  document.getElementById('show-message').innerHTML = msg;
}

// カードに data-class= 属性が設定されていたら、
// その値を取得してクラス名に追加する。
// 今回はカンマ区切りで複数が設定されているので、
// まずは配列に変換してから処理する。
document.querySelectorAll('.kanban-item').forEach(item => {
  if (item.dataset.class) {
    const arrayClass = item.dataset.class.split(',');
    arrayClass.forEach(className => {
      item.classList.add(className);
    });
  }
});
              
            
!
999px

Console