新規投稿
フォローする

jKanbanを使ってカンバン方式のタスク管理

カンバン方式のタスク管理を取り入れると、仕事の見える化により効率が上がるそうです。 今回は、カンバン方式のタスク管理を簡単に実装できる、jKanbanを紹介します。

サンプル

・「+」ボタンからタスクを作成。(Enterで決定)
・ドラッグアンドドロップで状態を変更。
・クリックでタスクを非表示。

フォーム設定

コード

HTML(カスタマイズビュー)

<link rel="stylesheet" href="//your-domain/path/jkanban.min.css">
<link rel="stylesheet" href="//your-domain/path/sample.css">
<div id="kanban"></div>

※モバイル版に対応するため、カスタマイズビューのHTMLからCSSを読み込んでいます。
パソコン表示のみ行う場合は、通常通り「JavaScript / CSSでカスタマイズ > PC用のCSSファイル」からの読み込みで問題ありません。

JavaScript

jkanban.min.jsを読み込み後、下記sample.jsを読み込みます。

・sample.js

(function(){
  "use strict";
  kintone.events.on([
    'app.record.index.show',
    'mobile.app.record.index.show',
  ], function(event){
    if(event.viewName !== 'カンバン') return;
    var fieldCodes = {
      task: 'タスク',
      state: '状態',
      show: '表示'
    };
    var app;
    if(event.type === 'app.record.index.show'){
      app = kintone.app.getId();
    }else{
      document.querySelector('meta[name="viewport"]').setAttribute('content', 'width=701, initial-scale=1.0, user-scalable=yes, maximum-scale=1.0');
      app = kintone.mobile.app.getId();
    }
    kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', {app: app}).then(function(response){
      var options = response.properties[fieldCodes.state].options;
      var elements = Object.keys(options).reduce(function(elements, option){
        elements[option] = [];
        return elements;
      }, {});
      kintone.api(kintone.api.url('/k/v1/records', true), 'GET', {
        app: app,
        query: '作成者 in (LOGINUSER()) and ' + fieldCodes.show + ' in ("on") order by レコード番号 asc'
      }).then(function(response){
        response.records.forEach(function(record){
          elements[record[fieldCodes.state].value].push({
            id: record.レコード番号.value,
            title: record[fieldCodes.task].value
          });
        });
        var kanban = new jKanban({
          element: '#kanban',
          responsivePercentage: true,
          boards: Object.keys(options).map(function(option){
            return options[option];
          }).sort(function(a, b){
            if(a.index < b.index) return -1;
            else return 1;
          }).map(function(option){
            return {
              id: option.label,
              title: option.label,
              item: elements[option.label]
            };
          }),
          dragBoards: false,
          addItemButton: true,
          click: function(el){
            if(!confirm('非表示にしますか?')) return;
            var record = {};
            record[fieldCodes.show] = {value: 'off'};
            kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', {
              app: app,
              id: el.dataset.eid,
              record: record
            });
            kanban.removeElement(el.dataset.eid);
          },
          dropEl: function(el, target){
            var record = {};
            record[fieldCodes.state] = {value: target.parentNode.dataset.id};
            kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', {
              app: app,
              id: el.dataset.eid,
              record: record
            });
          },
          buttonClick: function(el, boardId){
            var form = document.createElement('form');
            form.appendChild(document.createElement('input'));
            kanban.addForm(boardId, form);
            form.childNodes[0].focus();
            form.addEventListener('submit', function(e){
              e.preventDefault();
              var record = {};
              record[fieldCodes.task] = {value: e.target[0].value};
              record[fieldCodes.state] = {value: boardId};
              kintone.api(kintone.api.url('/k/v1/record', true), 'POST', {
                app: app,
                record: record
              }).then(function(response){
                kanban.addElement(boardId, {
                  id: response.id,
                  title: e.target[0].value
                });
              });
              form.parentNode.removeChild(form);
            });
          }
        });
      });
    });
  });
})();

※ウィンドウ幅700px以下で要素をドラッグできなくなるjKanbanのバグ(?)に対応するため、モバイル版ではviewportの幅を変更しています。 他に良い方法があればコメントお願いします。

CSS

jkanban.min.cssを読み込み後、下記sample.cssを読み込みます。
※モバイル版に対応する場合は、前述の通りカスタマイズビューのHTMLからCSSを読み込みます。

・sample.css

.kanban-board:not(:first-child) .kanban-title-button{
  display: none;
}

サンプルは個人での利用を想定し作成していますが、カスタマイズすれば複数人での利用もできるかと思います。

3

3件のコメント

Avatar
つらみ川しんど太郎

いつもお世話になっております。

当方、PCのみ利用の為、カスタマイズビューは利用せず、

・jkanban.min.js

・sample.js

・jkanban.min.css

・sample.css

のみ導入しております。

変更を適用しても何も反映されず、Chromeのコンソール上も特にバグがありません。

しかし、JSEdit等で編集するとjkanban.min.jsに大量の警告があるのですが、

kintoneのバージョンアップ等で対象のライブラリが利用不可能な状態になっていたりしますでしょうか。

 

もしお時間ありましたら、ご教授頂きたくお願い申し上げます。

0
Avatar
neenya

こちらのカスタマイズの仕方を教えていただきたいのですが、看板を実装するのは出来ました。

カンバンをクリックすると、下記のコードで『非表示にしますか?』のアラートが出るのですが、

そうではなく、カンバンクリックでレコードの詳細画面を表示させたいです。

この場合はどのようにカスタマイズしたらよいでしょうか?

ぜひご教示いただければ幸いです。

click: function(el){
if(!confirm('非表示にしますか?')) return;
var record = {};
record[fieldCodes.show] = {value: 'off'};
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', {
app: app,
id: el.dataset.eid,
record: record
});
kanban.removeElement(el.dataset.eid);
},

0
Avatar
江田篤史

neenya様

お世話になっております.

返信が遅くなり申し訳ございません.
コメントありがとうございます.

下記で実装できると思います.

click: function(el){
location.href = './show#record=' + el.dataset.eid;
},
0
サインインしてコメントを残してください。