datalistとJavaScriptで作るタグ入力フォームの実装ガイド
2024.11.17
基本的なHTML
複数入力・選択できるブログ記事のタグ入力UIのようなものを作る場合、datalist要素を使うのが良さそうです。
<input id="article-tag" name="taglist" list="taglist" value="" autocomplete="off">
<datalist id="taglist">
<option value=".htaccess">.htaccess</option>
<option value="CSS">CSS</option>
<option value="HTML">HTML</option>
<option value="JavaScript">JavaScript</option>
<option value="MySQL">MySQL</option>
<option value="Perl">Perl</option>
<option value="PHP">PHP</option>
</datalist>
上記のような感じで、タグ入力・選択フォームを作り、既存のリストからの選択も、新規入力もできるようにします。
複数選択できるようにする
前述のコードだけでは単一のタグが入力・選択できるだけなので、複数入力・選択できるように工夫を加えます。
まず、フォームからサーバーサイドに送るデータは、
<input type="hidden" name="tag[]" value="Perl">
<input type="hidden" name="tag[]" value="PHP">
<input type="hidden" name="tag[]" value="MySQL">
のような感じにしたいところ。
※name="tag[]"で複数指定することで、PHPなんかはそのまま複数の値を配列データとして受け取ってくれる。
なので、先ほどのinput id="article-tag"に値が入力・選択されたびに、type="hidden"の隠しinput要素をフォーム内に追加していくJavaScriptを書けば良いわけです。
まず、HTMLの方は、
<input id="article-tag" name="taglist" list="taglist" value="" autocomplete="off">
<datalist id="taglist">
<option value=".htaccess">.htaccess</option>
<option value="CSS">CSS</option>
<option value="HTML">HTML</option>
<option value="JavaScript">JavaScript</option>
<option value="MySQL">MySQL</option>
<option value="Perl">Perl</option>
<option value="PHP">PHP</option>
</datalist>
<!-- 入力・選択されたタグの挿入先の空ブロック -->
<div id="tag-container">
</div>
として、隠しinput要素をJSで追加するための空ブロックをあらかじめ用意しておきます。
その上で、以下のようなJavaScript(今回はjQueryで書きます)で、input id="article-tag"の値に変更があるたびに、隠しinput要素を追加するようにします。
$("#article-tag").change(function(){
let add_value = $(this).val();
if(add_value == ''){return false;}
addTags(add_value);
// タグ追加後は入力欄を空にする
$(this).val('');
});
function addTags(add_value){
// 追加済みのタグの一覧を取得
let tag_array = $('.addtags').map(function(){
return $(this).val();
}).get();
// 追加済みのタグと今回入力されたタグとの重複チェック
let finded = tag_array.find(tag_value => tag_value == add_value);
// 重複してたら何もせず終了
if(finded){return;}
// hiddenのinput要素
let add_input = '<input type="hidden" class="addtags" name="tag[]" value="' + add_value + '">';
// ユーザーに追加したタグがわかるようにテキストでも表示する
let add_tag = '<span class="tag-text">' + add_value + '</span>';
// 上記二つをまとめて追加するために別のspanで囲んでおく
let add_block = '<span class="tag-block">' + add_input + add_tag + '</span>';
$("#tag-container").append(add_block);
}
これで、input id="article-tag"の値が変更されるたびに、入力・選択されたタグが入力欄の下に、テキストと隠しinput要素として追加されるようになりました。
以下のHTMLのように追加されていきます。※タグとして「jQuery」と「Ruby」を追加した例。
<!-- 入力・選択されたタグの挿入先の空ブロック -->
<div id="tag-container">
<span class="tag-block">
<input type="hidden" class="addtags" name="tag[]" value="jQuery">
<span class="tag-text">jQuery</span>
</span>
<span class="tag-block">
<input type="hidden" class="addtags" name="tag[]" value="Ruby">
<span class="tag-text">Ruby</span>
</span>
</div>
Enterキーでも追加されるようにする
せっかくなので、タグを入力した後に、Enterキーの押下でタグが追加されるようにしたいところ。
というわけで、先ほどのJSに以下のコードを追加。
// Enterキーが押された時(keydown)の処理
$("#article-tag").on('keydown', function(e){
if(e.key==='Enter' || e.keyCode===13){
let add_value = $(this).val();
if(add_value == ''){return false;}
addTags(add_value);
return false;
}
});
// Enterキーが押され終わった時(keyup)の処理
$("#article-tag").on('keyup', function(e){
if(e.key==='Enter' || e.keyCode===13){
$(this).val('');
}
});
keydown時の処理は最後に必ずreturn falseを返すようにしておきましょう。これを忘れると、Enter押下と共にフォームが送信されてしまいます。
また、keydownとは分けてkeyup時に値を空にする処理を入れておかないとうまく動かないことがありました。
追加したタグを削除できるようにする
ここまできたら、入力ミスで追加されたタグを簡単に削除できるようにもしておきたいところ。
ということで、先ほどのJSで、タグの値とテキストをまとめて囲っていたspan class="tag-block"に「クリックされたら削除する」という処理を追加します。
$(document).on("click",".tag-block",function(){
$(this).remove();
});
※上記のコードが、$('.tag-block').click() ではなくて何故 $(document).on("click",".tag-block")なのかというと、前者の記述では、jQueryで後から追加した要素を検出・処理できないからです。
ついでに、CSSで「span class="tag-block"をクリックしたら削除できそう」感を出すために、以下のように「×」マークとかをつけておくと良いかもしれません。
.tag-text:after{
content: '×';
}
これで、複数のタグ入力・選択を行なえるUIが概ね出来上がりです。
セレクトボックスでデータ更新を実現する仕組みと実装例
2024.11.29
「チェックボックスを使ったデータ更新の仕組み」に続く記事として、今回はセレクトボックスを活用したデータ更新の方法をご紹介します。複数の選択肢から値を選び、それをサーバー側に送信して更新する仕組みを、実装例とともに解説します。
チェックボックスでデータ更新を実現する仕組みと実装例
2024.11.27
一覧画面のチェックボックスを用いて、データの状態を即時に更新する仕組みを実装する方法を解説します。HTMLの構造設計からJavaScriptの連携処理、サーバーサイドでの対応まで、説明しています。
ページリロードボタンを作成するシンプルな方法
2023.05.25
リロード機能を持つボタンを追加したい時に便利な、location.reload() を利用した実装方法を解説します。初心者にもわかりやすいコード例付きです。
Flexbox入門:ボックスを自動配置して均等に並べる方法
2023.04.27
Flexboxの基礎を学びながら、ボックスを均等に並べる方法を実例で紹介します。初心者向けの簡単なコーディング例です。