概要
- JavaScriptのjQueryを使って、「ボタンをクリックすると動的に入力欄が増えていく」という実装を行いました。本記事ではその方法を紹介します。
前提・実装方法
- 今回はdjangoを使っている中で実装しましたが、HTML部分とJavaScript部分だけなのでPythonは関係ありません。
- 以下の動作を想定します。
- ページ(テンプレート)に最初に一つだけ入力フィールド(テキストフィールド)が表示される。
- 「+」ボタンをクリックすると、新しい入力フィールドが追加される。それぞれ一意のIDが与えられる。
- 「+」ボタンをクリックすると「-」削除ボタンも一緒に追加される。これをクリックすると追加した入力フィールドが削除できる
- 以上の操作により、ユーザーが必要な数だけ入力フィールドを追加できるものとしました。
サンプルコード
- 今回は「IPアドレス」という入力フィールドが動的に増えるサンプルコードを紹介します。
<!-- CSS省く -->
<div class="container ip-fields-container">
<div class="row">
<div class="col-sm-2 flex flex-center">
<label for="">IP</label>
</div>
<div class="col-sm-4">
<input type="text" id="" class="form-control" placeholder="" name="ip_addresses[]" value="">
</div>
<div class="col-sm-4">
<button id="add-field-btn" type="button">+</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.datatables.net/1.11.2/js/jquery.dataTables.min.js"></script>
<!-- 動的に入力フィールドを増やすJS -->
<script>
var fieldCount = 1;
$(document).on('click', '#add-field-btn', function() {
fieldCount++;
var newField = $('<div class="row">' +
'<div class="col-sm-2">' +
' <label for="ip' + fieldCount + '">IP</label>' +
'</div>' +
'<div class="col-sm-4">' +
' <input type="text" id="ip' + fieldCount + '" class="form-control" placeholder="" name="ip_addresses[]" value="">' +
'</div>' +
'<div class="col-sm-4">' +
' <button class="remove-field-btn" type="button">-</button>' +
'</div>' +
'</div>');
$('.ip-fields-container').append(newField);
});
$(document).on('click', '.remove-field-btn', function() {
$(this).closest('.row').remove();
});
</script>
詳細に解説
- 以下は基礎的なこともまとめておいたので、知っている方はスルーくだされ。
jQueryについて
- jQueryはJavaScriptのライブラリであり、HTML文書内でのDOM操作やイベント処理などを簡単に使えることで人気です。
- 最初にjQueryとDataTablesというライブラリのCDNを追加します。
-
$(document)
は、HTMLドキュメント全体を表すjQueryオブジェクト -
.on('click', '#add-field-btn', function() { ... })
は、クリックイベントの監視とそのハンドラ関数の設定 - つまり、「ドキュメント内の
#add-field-btn
というIDを持つ要素がクリックされたときに、以下のハンドラ関数を実行するよ」という意味です。
id
とfieldCount
について
-
id=""
は、入力フィールドの一意の識別子です。 - HTML(最初の方)では、空の値が指定。
- JSで追加される方は
id="ip' + fieldCount + '":
としています。fieldCount
は「入力フィールドが動的に生成されるたびにインクリメントされる」変数です。これにより、各入力フィールドが一意のIDを持つことができます。 - スクリプト頭にある
fieldCount++
は、fieldCount += 1
と同じ意味です。フィールドの数をカウントするための変数fieldCount
の値を1増やします。
name
属性について
-
name="ip_addresses[]"
は、入力フィールドの名前属性です。 - フォームが送信される際は、この名前が使われます。
- 例えば、djangoであれば
forms.py
ではこの名前ip_addresses[]
で識別されます。私は今回、forms.py
のsave()
メソッドにて、ip_addresses[]
のリストの要素をfor文で取り出し、それぞれをDBに追加する、という処理を行いました。
- 例えば、djangoであれば
appendについて
-
var newField
は、新しいフィールドを作成するための変数です。この変数は、後続のコードで新しい要素を作成するために使用されます。var newField
には、新しいフィールドのHTML要素を表すオブジェクトが代入されます。このオブジェクトは、jQueryの $()
関数を使用して動的に作成されるものですね。 -
$('.ip-fields-container')
は、.ip-fields-container
クラスを持つ要素を選択します。この要素は、既存のHTMLにある<div class="container ip-fields-container">
のことです。 -
append(newField)
は、上記の<div>
で囲まれた部分に、新しい要素を追加するよ、という意味になります。これにより、新しいフィールドが既存の要素内に追加されます。
removeについて
-
$(this).closest('.row').remove();
は、クリックされた削除ボタンに最も近い.row
要素を削除する処理です。この場合、最も近く追加されたテキストフィールドが削除されます。-
.closest('.row')
:クリックされた削除ボタンに最も近い親要素で、クラス名が.row
である要素を取得できます
-