Redmine: チケット一覧のコンテキストメニューをクリック時に処理を挟み込む (View customize plugin)

チケット一覧のコンテキストメニューからステータスを変更しようとした際に、アラートを出したいといった質問があったので調べてみました。

単にイベント差し込めばいいよねと、簡単に考えていましたが、コンテキストメニューを表示しようとしたタイミングでサーバに問い合わせて、DOMを生成していました。しかも、その後に呼ばれるようなメソッドも無いので、フックさせることもできなそうです…

clickイベントをdocumentなどの親要素に対して設定して、click対象が該当の要素だったら制御するようにしようとしましたが、リンクになっているので、親要素にclickイベントが通知されたタイミングでは、すでにリンクが押されてしまっています。

ということで、しょうがないので、クリックする直前(マウスオーバのタイミング)で、リンクを無効にして、さらにクリックイベントを差し込むといった方法を取ることにしました。

/*
Path pattern: /issues$
Type: JavaScript
チケット一覧のコンテキストメニューでステータス変更を無効に
*/
$(function() {
  var handler = function() {
    alert('コンテキストメニューからステータスを却下には出来ません。');
    return false;
  }

  $(document)
    .on('mouseover', '#context-menu a[href*="status_id%5D=6"]', function(event) {
      $(this)
        .attr('href', '#')
        .off('click', handler)
        .on('click', handler);
    });
});

上記は、ステータスを却下にしようとした際に、アラートを表示するサンプルです。

複数回マウスオーバしても問題ないように、設定済みの可能性があるイベントを外してから設定するようにしています。わかりずらいコードになりましたね。。