t-kurokawa0
@t-kurokawa0

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Redmineの担当者フィルタにSelect2を適用する方法

解決したいこと

Redmineのチケット一覧画面->フィルタ追加->「担当者」で
担当者でフィルタ可能になりますが、
ここで出現する「担当者」フィールドにselect2を適用させ、キーワードフィルタを実装したいと考えています。

👇select2を適用したい担当者フィールド
担当者フィルタ.png

【参考情報】
チケット作成画面ではすでに表示カスタマイズでselect2を実装済みとなり、
これと同様の機能を適用したいのが要件です。

👇チケット作成画面で実装している表示例
image.png

実装済みのselect2適用コード
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script>
    $(document).ready(function() {
        function applySelect2() {
            var $select = $('#issue_assigned_to_id');
            //var $select = $('#values_assigned_to_id_1');
            if ($select.length > 0) {
                $select.select2({
                    width: "100%",
                    placeholder: "担当者を検索...",
                    allowClear: true,
                    matcher: function(params, data) {
                        // 検索条件が空の場合はデータをそのまま返す
                        if (!params.term || $.trim(params.term) === '') {
                            return data;
                        }

                        // optgroup(childrenが存在する要素)を無視
                        if (data.children && data.children.length > 0) {
                            // 子要素を再帰的にチェックし、マッチするものがあればそれを含むデータを返す
                            var filteredChildren = $.grep(data.children, function(child) {
                                return child.text.toLowerCase().includes(params.term.toLowerCase());
                            });

                            if (filteredChildren.length > 0) {
                                return $.extend({}, data, {
                                    children: filteredChildren // マッチした子要素のみを返す
                                });
                            }
                            return null; // 子要素にマッチしない場合はnull
                        }

                        // 通常の要素のマッチング処理
                        var decodedText = $('<div>').html(data.text).text().toLowerCase().trim();
                        var searchTerm = params.term.toLowerCase().trim();

                        if (decodedText.indexOf(searchTerm) > -1) {
                            return data; // 親要素がマッチする場合
                        }

                        return null; // マッチしない場合
                    }
                });
            } else {
                console.log("担当者フィールドが見つかりません");
            }
        }

        // 初期化時にselect2を適用
        applySelect2();


    });
</script>


自分で試したこと

 チケット作成画面での担当者フィールドのオブジェクトID

var $select = $('#issue_assigned_to_id');

上記オブジェクトID(#issue_assigned_to_id)を
フィルタで表示されるID(#values_assigned_to_id_1)へ置き換えてみましたがダメでした。

動的に生成されるフィールドなので非同期的に適用させる必要があるのでしょうか、、、?
とか色々考えましたが、利用者から早めに対処してほしいと圧をかけられており、
質問させていただきました。

よろしくお願いいたします。

0

1Answer

以下のようにしたら実現できるかなと。

パスのパターン:/issues$
挿入位置:全ページのヘッダ
種別:HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script>
    $(document).ready(function() {

        // フィルタ追加した際
        $('#add_filter_select').on('change', function() {
            $(document).on('ajaxSuccess', function() {
                applySelect2();
            })
        })

        // 適用・保存した際
        $(document).on('ajaxSuccess', function() {
            applySelect2();
        })

        // 担当者をクリックした際(念のため)
        $('#filters-table').on('click', '#values_assigned_to_id_1', function() {
            applySelect2();
        })
    });

    function applySelect2() {
        const $select = $('#values_assigned_to_id_1');

        if ($select.length > 0) {
            $select.select2({
                width: "100%",
                placeholder: "担当者を検索...",
                allowClear: true,
                matcher: function(params, data) {
                    // 検索条件が空の場合はデータをそのまま返す
                    if (!params.term || $.trim(params.term) === '') {
                        return data;
                    }

                    // optgroup(childrenが存在する要素)を無視
                    if (data.children && data.children.length > 0) {
                        // 子要素を再帰的にチェックし、マッチするものがあればそれを含むデータを返す
                        var filteredChildren = $.grep(data.children, function(child) {
                            return child.text.toLowerCase().includes(params.term.toLowerCase());
                        });

                        if (filteredChildren.length > 0) {
                            return $.extend({}, data, {
                                children: filteredChildren // マッチした子要素のみを返す
                            });
                        }
                        return null; // 子要素にマッチしない場合はnull
                    }

                    // 通常の要素のマッチング処理
                    var decodedText = $('<div>').html(data.text).text().toLowerCase().trim();
                    var searchTerm = params.term.toLowerCase().trim();

                    if (decodedText.indexOf(searchTerm) > -1) {
                        return data; // 親要素がマッチする場合
                    }

                    return null; // マッチしない場合
                }
            });
        } else {
            console.log("担当者フィールドが見つかりません");
        }
    }
</script>
0Like

Your answer might help someone💌