WEB制作、マーケティングに関する情報をお届けします。ホームページ制作会社、テラのブログ

Javascriptで入力フォームからリストをリアルタイムで検索する方法

タグ:

今回は入力フォームの値を取得してリストなどをリアルタイムで検索する方法を紹介します。カタカナ、ひらがなにも対応していますのでさまざまなケースで対応できるはずです。
また、ヒットしたものにクラス名を付与する方法にしているのでcss側で処理や動きは設定できます。

コードを解説

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Flexible Search List</title>
</head>
<body>
<input type="text" id="search_query" placeholder="キーワードで検索">

<ul class="search_list">
    <li>バナナのコンテンツ</li>
    <li>バナナとリンゴのコンテンツ</li>
    <li>バナナとオレンジのコンテンツ</li>
    <li>リンゴのコンテンツ</li>
    <li>リンゴとオレンジのコンテンツ</li>
    <li>オレンジのコンテンツ</li>
    <li>バナナとオレンジのコンテンツ</li>
    <li>ばななとりんごのコンテンツ</li>
    <li>バナナとリンゴのコンテンツ</li>
    <li>ばななとオレンジのコンテンツ</li>
    <li>バナナとりんごのコンテンツ</li>
</ul>

<style type="text/css">
    .active {
        background-color: yellow; /* アクティブなアイテムの背景色を黄色に設定 */
    }
    .hidden {
        display: none; /* 非表示のアイテムにはdisplay:noneを適用 */
    }
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
    // 検索入力フィールドを取得
    const searchInput = document.getElementById('search_query');
    // リストアイテムを取得
    const listItems = document.querySelectorAll('.search_list li');

    // テキストを全角ひらがなに変換する関数
    function normalizeText(text) {
        return text
            .normalize("NFKC") // 全角文字を半角に変換
            .replace(/[\u30a1-\u30f6]/g, match => 
                String.fromCharCode(match.charCodeAt(0) - 0x60)) // 全角カタカナをひらがなに変換
            .toLowerCase(); // 英数字を小文字に変換
    }

    // 入力フィールドの入力イベントに応じた処理
    searchInput.addEventListener('input', function() {
        const query = normalizeText(searchInput.value); // 入力されたクエリを正規化
        const keywords = query.split(/[\s\u3000]+/).filter(keyword => keyword); // スペースで分割してキーワード配列を生成

        if (query.trim() === '') { // クエリが空の場合は全アイテムを表示
            listItems.forEach(item => {
                item.classList.remove('active');
                item.classList.remove('hidden');
            });
        } else { // クエリがある場合、各リストアイテムに対して処理を行う
            listItems.forEach(item => {
                // アイテムのテキストを正規化
                const text = normalizeText(item.textContent);
                // キーワードのいずれかがテキストに含まれているかチェック
                const matches = keywords.some(keyword => text.includes(keyword));

                if (matches) { // マッチした場合、アクティブクラスを追加し非表示クラスを削除
                    item.classList.add('active');
                    item.classList.remove('hidden');
                } else { // マッチしない場合、アクティブクラスを削除し非表示クラスを追加
                    item.classList.remove('active');
                    item.classList.add('hidden');
                }
            });
        }
    });
});
</script>
</body>
</html>

コードを解説

入力フォームに振っているIDを取得します。

const searchInput = document.getElementById('search_query');

リストのアイテムを取得します。
今回はulタグにクラス名『.search_list』を振ってありそ配下であるliタグを対象にします。

const listItems = document.querySelectorAll('.search_list li');

入力されたテキストを全角ひらがなに変換、正規化します。

function normalizeText(text) {
    return text
        .normalize("NFKC") // 文字を正規化し全角文字を半角に変換
        .replace(/[\u30a1-\u30f6]/g, match => 
            String.fromCharCode(match.charCodeAt(0) - 0x60)) // 全角カタカナをひらがなに変換
        .toLowerCase(); // 英数字を小文字に変換
}

以下で入力フォームがあった場合に実行させます。

searchInput.addEventListener('input', function() {
}

処理を書いていきます。
まずは入力されたテキストの値を引き取り、「入力されたテキストを全角ひらがなに変換、正規化」の関数を実行させます。
変数『query』に格納してsplitでスペースで分割してキーワード配列を生成します。

const query = normalizeText(searchInput.value); // 入力されたクエリを正規化
const keywords = query.split(/[\s\u3000]+/).filter(keyword => keyword); // スペースで分割してキーワード配列を生成

クエリがあるかないかをチェックして処理を振り分けます。

if (query.trim() === '') { // クエリが空の場合は全アイテムを表示
} else {
}

もし入力フォームに何も値がない場合は全てを表示する処理を書きます。

listItems.forEach(item => {
    item.classList.remove('active');
    item.classList.remove('hidden');
});

もし入力フォームに値がある場合は『forEach』でulタグの配下であるliタグ全てにテキストが含まれるかどうかを確認します。

listItems.forEach(item => {}

以下でリスト内のテキストを正規化します。
『.some()』は配列の中の条件が一つでも含まれていたら変数の『matches』にtrueを返します。
『text.includes(keyword)』は『リストのアイテム名.含まれるか?(キーワードに)』という意味です。

const text = normalizeText(item.textContent);
const matches = keywords.some(keyword => text.includes(keyword));

マッチした場合、アクティブクラスを追加し非表示クラスを削除、マッチしない場合、アクティブクラスを削除し非表示クラスを追加します。

if (matches) { // マッチした場合、アクティブクラスを追加し非表示クラスを削除
    item.classList.add('active');
    item.classList.remove('hidden');
} else { // マッチしない場合、アクティブクラスを削除し非表示クラスを追加
    item.classList.remove('active');
    item.classList.add('hidden');
}

まとめ

以上、『Javascriptでリストをリアルタイム検索する方法』でした。
ユーザービリティの高いサイトを構築する上でリストのリアルタイム検索など実装する場合も多々あります。
ぜひ参考にしてください。

テラ合同会社(東京都)

テラは2014年に東京都でスタートアップしたホームページ制作会社です。ホームページ制作以外にも広告運用、マーケティング、ブランディング、印刷物など幅広い領域をサポートしています。
コーポレートサイトはこちらをご覧ください。