読者です 読者をやめる 読者になる 読者になる

Redmine のカスタムフィールド「リスト」をチェックリストとして使う

Redmine のカスタムフィールドには、リストを選択するための書式「リスト」があります。(そのまんま)

その書式で定義したカスタムフィールドを「チェックリスト」として使いたかったのですが、デフォルトの Redmine では使いにくかったので、プラグイン「View Customize Plugin」を使ってカスタマイズした話を書きます。

※これ以降、書式「リスト」のカスタムフィールドのことを 「リストフィールド」 と記載します。

前提

上記プラグインがあれば何でもできるので、ぜひ導入しましょう。

デフォルト Redmine を使ったチェックリストの問題点

デフォルト Redmine で、リストフィールドを利用したチェックリストを実装しようとすると、以下の問題に気が付きます。

  • チケット表示画面では、リストフィールドのチェックされている項目は見えるが、チェックされていない項目が見えない。

具体的に、以下のようなリストフィールドを作成し、チケット入力画面と表示画面を見比べてみます。

カスタムフィールド定義

チェックリスト項目「テスト用リストフィールド」を定義します。

f:id:rabitarochan:20160905184214p:plain

項番 説明
(1) 書式に「リスト」を指定します
(2) 複数選択可にチェックを付けます
(3) 選択肢に、チェックリストの項目を指定します
(4) 表示に「チェックボックス」を指定します

チケット入力画面

作成したリストフィールドは、入力画面では以下のとおり表示されます。

この画面だけだと、チェックリストのように使えるのではないかと思ってしまいます。

f:id:rabitarochan:20160905184219p:plain

チケット表示画面

問題のチケット表示画面です。

赤枠で囲まれている箇所がリストフィールドの表示箇所ですが、チェックした項目のみ表示されており全体が見えません。また、改行もされず読みにくいです。

f:id:rabitarochan:20160905184224p:plain

解決案

解決案としては、チェックボックスをそのまま表示するだけで格段に見やすくなると思います。

今回は、View Customize Plugin を使ってチケット表示画面に JavaScript を適用して解決しようと思います。

解決したスクリプト

早速答え合わせですが、以下の JavaScript を登録することで、カスタムフィールド名に「チェックリスト」が含まれている場合のみチェックリスト表示にしてくれます。

カスタムフィールド名に「チェックリスト」を含むことを条件とした理由は、リストフィールドの本来の使い方をしたい場合と差別化するためです。

Path pattern: /issues/[0-9]+

Type: JavaScript

// カスタムフィールド名に「チェックリスト」が含まれる場合、表示時にチェックボックスを表示する。
$(function () {

  // 処理対象のカスタムフィールドを抽出する。
  var $checklists = [];
  $('.attribute .label span').each(function () {
    var $this = $(this);
    if (!isChecklist($this)) return ;

    var $parent = $this.parent().parent();
    $checklists.push($parent);
  });

  // カスタムフィールドをチェックリスト形式で表示する。
  $.each($checklists, function (i, $this) {
    var id = getCfId($this);
    if (id === null) return;

    var $items = getChecklistItems(id);
    var newHtml = createChecklistHtml($items);

    $this.find('.value').html(newHtml);
  });

  // fun: 処理対象のカスタムフィールドかどうかを判定する
  function isChecklist($this) {
    var label = $this.text();
    return (label.indexOf('チェックリスト') >= 0);
  }

  // fun: カスタムフィールドの id を取得する
  function getCfId($this) {
    var id = $this.attr('class').match(/\d+/);
    if (id === null) return null;
    return id[0];
  }

  // fun: カスタムフィールドのすべての項目を取得します。
  function getChecklistItems(id) {
    var selector = '#issue_custom_field_values_' + id;
    var $items = $(selector).parent().parent().find('label');
    return $items;
  }

  // fun: 表示用の HTML 要素を作成します。
  function createChecklistHtml($items) {
    var html = [];
    $items.each(function () {
      var $this = $(this);
      var $input = $this.find('input');
      var result = '<input type="checkbox" value="test" disabled="true" /> ';

      if ($input.attr('checked')) {
        result = '<input type="checkbox" value="test" checked="checked" disabled="true" /> ';
      }

      result += $input.attr('value');
      html.push(result);
    });

    var newHtml = html.join('<br />')
    return newHtml;
  }

});

適用後の画面

圧倒的見やすさ!

チェックしていない項目も表示されていて、チェック項目の見た目も入力画面と統一できました。これならチェックリストとして使えそうです。

f:id:rabitarochan:20160905185815p:plain

まとめ

Redmine のカスタムフィールドを使ってチェックリストを実現する方法についてまとめました。

ほぼ View Customize Plugin のサンプルみたいな記事ですが、とても便利ですし Redmine魔改造しやすいのでとてもおすすめです。 (時間があれば、カスタムフィールドをグループ化 / 並べ替えするスクリプトも作っているので紹介しようと思います。)

みなさんも便利なスクリプトがあればぜひ教えてください!