プロジェクト切り替え時にウォッチャーを変えたいのだけどうまくいかないといった問い合わせもらったので、サンプルコード書いてみました。
入力フォーム差し替えと絡んでハマりそうな箇所なので、他の方の参考にもなればと思います。
入力フォームの差し替え
プロジェクトやステータス、トラッカーを切り替えた際には、入力フォーム自体が差し替えられます。サーバ側を呼び出して、受け取ったHTMLの断片で差し替えるようなイメージです。
チケットの題名や説明、カスタムフィールドなどは、空の入力フォームを作った後に、もともと設定されていた情報に移し替えています。
ただ、ウォッチャーのところは、チェックの付与情報自体が付いたHTMLがサーバ側からかえってきて、それをそのまま差し替えるだけです。(サーバ呼び出しの際にフォームの情報も送っている)
そのため、サーバの呼び出しが行われた後に画面側の情報を変えてもそれが反映されません。
ということで、サーバ側呼び出しの前に画面側を変えてあげる必要がありますが、そうなるとイベントのキャプチャフェーズで拾ってあげる必要があります。jQueryではキャプチャフェーズを指定できないので、addEventListenerで指定する形となります。
設定内容
- Path pattern:
/issues/
- Insertion position:
Head of all pages
$(function() { const checkWatcher = function(userId) { if ($('#issue_watcher_user_ids_' + userId).length == 0) { // When the number of users exceeds 20, the check box is not initially displayed, so add a check box. const label = $('<label>').attr({ id: 'issue_watcher_user_ids_' + userId, class: 'floating' }).append( $('<input>').attr({ type: 'checkbox', name: 'issue[watcher_user_ids][]', value: userId }) ); $('#watchers_inputs').append(label); } $('#issue_watcher_user_ids_' + userId + ' input').prop('checked', true); } const changeWatcher = function() { // reset all watchers $('input[name="issue[watcher_user_ids][]"]').prop('checked', false); switch($('#issue_project_id').val()) { case '1': checkWatcher(1); break; case '2': checkWatcher(5); break; case '3': checkWatcher(6); break; } }; const allAttributes = document.getElementById('all_attributes'); if (!allAttributes) { return; } allAttributes.addEventListener( 'change', function(e) { if (e.target.id == 'issue_project_id') { changeWatcher(); } }, // Capturing phase (To work before updateIssueFrom is executed) true); });
追記@2022-12-25
ユーザ数が20を超えていた場合の考慮を追加しました。
20を超えると、ウォッチャーをチェックするためのチェックボックスが未選択のものだと表示されないため、うまく動きませんでした。