Redmineの担当者欄にインクリメンタルサーチをつける(focus、スクロールバー追加)

以下の記事で、Redmineの担当者欄にインクリメンタルサーチを付けれることを知り、対応してみた結果をまとめる。
（参考サイトの組み合わせなので、おもに自分用メモとして）

- [Redmineを4-5年運用している中で挙がってきた細かな要望と対応について](https://qiita.com/iwadara/items/d04e618b4c297544dd90)
  - [要望2-8] 担当者欄を素早く選択できるようにしてほしい

## はじめに
- [Redmineバージョン] 3.3.1.stable
- [view_customize_pluginバージョン] 1.1.4
- [Redmineサーバ環境] 社内オンプレ環境、OS:Windows Server 2012 R2
- [動作確認ブラウザ] Chrome

## 追加で対応したこと
上記記事で触れている[方法](http://blog.enjoyxstudy.com/entry/2017/12/05/000000)を元に、以下へ対応した。

- 元記事での未解決事項
  - 担当者欄をクリックしても一覧表示にならず、何か 1 文字打つと一覧表示が始まる
- あらたに発生した対応事項
  - 担当者候補が多すぎてリストの表示が縦に長くなる

## 設定内容（抜粋）
### 担当者欄をクリックしても一覧表示にならず、何か 1 文字打つと一覧表示が始まる
解決方法：フォームにfocusイベントを追加した。

``` javascript:
.focus(function() {
  jQuery(this).autocomplete("search", "");
})
```

### 担当者候補が多すぎてリストの表示が縦に長くなる
解決方法：スクロールバーを導入した。
（CSSファイルを編集したくなかったので、JQueryでCSSプロパティをいじっている。heightは要調整）

``` javascript:
$('.ui-autocomplete').css({'max-height':'250px','overflow-y':'auto','overflow-x':'hidden','padding-right':'20px'});
```

## 設定内容（全文）
View customize に以下を設定する。

- Path pattern : `/issues`
- Type : `JavaScript`
- Code : 下記

```javascript:View_customize
// 担当者欄にインクリメンタルサーチをつける(Redmine View Customize Plugin)
// http://blog.enjoyxstudy.com/entry/2017/12/05/000000

$(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('');
          }
        }
      })
      .focus(function() {
        jQuery(this).autocomplete("search", "");
      });

    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');
    $('.ui-autocomplete').css({'max-height':'250px','overflow-y':'auto','overflow-x':'hidden','padding-right':'20px'});
  }

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

    _replaceIssueFormWith(html);

    setupAssignedAutocomplete();
  };

  setupAssignedAutocomplete();
});
```

## 参考
- [担当者欄にインクリメンタルサーチをつける(Redmine View Customize Plugin)](http://blog.enjoyxstudy.com/entry/2017/12/05/000000)
- [jQueryUIのautocompleteをフォームクリックで表示する](https://hacknote.jp/archives/24965/)
- [スクロールバーを出現させるオートコンプリート](http://alphasis.info/2011/06/jquery-ui-autocomplete-scrollbar/)