カテゴリー
アーカイブ

10.11
2024

jQueryでリアルタイム検索ぽいものをつくる

  • LINE

はじめに

こんにちは!

jQueryに悪戦苦闘中のエンジニアです!

最近Webページを見ているときに検索ワードからリアルタイムで結果を絞り込む機能を目にします。
いま携わっているプロジェクトでjQueryを触る機会が多いからか、このような機能をjQueryで実装できないかと興味が沸いたので実際に作ってみました!

例) 以下のような本の一覧がある場合に、

検索欄に文字を入力するだけで該当する本だけがリアルタイムに表示されるイメージです。

今回はDjangoで本の一覧を表示するアプリを作成し、そこにjQueryでリアルタイム検索ぽい機能をつけてみます!

目次

    1. 1. DockerでDjangoの環境構築を行う
    2. 2. Djangoで本アプリを作成する
    3. 3. jQueryでリアルタイム検索ぽい機能を追加する
    4. 4. まとめ

     

    1. DockerでDjangoの環境構築を行う

    環境構築は『DockerでDjangoの環境構築をしてみた』の記事を参考に行います!

    環境構成は以下になります。

    • Docker
    • Python
    • Django
    • mysql
    • mysqlclient

    記事を参考にDockerコンテナを立ち上げたら、http://127.0.0.1:8000にアクセスしましょう。

    Djangoのトップページが確認できたら環境構築完了です。

    2. Djangoで本アプリを作成する

    次はDjangoで本の管理アプリのようなものを作成していきます。

    プロジェクトまでは作成しましたが、アプリをまだ作成していないので作成します。

    ターミナル(コマンドライン)で以下を実行します。

    $ docker-compose run --rm web django-admin startapp book

    これでbookという名前のアプリが作成されると思います。

    次に管理画面にログインするためにスーパーユーザーを作成します。

    以下コマンドを実行したら、ユーザー名、メールアドレス、パスワードを求められると思うので、任意のものを入力してください。

    $docker-compose run --rm web python manage.py createsuperuser

    最後にmigrationを行います。

    以下の2つのコマンドを実行してください。

    $docker-compose run --rm web python manage.py makemigrtions
    $docker-compose run --rm web python manage.py migrate

    こちらでmigrationは完了です。

    ここまででhttp://127.0.0.1:8000/adminにアクセスするとDjangoの管理画面に行けると思います。

    次は本のモデルを作成します。今回はタイトルを検索する機能しか作成しないので、必要最低限にします。

    book/models.py

    
    from django.db import models
    
    
    class Book(models.Model):
        """本のモデル"""
        # タイトル
        title = models.CharField(max_length=255)
        # 著者
        author = models.CharField(max_length=32)
        # 出版社
        publisher = models.CharField(max_length=32)
    
        class Meta:
            db_table = 'Book'
            verbose_name_plural = 'Book'
    
        # 管理画面で表記をタイトルにするため
        def __str__(self):
            return self.title

    次に登録された本を表示するためのviewを作成します。

    book/views.py

    
    from django.shortcuts import render, HttpResponse
    from book.models import Book
    
    
    def top(request):
        # 登録されている全ての本を取得する。
        books = Book.objects.all()
        return render(request, 'top.html', {'books': books})
    
    

    テンプレートがないのでテンプレートも作成します。

    projectやbookと同階層にtemplatesフォルダを作成し、その中にtop.htmlを作成します。

    templates/base.html

    <!doctype html>
    <html lang="ja">
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
        <title>TOPページ</title>
      </head>
      <body>
        <form>
          <input type="text" id="search-word" placeholder="検索ワードを入力"/>
        </form>
        {% for book in books %}
        <ul class="result">
          <li>
            {{ book.title }}<br>
            {{ book.author }}
            {{ book.publisher }}
          </li>
        </ul>
        {% endfor %}
        <script src="https://code.jquery.com/jquery-3.7.1.slim.min.js" integrity="sha256-kmHvs0B+OpCW5GVHUNjv9rOmY0IvSIRcf7zGUDTDQM8=" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js" integrity="sha384-fbbOQedDUMZZ5KreZpsbe1LCZPVmfTnH7ois6mU1QK+m14rQ1l2bGBq41eYeM/fS" crossorigin="anonymous"></script>
      </body>
    </html>

    jQueryを読み込みつつ、デザインに便利なBootstrapも読み込んでおきます。

    最後にプロジェクトとアプリのurlをそれぞれ設定します。

    project/urls.py

    
    from django.contrib import admin
    from django.urls import path, include
    
    
    urlpatterns = [
        path('', include('book.urls')),
        path('admin/', admin.site.urls),
    ]
    

    これでアプリ側に作成したurlsを読み込んでくれるようになります。

    次にアプリ側にurls.pyを作成します。このurls.pyはアプリを作成した時に自動で作られるものではないので自分で追加してください

    book/urls.py

    
    from django.urls import path
    
    from book.views import top
    
    urlpatterns = [
        path('', top, name='top'),
    ]
    

    こちらで、http://127.0.0.1:8000 からTOPページにアクセスできるようになっていると思います!

    ただ、現時点では本を登録していないので、お好きな本をadminサイトから登録してください!

    本を登録したら以下のようになります!

    こちらで本を表示するためのアプリは作成できました!

    最後に今回のメインであるリアルタイムぽい検索をするためのjQueryを記載していきます!

    3. jQueryでリアルタイム検索ぽい機能を追加する

    先ほど作成したtop.htmlファイルの<body>タグの下に<script>タグを追加してjQueryを記載します。

    </body>
    <script>
    $(function () {
      searchWord = function(){
      // 検索欄に入力された文字を取得
      var searchText = $(this).val(), targetText;
      $('.result li').each(function() {
        targetText = $(this).text();
        // 検索対象となるリストに入力された文字列が存在するかどうかを判断
        if (targetText.indexOf(searchText) != -1) {
          $(this).removeClass('hidden');
        } else {
          $(this).addClass('hidden');
        }
      });
    };
    
    // searchWordの実行
    $('#search-word').on('input', searchWord);
    });
    </script>
    

    inputイベントを使って、検索欄に文字が入力されるたびに、

    indexofメソッドを用いて、タイトル、著者、出版社が含まれていなければ、hiddenクラス削除し、

    含んでいればhiddenクラスを与えるようにします。

    ※indexofメソッドは文字列に対して、検索ワードを含んでいない場合は-1を含んでいる場合はその文字数を返します。

    これだとまだ、hiddenクラスが追加されたり、削除されたりするだけなのでhiddenクラスがある場合は表示しないようにCSSを追加します。

    top.htmlの<body>タグの直前に<style>タグを追加してdisplay: none;を追加しましょう。

    <style>
    .hidden {
      display: none
    }
    </style>
    

    これで以下のように入力のたびに検索結果が絞り込めると思います!

    完成イメージ)

    4. まとめ

    こういった機能はたまに見たりしますが、案外少ないコード量で実装することができました!

    都度ボタンを押したりしなくていいんでUXは向上するのではないでしょうか!

    より一層jQueryに興味が湧きました!