担当者欄にインクリメンタルサーチをつける(Redmine View Customize Plugin)

この記事は、Redmine Advent Calendar 2017 - Qiitaの5日目の記事となります。


更新@2017-12-29
チケット一覧でエラーが発生していたので、コードを少し変更(対象のIDが存在しない場合、何も処理しない)しました。


前田さんの下記スライドみて、Redmine 4.0 で担当者欄にインクリメンタルサーチが付くことを知りました。

とっても便利そうです。4.0が待ち遠しいですね!

で、4.0が出るまで待てないので、View customize plugin for Redmineで同じようなことをやってみることにしました。

Redmineが jQuery UI 使っているので、Autocomplete | jQuery UI を使っています。イメージとしては、もともとあるプルダウンを非表示にして、担当者をインクリメンタルサーチするためのテキストボックスを追加し、非表示としているプルダウンと同期を取るような形にします。

View customize の設定内容

Path pattern

チケット画面を対象にします。

/issues

Code

Type:JavaScriptとして下記を設定します。

$(function() {

  function replaceSelectToAutocomplete(selectElement) {

    var $select = $(selectElement);
    if ($select.length == 0) {
      return;
    }

    var options = $select.find('option[value!=""]')
      .map(function() {
        var $option = $(this);
        return {
          label: $option.text(),
          optionValue: $option.val()
        };
      })
      .toArray();

    var $autocomplete = $('<input type="text" class="ui-autocomplete-input autocomplete" autocomplete="off">')
      .autocomplete({
        source: options,
        minLength: 0,
        select: function(event, ui) {
          $select.val(ui.item.optionValue);
        },
        change: function(event, ui) {
          if (ui.item != null) {
            return;
          }

          var inputValue = $autocomplete.val();
          var matchOption = $.grep(options, function(option) {
            return option.label == inputValue;
          })[0];

          if (matchOption != null) {
            $select.val(matchOption.optionValue);
          } else {
            $autocomplete.val('');
            $select.val('');
          }
        }});

    var currentSelectValue = $select.val();
    if (currentSelectValue != '') {
      var initAutcompleteValue = $.grep(options, function(option) {
        return option.optionValue == currentSelectValue;
      })[0].label;

      $autocomplete.val(initAutcompleteValue);
    }

    $select.hide()
      .after($autocomplete);
  }

  function setupAssignedAutocomplete() {
    replaceSelectToAutocomplete('#issue_assigned_to_id');
  }

  // ステータス変更時などにDOMが差し替えられるので
  // フォームの内容が書き変わるたびに表示切替
  var _replaceIssueFormWith = replaceIssueFormWith;
  replaceIssueFormWith = function(html){

    _replaceIssueFormWith(html);

    setupAssignedAutocomplete();
  };

  setupAssignedAutocomplete();
});

画面イメージ

下記のような感じになりました。

f:id:onozaty:20171203141830g:plain

6日目は @g_maedaさんです!