課題
- 入力フォームで複数の値を入力したい
- 入力フォームの行を動的に増やした
- 動的に増やした入力フォームに対して、イベント追加したい
- イベントを検知した要素を取得したい
- 複数の値を入力するフォーム(select2など)を動的に増やした場合に、適切にpostする方法。
- select2の選択肢をjqueryで操作する方法
対策
入力フォームで複数の値を入力したい
- フロント側
- multiple=multipleとする。
- プレースホルダーはplaceholder
<select name="stores[1][]" class="form-control select2-js-store-name cursor-pointer" multiple="multiple" data-placeholder="店舗(指定なし)">
</select>
- js
- select要素に対してselect2を呼び出す。※前提としてselect2を読み込んでいる必要がある。
$(document).ready(function () {
$('.select2-js-store-name').select2();
});
入力フォームの行を動的に増やしたい&&複数の値を入力するフォーム(select2など)を動的に増やした場合に、適切にpostする方法。
<div class="accounts-to-add">
<div class="row d-flex align-center justify-content-between margin-top-8 row-invitation-input">
<div class="col-md-3 pl-0 pr-1">
<input name='email[]' type="text" class="form-control border-radius-4"
placeholder="name@example.com">
</div>
<div class="col-md-2 pl-0 pr-1 select-store">
<div class="custom-select select2-div">
<select name="stores[1][]" class="form-control select2-js-store-name cursor-pointer" multiple="multiple" data-placeholder="店舗(指定なし)">
</select>
<i class="fa fa-chevron-down"></i>
</div>
</div>
<div class="col-md-1 px-0">
<span>
<button type="button" class="btn btn-add-key p-0 m-12 btn-add-account-row-delete"
onclick='deleteAccountRowOnAddModal(this)'>
<i class="fa fa-times"></i>
</button>
</span>
</div>
</div>
</div>
- js側
- INPUT_ACCOUNT_ROWで初期の1行目をクローンしておく
- ボタン(add-invitation-button)が押されたら、親要素(account-to-add)にクローンを追加する
- select2の場合追加後に、select2を設定しないとplaceholderが正しく表示されない。
store_length
以降の処理で新しく生成した要素に個別のnameを付けている。それにより、postされた側での処理がしやすくなる。
INPUT_ACCOUNT_ROW = $('.accounts-to-add').children().clone();
$('.add-invitation-button').click(function () {
let newLine = INPUT_ACCOUNT_ROW.clone(true);
newLine.find('span.select2-container').remove();
$('.accounts-to-add').append(newLine);
let stores_length = $('.accounts-to-add').children('div').length
newLine.find('.select2-js-store-name').select2()
newLine.find('.select2-js-store-name').attr('name', 'stores'+'['+stores_length+'][]')
});
動的に増やした入力フォームに対して、イベント追加したい&&select2の選択肢をjqueryで操作する方法&&イベントを検知した要素を取得したい
- js側
- documentに対して、第一引数にイベントを設定し第二引数で動的に増やした要素名を入力する。
$(this)
とすればイベントを検知した要素を取得できる。
$(document).on("change", ".select-company", function(){
let select = $(this).parent().parent().parent().find(".select2-js-store-name")
select.children().remove()
let val = $(this).val()
companies.forEach(company => {
if(val == company.id) {
company.stores.forEach(store => {
select.append($('<option>').attr({value: store.id}).text(store.title))
});
}
});
select.val(null).trigger('change')
});