開発情報・ナレッジ

投稿者: 株式会社ゴンドラ 2025年6月26日 (木)

メールアドレス入力時にドメインをサジェスト表示し入力補完する機能

SPIRALフォームにおけるメールアドレス入力欄にドメイン部分のサジェスト機能を追加する方法について紹介いたします。

はじめに

メールアドレス入力欄にドメインのサジェスト機能を実装する方法として、以下の2種類の方法があります。
1. サジェストするドメインを全てソース内で管理する方法
2. ドメインを管理しているDBからドメインを取得し、サジェストに表示させる方法
それぞれの特徴やメリット・デメリットについて解説しながら、実装手順を紹介します。

実装種類 ドメインをソースコード内で直接管理する方法 ドメインリストDBを作成し読み込む方法
メリット
  • ・実装が簡単で手軽
  • ・外部リソース不要
  • ・小規模なプロジェクトに適している
  • ・メンテナンス性が高い
  • ・ドメインリストの更新が容易
  • ・大量のデータを効率的に管理可能
  • ・複数のフォームで同じリストを共有可能
デメリット
  • ・ドメインリストの更新時にコードの修正が必要
  • ・メンテナンス性が低い
  • ・大量のドメインを扱う場合、コードが煩雑になる
  • ・DBやAPIの準備が必要
  • ・実装が複雑
  • ・外部リソースへの依存が発生

HTML・CSSの準備

紹介している2種類の実装方法において、HTMLとCSSは同じです。
こちらに記載しているソースを参考にHTMLとCSSの準備を行って下さい。

HTMLの準備:サジェストを表示できるようにする
メールアドレス入力欄で、サジェスト機能が動作するようにするために、classを指定する必要があります。
タグ内に
class="emailInput"
を指定してください。
<dl class="cf">
  <dt class="title">
    メールアドレス
  </dt>
  <dd class="data ">
    
    <input class="input emailInput $errorInputColor:mailAddress$" type="text" name="mailAddress"
      value="$mailAddress$" maxlength="129"><br>
    (確認用)<br>
    <input class="input emailInput $errorInputColor:mailAddress$" type="text" name="mailAddress:cf"
      value="$mailAddress:cf$" maxlength="129"><br>

    <span class="msg">$error:mailAddress$</span>
  </dd>
</dl>
サジェスト部分のCSS
下記CSSは、ページ内の
<style>
タグ内に記載してください。
PC版とスマートフォン版でCSSを分ける必要はありません。
ただし、スマートフォン版のCSSを追加する場合は、PC版のCSSよりも下に記載してください。
 .suggestions {
    overflow: scroll;
    border: 1px solid #ccc;
    max-width: 300px;
    max-height: 200px;
    list-style: none;
    margin: 0;
    padding: 0;
    position: absolute;
    background: white;
    z-index: 1000;
  }

  .suggestions li {
    padding: 8px;
    cursor: pointer;
  }

  .suggestions li:hover {
    background-color: #f0f0f0;
  }

ドメインをソースコード内で直接管理する方法

  1. 概要説明
  2. サジェストを表示するjavascript
概要説明

ソースコード内でドメインリストを管理する方法には、以下のようなメリットがあります。

  • DBを使用しないため、レコードを消費せずサーバー構成が簡素
  • 小規模なフォームや一時的な用途に適しています

  • サジェストを表示するjavascript
    JavaScriptを使用する為の準備
    このソースはjQueryを使用しているため、事前にjQueryのライブラリを読み込んでおく必要があります。
    jQueryを使用するために以下のタグを記載してください。
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="crossorigin="anonymous"></script>

  • メールアドレス入力フィールドに@マークを入力すると、サジェスト機能が動作を開始します。
  • @以降に文字を入力すると入力した文字に合わせて、候補のドメインがリスト表示されます
  • 表示された候補リストから希望のドメインをクリックすると自動的に完全なメールアドレスが入力されます
  • @マーク前に入力した文字はそのまま保持されます
  • 実装方法
    このソースは
    </html>
    よりも下に設置して下さい

    DBから取得したドメインリストをサジェスト表示するためのJavaScriptコードです。
    このコードは、PHPで取得したドメインリストをJavaScriptに渡し、サジェスト表示します。

    <script>
      // サンプルのメールドメイン
    	const domains = [
            "docomo.ne.jp",
            "gmail.com",
            "icloud.com",
            "yahoo.co.jp",
            "softbank.ne.jp",
            "au.com",
            "ezweb.ne.jp",
            "i.softbank.jp",
            "rakuten.jp",
            "ymobile.ne.jp",
            "yahoo.ne.jp",
            "uqmobile.jp",
            "mineo.jp",
            "rakumail.jp",
            "ymail.ne.jp"
    	];
    
      // 入力欄を監視
    	$('.emailInput').each(function () {
    		const input = $(this);
    		const suggestionsList = $('<ul class="suggestions"></ul>').appendTo('body');
    
    		// 入力時のイベント
    		input.on('input', function () {
    			const inputValue = input.val().trim();
    			suggestionsList.empty(); // リストをクリア
    
    			if (!inputValue.includes('@') || inputValue === '') {
    				suggestionsList.hide();
    				return;
    			}
    
    			const [localPart, domainPart] = inputValue.split('@');
    			if (domainPart === undefined) return;
    
    			const matches = domains.filter(domain => domain.startsWith(domainPart));
    
    			matches.forEach(match => {
    				const li = $('<li></li>').text(`@${match}`).appendTo(suggestionsList); 
    				li.on('click', function () {
    					input.val(`${localPart}@${match}`); // フルアドレスをセット
    					suggestionsList.empty(); // リストをクリア
    					suggestionsList.hide();
    				});
    			});
    
    			// サジェストリストの位置調整
    			const rect = input[0].getBoundingClientRect();
    			suggestionsList.css({
    				position: 'absolute',
    				left: `${rect.left + window.scrollX}px`,
    				top: `${rect.bottom + window.scrollY}px`,
    				width: `${rect.width}px`,
    				display: matches.length ? 'block' : 'none'
    			});
    		});
    
    		// 外部クリック時のリスト非表示
    		$(document).on('click', function (event) {
    			if (!input.is(event.target) && !suggestionsList.is(event.target) && suggestionsList.has(event.target).length === 0) {
    				suggestionsList.hide();
    			}
    		});
    	});
      
    </script>

    ドメインを管理しているDBからドメインを取得し、サジェストに表示させる方法

    1. 概要説明
    2. ドメインリストDBの注意点
    3. DBからドメインを取得するPHP
    4. DBから取得したドメインリストをサジェスト表示するJavaScript
    概要説明
  • メンテナンス性の向上:ドメインリストの更新や管理が一元化され、コード内でハードコーディングする必要がなくなります。
  • 柔軟な運用:新しいドメインの追加や削除がDBで完結し、コードの変更なしで対応が可能です。
  • データの一貫性:複数のフォームや機能で同じドメインリストを使用する場合、DBから取得することで一貫性を保てます。
  • リアルタイム更新:DBの更新がすぐにサジェスト機能に反映されるため、常に最新のドメインリストを使用することができます。

  • ドメインリストDBの注意点
    ドメインリストDBへは、メールアドレスの
    @
    を除いたドメイン部分
    をDBへ登録してください。
    例)
    メールアドレスが
    gondola@sample.com
    の場合、
    sample.com
    を登録してください。

    DBからドメインを取得するPHP
    PHPを使用する為の準備
    SPIRALでPHPを使用する場合は、PHPを使用できるようにするためのおまじないを記載する必要があります。
    <?php // <!-- SMP_DYNAMIC_PAGE DISPLAY_ERRORS=ON NAME=SAMPLE VERSION=7.2 --> ?>

    をソースの一番上に記載すると、PHPが使用できるようになります。
    実装方法
    このPHPソースは
    <head>
    タグ内に記載をしてください
    $db = $SPIRAL->setApiTokenTitle("トークン名");

    には利用しているSPIRALアカウントのAPIトークン名を指定してください。
    $db = $SPIRAL->getDataBase("取得するDBの名前");

    には取得したいDBの名前を指定してください。
    $db->addSelectFields("取得したいフィールド名");

    には取得したいフィールド名を指定してください。

    ※こちらのソースでは、最大500件のキーワードを取得できますが、万が一500件以上のキーワードがある場合は、
    $db->setLinesPerPage("ここの指定を変える");
    を変更してください。指定可能な値は1件以上1000件以下です。
    詳細: APIリファレンス

    <script type="text/javascript">
    	//DBからドメインを取得
    	<?php
    	    $SPIRAL->setApiTokenTitle("トークン名");
          $db = $SPIRAL->getDataBase("取得するDBの名前");
          $db->addSelectFields("取得したいフィールド名");
    	   $db->setLinesPerPage(500);
    	   $result = $db->doSelect();
          $domains = $result["data"]; 
      ?>
    	var domains_json = <? echo json_encode($domains) ?>;
    </script>
    DBから取得したドメインリストをサジェスト表示するJavaScript
    JavaScriptを使用する為の準備
    このソースはjQueryを使用しているため、事前にjQueryのライブラリを読み込んでおく必要があります。
    jQueryを使用するために以下のタグを記載してください。
    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="crossorigin="anonymous"></script>

    記載する箇所はソース上の方にあるmetaタグの下に記載してください。
    機能の説明
    実動作では@まで入力すると、@以降の部分がサジェスト表示されます。
    表示されたサジェストを選択すると、現在入力中のメールアドレスの@以降にサジェスト表示されたドメインが自動的に入力されます。
    また、
    gondola@i
    まで入力すると、
    icloud.com
    のようにiから始まるドメインがサジェスト表示されます。
    実装方法
    このソースは
    </html>
    よりも下に設置して下さい
    <script>
    $('.emailInput').each(function () {
        const input = $(this);
        const suggestionsList = $('<ul class="suggestions"></ul>').appendTo('body');
    
        // 入力時のイベント
        input.on('input', function () {
            const inputValue = input.val().trim();
            suggestionsList.empty(); // リストをクリア
    
            if (!inputValue.includes('@') || inputValue === '') {
                suggestionsList.hide();
                return;
            }
    
            const [localPart, domainPart] = inputValue.split('@');
            if (domainPart === undefined) return;
    
            const matches = domains_json
                .map(item => item.domain) // domainだけ取り出す
                .filter(domain => domain.startsWith(domainPart));
    
            matches.forEach(match => {
                const li = $('<li></li>').text(`@${match}`).appendTo(suggestionsList); 
                li.on('click', function () {
                    input.val(`${localPart}@${match}`); // フルアドレスをセット
                    suggestionsList.empty(); // リストをクリア
                    suggestionsList.hide();
                });
            });
    
            // サジェストリストの位置調整
            const rect = input[0].getBoundingClientRect();
            suggestionsList.css({
                position: 'absolute',
                left: `${rect.left + window.scrollX}px`,
                top: `${rect.bottom + window.scrollY}px`,
                width: `${rect.width}px`,
                display: matches.length ? 'block' : 'none'
            });
        });
    
        // 外部クリック時のリスト非表示
        $(document).on('click', function (event) {
            if (!input.is(event.target) && !suggestionsList.is(event.target) && suggestionsList.has(event.target).length === 0) {
                suggestionsList.hide();
            }
        });
    });
    </script>
    解決しない場合はこちら コンテンツに関しての
    要望はこちら