特定のキーワードを元に絞り込み機能をつける方法(JavaScript)

[前置き]
自分で使った内容を忘れないように「作業メモ」の役割もになって書いています。
まだまだ勉強中の身ですので、回りくどい書き方をしていたり、コードがなが〜くなっていたりしますが、あたたかい目で観ていただけますと幸いです。

本日のお勉強メモ

とある一覧表があるとします。
私が、コードで作成する際は、「div」だったり、「table」だったり、「dl,dt,dd」だったり、その時の状況に応じてHTMLやCSSなんかを使って作成していきますが、その時は、Wordpressのブロックエディタを使って、ほぼHTMLのコーディングはなし(CSSは別途追加)で作成しました。
よし!出来た♪と思ったその後に「特定のカテゴリー」に応じて絞り込みをかけることになったぞ、そんな作業のお勉強メモです。

一覧表の例

例として、tableタグを使って作成した次のような一覧表があったとします。

飼い主ペット名前
鈴木犬:ボストンテリア
爬虫類:ギリシャリクガメ
タロウ
亀治郎
山本猫:マンチカンハナコ
吉田なしなし
佐藤犬:チワワゴンベイ
田中鳥:セキセイインコピーちゃん
高橋爬虫類:レオパやもくん

簡単にかくと、HTML的にはこんな感じだとします。(cssは省略します)

    <table id="pet_table">
        <thead>
            <tr>
                <th class="owner">飼い主</th>
                <th class="pets">ペット</th>
                <th class="pets_name">名前</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="owner">鈴木</td>
                <td class="pets">犬:ボストンテリア<br>
                                 爬虫類:ギリシャリクガメ</td>
                <td class="pets_name">タロウ<br>
                                      亀治郎</td>
            </tr>
            <tr>
                <td class="owner">山本</td>
                <td class="pets">猫:マンチカン</td>
                <td class="pets_name">ハナコ</td>
            </tr>
        <!------------中略------------>
            <tr>
                <td class="owner">高橋</td>
                <td class="pets">爬虫類:レオパ</td>
                <td class="pets_name">やもくん</td>
            </tr>
        </tbody>
    </table>

絞り込みの条件

  • 表の真ん中にある「ペット」列からの絞り込み
  • 絞り込み項目は「全て」「犬または猫」「なし」「その他」
  • 「その他」には「ペットなし」「犬」「猫」は含まない

一番上の行には「犬」と「爬虫類(その他)」が含まれていますので、「犬または猫」で絞り込んでも表示されるし、「その他」で絞り込んでも表示されるようにしなくてはなりません。
また、今後、想定外の「その他」の動物の種類が増えることも想定し、その場合は「その他」として表示させたいところです。

絞り込み用ドロップダウンリストとボタンを設置

とりあえず絞り込みを行うにあたり、キーワードの選択部分と絞り込みボタンが必要なので、tableの上にHTMLで記載します。

    <form name="pet_sort">
        <div class="select_box">
            <select name="pets" id="pets" class="pets_filter">
                <option value="all">全て</option>
                <option value="no_pets">なし</option>
                <option value="cat_dog">犬または猫</option>
                <option value="other_pet">その他</option>
            </select>
        </div>
    </form>
    <div class="button_box">
        <button id="sort_btn" class="sort_btn">絞り込み</button>
    </div>

特定の文字列が含まれているかどうかの判別方法

本来なら、絞り込み用の要素をtable内に設置したりするのが一番良いと思うのですが、
状況的にそういったことができなかったため、表の真ん中の「ペット」列に特定の文字が含まれているかどうかを判別し、非表示のクラスを付与(または削除)、CSSで非表示のクラスに「display:none;」を設定する方法を取りました。

まずは特定の文字列を判別するための配列を用意します。

let Word = ['犬','猫'];

配列に格納した文字列の一つでも当てはまれば「true」を出力させます。

//複数の特定の要素のうち、ひとつでも当てはまったらtrueを返す
 const isIncludes = (arr,target) => arr.some(el => target.includes(el));
//Word(犬・猫)が含まれていたらtrueを返す
 let Cat_Dog = isIncludes(Word,'検索したい部分(ペット列)');

trueなら犬または猫が含まれているので表示(非表示クラス名を削除)、falseなら含まれていないので非表示するためのクラス名を付与すれば、絞り込みが「犬または猫」用の動作の出来上がりです。
検索する行は複数あるので、ループで処理することをお忘れなく!

jsコード全体はこんな感じです。

//絞り込みボタン(#sort_btn)の取得
const SortBtn = document.getElementById('sort_btn');

//sort_btnをクリックしたら
SortBtn.addEventListener('click',function(){

    //検索用のワードを設定
    let Word1 = ['なし'];
    let Word2 = ['犬','猫'];
    //その他で除外するワードを設定
    let Exclusion_word = ['なし','犬','猫'];
    let OterWord = ['爬虫類','鳥','両生類','馬','ブタ','虫','小動物']

    //selectタグを取得(pet_sort=formのname値/pets=selectのname値)
    const PetsSelect = document.pet_sort.pets;
    //selectの値(数値)を取得
    const Num = PetsSelect.selectedIndex;
    //値(数値)から表示されているoptionのvalue値を取得
    const pets_val = PetsSelect.options[Num].value;
    //選択しているoptionに応じて
    //全て → all  なし → no_pets  犬または猫 → cat_dog  その他 → other_pet
    //がそれぞれ取得される。

    //tableが複数あることもあるので、特定のID名のtableを指定
    const PetTable = document.getElementById('pet_table');
    //tableの中のtbodyを指定
    const TableTbody = PetTable.querySelector('tbody');
    //tbodyの中の特定のクラス名を指定
    const PetTd = TableTbody.querySelectorAll('.pets');

    //PetTdの数だけループして処理する
    for(let i = 0; i < PetTd.length; i++){
        //.petsの親要素取得
        const PetTr = PetTd[i].closest('tr');
        //.petsのテキストを取得
        const PetTxt =  PetTd[i].innerText;

        //複数の特定の要素のうち、ひとつでも当てはまったらtrueを返す
        const isIncludes = (arr,target) => arr.some(el => target.includes(el));
        //Word1(なし)が含まれていたらtrueを返す
        let No_Pet = isIncludes(Word1, PetTxt);
        //Word2(犬・猫)が含まれていたらtrueを返す
        let Cat_Dog = isIncludes(Word2, PetTxt);
        //Exclusion_wordが含まれていたらtrueを返す
        let Exclusion = isIncludes(Exclusion_word, PetTxt);
        //OterWordが含まれていたらtrueを返す
        let OtherPet = isIncludes(OterWord, PetTxt);

        //非表示クラス(hidden)を一旦削除
        if(PetTr.classList.contains('hidden') == true){
            PetTr.classList.remove('hidden');
           }

        //絞り込み条件が「その他(other_pet)」の時
        if(pets_val === 'other_pet'){
            //除外:true その他:false
            if(Exclusion === true && OtherPet === false){
                //その他にあたるものが含まれないので非表示
                //複数種類のキーワードがあるときの表示の設定
                PetTr.classList.add('hidden');

            //除外:true その他:true
            }else if(Exclusion === true && OtherPet === true){
                //除外も含まれてるけどその他も含まれているからから表示
                //複数種類のキーワードがあるときの表示の設定
                PetTr.classList.remove('hidden');

            //除外:false その他:true
             }else if(Exclusion === false && OtherPet === true){
                //その他に該当するから表示
                PetTr.classList.remove('hidden');
            }else{
                //キーワードが何も含まれていないものはその他として表示
                PetTr.classList.remove('hidden');
            }
        }

        //絞り込み条件が「なし(no_pets)」の時
        if(pets_val === 'no_pets'){
            if(No_Pet === true){
                //なしが含まれてたら表示
                PetTr.classList.remove('hidden');
            }else{
                //含まれていなかったら非表示
                PetTr.classList.add('hidden');
            }
        }

        //絞り込み条件が「犬または猫(cat_dog)だったら
        if(pets_val === 'cat_dog'){
            if(Cat_Dog === true){
                //犬または猫が含まれていたら表示
                PetTr.classList.remove('hidden');
            }else{
                //含まれていなかったら非表示
                PetTr.classList.add('hidden');
            }
        }

        //絞り込み条件が「全て(all)だったら
        if(pets_val === 'all'){
            PetTr.classList.remove('hidden');
        }
 
    }//for終わり
});//function終わり

CSSに非表示の記載もお忘れなく!

.hidden{
    display: none;
}

このやり方のデメリットとしては、仮に「猫もどき」という名の「その他」に該当する生き物がいた場合、「猫」という特定の文字列が含まれてしまっているため、「その他」ではなく「犬または猫」として絞込み表示されてしまいます。
ただ、もう既に一覧表の内容が何行も書き込まれている状況で、新たに「検索用の要素」をHTMLに追加するのことができない場合、この方法で絞込み検索を行うというのも一つの方法かと思います。

実機でもチェックしてみよう!

JavaScriptを実装するにあたり

JavaScriptに限ったはなしではないですが、検証ツールではちゃんと動いていたのに、いざブラウザで実装してみたら、このブラウザでは動かない!スマホの機種によっては動かない!なんてことは、結構あります。
せっかく作ったJavaScriptがちゃんと本番環境での動くのかを試すためには実機でチェックする必要があります。
実機でチェックするということは、そうです。サーバーが必要になります。
それに、自分のサイトに載せたいと思う方もいるのではないでしょうか?
※「HTML・CSSだけではなく、JavaScriptやjQueryも書けますよ!」というのがわかるポートフォリオはそれだけで魅力が増すというものです。

弊社で利用しているサーバーについて

実機で確認する、またはサイトを公開するということは、サーバーが必要となるわけですが、おすすめのサーバーはありますか?という話はよく聞かれます。
色々なサーバーがあるので「おすすめなサーバー○選!」というような細かい内容は、長くなってしまうため、また今度別の記事で書けたらいいなと思います。
とりあえず、今回は弊社が使っているサーバーをご紹介させていただきます。
弊社が利用しているサーバーはXserverです。もちろん、今度おすすめサーバーの記事を書くときは必ず載ってきます。
Xseverには無料のXfreeという無料サーバーもあります。初めの練習などにはXfreeでもいいと思います。
ですが、Xfreeは3ヶ月毎に管理画面にログインして更新ボタンを押さないとサイトが閲覧できなくなる(なくなるわけではない)、スマホでサイトを見た時に広告が表示される、無料サーバーなので通常と比べて若干遅い、といったようなデメリットもあったりますので、ちゃんと自分のサイトを持ちたい!ポートフォリオを作りたい!という方は有料版のXserverをお勧めいたします。

やってみたけど上手くいかない!困ってしまったら?

弊社ではセミナーも開催しています!

JavaScriptで検索機能つけてみたけど、うまくいかない。
サーバー契約してサイト作りたいけど、初めてだから不安。
WordPressを使って自分のサイト作ってみたけど、うまくいかない、わからない。
もし、このような感じで困ってしまったら、弊社のセミナーに参加してみませんか?
セミナーについては当サイトのページをご覧いただき、詳しくはお問い合わせフォームより、ご連絡またはご相談いただきますようお願いいたします。

この記事を掲載するにあたり、セミナーの講師もしているスタッフ(私の先輩)に見てもらったのですが、案の定「コード長いね」って言われてしまいました(泣)私ももっと勉強しないと!

会社のページを作ってみようと思ったけどやっぱり依頼したい

もちろん、弊社でサイトの新規作成や、既存サイトの修正、サーバーのお引越し等のお仕事も承っております。
お困りのことなどございましたら、お気軽にお問い合わせください。

関連記事

  1. 2024年2月21日開催 地域経済への貢献が期待される「最新技術(AI…

  2. Claris Engage Japan 2023

  3. 2024年2月24日開催 WordCamp Kansai 2024 参…