フォームに法人名リアルタイム検索機能を実装する方法を解説します。

このブログでは、CodeIgniterフレームワークを使用して、フォームに法人名リアルタイム検索機能を実装する方法を解説します。ユーザーが法人名を入力する際に、リアルタイムで検索結果を表示し、選択した情報をフォームに自動入力することで、入力作業を効率化できます。

1. 実装する機能の概要

今回の実装では、以下の機能を実現します。

  • 法人名入力欄のリアルタイム検索:
    • 入力中に候補が自動表示されるオートコンプリート機能
    • Elasticsearchをデータソースとした検索
  • 検索結果のフォームへの自動挿入:
    • 法人名を選択すると、関連情報(会社名カナ、代表者名、代表者名カナ、郵便番号、都道府県、市区町村、住所など)を自動でフォームに入力
  • UI/UXの向上:
    • 検索候補の表示、選択、ローディング表示などのユーザーフレンドリーなUI

2. 実装手順

2.1 フォームの修正 (HTML)

<div class="form-group">
    <div class="row">
        <label for="company_name" class="<?php echo $label_column; ?> company_name_section"><?php echo ($model_info->type == "person") ? app_lang('name') : app_lang('company_name'); ?></label>
        <div class="<?php echo $field_column; ?>">
            <input type="text"
                   id="<?php echo ($model_info->type == "person") ? "name" : "company_name"; ?>"
                   name="<?php echo ($model_info->type == "person") ? "name" : "company_name"; ?>"
                   value="<?php echo ($model_info->type == "person") ? $model_info->name : $model_info->company_name; ?>"
                   class="form-control company_name_input_section"
                   placeholder="<?php echo ($model_info->type == "person") ? app_lang('name') : app_lang('company_name'); ?>"
                   autofocus="true"
                   data-rule-required="true"
                   data-msg-required="<?php echo app_lang("field_required"); ?>"
                   autocomplete="off">
            <!-- 検索候補表示用の要素 -->
            <div id="company_name_suggestions" class="list-group" style="position:absolute; z-index: 1000; width: 100%; max-height: 200px; overflow-y: auto; display: none;"></div>
        </div>
    </div>
</div>

まずは、company_name入力欄をリアルタイム検索に対応させます。

ポイント:

  • autocomplete="off": ブラウザのオートコンプリート機能を無効化
  • <div id="company_name_suggestions">: 検索候補を表示するための要素

2.2 JavaScriptの追加/修正

次に、JavaScriptで検索処理と結果の表示処理を実装します。

$(document).ready(function() {
    // ... (既存のJavaScriptコード) ...

    // 法人名リアルタイム検索機能
    let companyNameTimeout;
    $("#company_name").on("input", function () {
        clearTimeout(companyNameTimeout);
        const query = $(this).val();
        const suggestionsElement = $("#company_name_suggestions");

        suggestionsElement.hide(); // 検索前に候補を非表示
        suggestionsElement.empty(); // 検索前に候補リストをクリア

        if (query.length >= 2) { // 2文字以上入力されたら検索開始
            companyNameTimeout = setTimeout(() => {
                $.ajax({
                    url: "<?php echo get_uri('clients/search_company_name'); ?>",
                    method: "POST",
                    data: { query: query },
                    dataType: "json",
                    success: function (data) {
                        if (data && data.hits && data.hits.hits.length > 0) {
                            data.hits.hits.forEach(function (hit) {
                                const company = hit._source;
                                const listItem = $("<a href='#' class='list-group-item list-group-item-action'></a>")
                                    .text(company.company_name)
                                    .on("click", function(e){
                                        e.preventDefault();
                                        // 選択された法人情報を各フィールドにセット
                                        $("#company_name").val(company.company_name);
                                        $("#company_name_kana").val(company.company_name_kana);
                                        $("#trade_name").val(company.trade_name);
                                        $("#trade_name_kana").val(company.trade_name_kana);
                                        $("#zip").val(company.zip);
                                        $("#state").val(company.state);
                                        $("#city").val(company.city);
                                        $("#address").val(company.address);
                                        suggestionsElement.hide(); // 候補を非表示
                                    });
                                suggestionsElement.append(listItem);
                            });
                            suggestionsElement.show(); // 候補を表示
                        } else {
                           suggestionsElement.hide(); // 検索結果がない場合は非表示
                        }
                    },
                    error: function () {
                        suggestionsElement.hide();
                        console.error("法人名検索に失敗しました。");
                    },
                });
            }, 500); // 500msのディレイを設定
        }
    });

    // 候補リスト外クリックでリストを閉じる
    $(document).on('click', function(event) {
        if (!$(event.target).closest('#company_name_suggestions').length && !$(event.target).closest('#company_name').length) {
            $('#company_name_suggestions').hide();
        }
    });
});

ポイント:

  • $("#company_name").on("input", ...): 入力欄のinputイベントを監視
  • $.ajax(): サーバーに検索リクエストを送信
  • success コールバック関数: 検索結果を解析し、候補リストを生成
  • 候補リストのクリックイベントで、各フィールドに値をセット
  • setTimeout(): 短時間での連続的な検索を防ぐ(デバウンス)

2.3 コントローラーの追加/修正 (PHP)

次に、Elasticsearchに検索リクエストを送信し、JSON形式で結果を返すコントローラーメソッドを実装します。

<?php
// application/controllers/Clients.php
class Clients extends Clients_Controller{
    // ... (既存のコード) ...

    public function search_company_name() {
        $this->load->library('elasticsearch'); // Elasticsearchライブラリをロード
        $query = $this->input->post('query');

        $params = [
        'index' => 'companies', // Elasticsearchのインデックス名
        'body'  => [
            'query' => [
            'multi_match' => [
                'query' => $query,
                'fields' => ['company_name^3', 'company_name_kana','trade_name', 'trade_name_kana'] // 検索対象フィールド
            ]
            ]
        ]
        ];

        $result = $this->elasticsearch->search($params);
        echo json_encode($result);
    }
    // ... (既存のコード) ...
}

ポイント:

  • $this->load->library('elasticsearch');: Elasticsearchライブラリをロード
  • Elasticsearchの検索パラメータを定義
  • $this->elasticsearch->search($params);: Elasticsearchに検索リクエストを送信
  • echo json_encode($result);: 検索結果をJSON形式で返す

2.4 Elasticsearchライブラリの作成 (PHP)

Elasticsearchと連携するためのライブラリを作成します。

  • application/libraries/Elasticsearch.php
<?php
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;

class Elasticsearch {

    private $client;

    public function __construct()
    {
        $this->client = ClientBuilder::create()
                ->setHosts(['127.0.0.1:9200']) // Elasticsearchの接続情報を設定
                ->build();
    }

    public function search($params){
        return $this->client->search($params);
    }

    public function index($params){
        return $this->client->index($params);
    }

    public function get($params){
        return $this->client->get($params);
    }
}

ポイント:

  • composer require elasticsearch/elasticsearch: ComposerでElasticsearchクライアントをインストール
  • setHosts(): Elasticsearchの接続先を設定
  • search(), index(), get(): Elasticsearchの基本的な操作メソッドを定義

3. 補足事項

  • Elasticsearchの準備: 事前にElasticsearchをインストールし、companiesインデックスを作成してデータを登録しておく必要があります。
  • 検索クエリの調整: Elasticsearchの検索クエリは、検索精度を向上させるために調整できます。
  • UIの改善: ローディング表示やエラーメッセージなどを追加することで、より使いやすいUIを実現できます。
  • セキュリティ: Elasticsearchへのアクセスを保護するため、適切な認証・認可設定を行ってください。

4. まとめ

このブログでは、CodeIgniterに法人名リアルタイム検索機能を実装する手順を詳しく解説しました。この機能を活用することで、フォーム入力作業を効率化し、ユーザーエクスペリエンスを向上させることができます。

ぜひ、このガイドを参考に、あなたのアプリケーションにリアルタイム検索機能を実装してみてください。

ご不明な点や質問があれば、コメント欄にてお気軽にお問い合わせください。

Previous Article

Hello world!

Next Article

目標: 1秒でも早く検索結果1位を獲得すること。

Write a Comment

Leave a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Subscribe to our Newsletter

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨