jQuery 表示フィルタをつくってみる (JavaScript)

WEBぺージを作成する時、
JavaScriptとjQueryを使うと結構簡単にリストなどの表示フィルタが実装できます。
案外知らない人が多かったので、共有します。

最近なら、jQueryを使わなくても
Angular とか、Reactで、こういうのは簡単に実装できるけど、
まぁ、ちょっと古い臭い方法ということで〜。

表示フィルター

ここで言う表示フィルターとは、
何らかの一覧リストがあって、検索窓にキーワードを入力すると
検索にマッチするリストだけが表示されるというもの。

jQuery セレクター

検索に利用するのは、jQueryのセレクタを利用します。

jQueryのセレクタについては、ここらへん参照
https://qiita.com/Thought_Nibbler/items/5d4fc40a4d4325128b24

今回は、部分一致というセレクタを使います。
*= ってやつですね。

data 属性

セレクタで検索する対象は、data属性を利用します。 

<li data-keyword="hoge">hoge</li>
みたいに、data- で始まるattribute(属性)のことです。

別に data- で始める必要はないんだけれど、
独自に追記した属性という事が明確になる為の慣習みたいです。

keyup で show/hide

フィルタの表示を実行するタイミングは、
キーボードのkeyupのタイミングで処理をはさみます。

これらを駆使する事で、簡単にフィルタ実装ができる!!

実際に実装してみる。

HTMLはこんな感じでリストと、表示フィルタの入力欄があるものを想定。

<input type="button" onclick="reset();" value="リセットボタン"/>
<input id="filter" type="text" placeholder="表示フィルタ"/>

<ul>
    <li data-keyword="hoge">hoge</li>
    <li data-keyword="piyo">piyo</li>
    <li data-keyword="foo">foo</li>
</ul>

で、肝心のJavaScriptはこんな感じだ。

<script>
function filter(){
    var text = $('#filter').val();
    if ("" == text){
        $('li[data-keyword]').show();
        return;
    }

    $('li[data-keyword]').hide();
    $('li[data-keyword*=' + text + ']').show();
}

function reset(){
    $('#filter').val("");
    filter();
}

$(document).ready(function () {
    $('#filter').keyup(function () {
        filter();
        return (13 !== event.which);
    });

    filter();
});
</script>

一番肝になるのが、属性セレクタで、data属性の文字列と部分一致した場合にマッチする。
(*=)という演算子で比較する。

[data-keyword*=hoge]

入力ボックスのキーイベントに、filter関数を挟む。
空文字が入力されているときは、もちろん全件表示となるようにしている。

エンターキーのsubmitを抑止する

event.which は入力されたキーの番号で、13はエンターキーの事だ。
エンターキーが押されたときはfalseを返す事で、フィルター入力枠でsubmitを抑止する事ができる。

おわり

一覧表示はいろんなところにあるが、
既存の構造を変えなくても、data属性を加えるだけで、簡単に表示フィルタが実装できるぞ!!
これで、いろんなところにフィルタ追加して便利にしてみよう〜。

[追記] サンプルコード

実際に動作する、サンプルコードを載せておきます。
以下のソースを、index.html というファイル名で保存してchromeで起動すれば確認できるだろう。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>jQuery Text Filter Sample</title>
    <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
    <script>
        function filter() {
            var text = $('#filter').val();
            if ("" == text) {
                $('li[data-keyword]').show();
                return;
            }

            $('li[data-keyword]').hide();
            $('li[data-keyword*=' + text.toLowerCase() + ']').show();
        }

        function reset() {
            $('#filter').val("");
            filter();
        }

        $(document).ready(function () {
            $('#filter').keyup(function () {
                filter();
                return (13 !== event.which);
            });

            filter();
        });
    </script>
</head>

<body>
    <input type="button" onclick="reset();" value="リセットボタン" />
    <input id="filter" type="text" placeholder="表示フィルタ" />

    <ul>
        <script>
            var data = [
                "eHnEwSfTkaLcJ46aRDES",
                "XFmPmWfryP5XRy_YyNcp",
                "sVdCGVbShBPa3Pi2PQTk",
                "wDzmKwFaJiG4M3iEeR8p",
                "AcCaUrZGjUEXyWhxGnAN",
                "WrmMyNzXsPGDJSeLRhx4",
                "ur8FzJLbrKUhZ_JE8Yde",
                "a5VjQr5JLDGA9EeMgi5-",
                "HTznGXjmiWLYc8sWwScu",
                "nbi_uNbu6JJUQZN62Uj5",
                "yWpatFbEsTt8aULhDGCM",
                "GeVTJyLSVtt4kJVrQ7Tw",
                "panxCLAYaF-sr6JcEz69",
                "_95RUiy5r8AbiWH_7ehu",
                "D_MNx2QMedCePwXhNd-i",
                "nRbrSK8RGpi9PJ-jw6fR",
                "gz45CgcwLDx5Z5c-4RhR",
                "2THH4wDr5BHcGaJ5hRLe",
                "V6M8d4VmhWkm7PuLmjCM",
                "UNrRndnYCyLbFg7g7h7X",
                "M5djD4MXzgmSRWgKsx_Y",
                "8BZsbfxcV_rHLbXeRL6X",
                "YEfjhcaDPxgi5Y3XJHXt",
                "y57LxWDBTtJmtsn_GZiT",
                "xUdMQthchugPFK45xKai",
                "YHsy9FCUdHiYAMD7m52Y",
                "iFTJSjG8yt3QUNZ5NBbD",
                "ZmSs9rnErnP5DwTPU587",
                "rrpWjnVbD3z9WCiinVK3",
                "zpBgdSbLDSJRYzHxwgth",
            ];
            for (var i = 0; i < data.length; i++) {
                document.writeln("<li data-keyword=\"" + data[i].toLowerCase() + "\">" + data[i] + "</li>");
            }
        </script>
    </ul>
</body>

</html>

コメントを残す