学習備忘録

よく忘れてしまうのをここにメモしておく

jquery複数の値入力周りのまとめ

課題

  • 入力フォームで複数の値を入力したい
  • 入力フォームの行を動的に増やした
  • 動的に増やした入力フォームに対して、イベント追加したい
  • イベントを検知した要素を取得したい
  • 複数の値を入力するフォーム(select2など)を動的に増やした場合に、適切にpostする方法。
  • select2の選択肢をjqueryで操作する方法

対策

入力フォームで複数の値を入力したい

<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);
  // select2 を remove して再設定する
  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))//セレクトボックスのoptionの追加
      });
    }
  });

  //セレクトボックスのoptionの削除
  select.val(null).trigger('change')
});