SPIRALフォームにおけるメールアドレス入力欄にドメイン部分のサジェスト機能を追加する方法について紹介いたします。
はじめに
メールアドレス入力欄にドメインのサジェスト機能を実装する方法として、以下の2種類の方法があります。
1. サジェストするドメインを全てソース内で管理する方法
2. ドメインを管理しているDBからドメインを取得し、サジェストに表示させる方法
それぞれの特徴やメリット・デメリットについて解説しながら、実装手順を紹介します。
| 実装種類 | ドメインをソースコード内で直接管理する方法 | ドメインリストDBを作成し読み込む方法 |
| メリット |
|
|
| デメリット |
|
|
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は、ページ内の
PC版とスマートフォン版でCSSを分ける必要はありません。
ただし、スマートフォン版のCSSを追加する場合は、PC版の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;
}
ドメインをソースコード内で直接管理する方法
概要説明
ソースコード内でドメインリストを管理する方法には、以下のようなメリットがあります。
サジェストを表示する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からドメインを取得し、サジェストに表示させる方法
概要説明
ドメインリスト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>