LoginSignup
0
0

More than 1 year has passed since last update.

動的にフォームを追加、削除する

Last updated at Posted at 2022-06-07

追加した分もDBに保存したい

初投稿です。

フォームを追加、削除する記事はいくつかあったのですが、
DBに保存できるようにする記事は見つけられなかったので備忘録として投稿します。

初学者なのでアラが目立つコードだと思いますが、どなたかの役に立てば幸いです。

間違えや、添削があればコメントにて教えていただければものすごく嬉しいです。

new.html.rb

<!--動的に追加、削除できる材料、分量のフォームを別テーブル(ingredients)に保存-->
<%= javascript_pack_tag 'addForm.js'%>

  <%= f.fields_for :ingredients do |ingredient| %>

    <div id="ingredient-main">
      <div id="ingredient-form">
        <div id="add-form">
          <%= ingredient.text_field :name, id:"ingredient-name_0",  placeholder: "材料-0" %>
        </div>
        <div id="add-form">
          <%= ingredient.text_field :amount, id:"ingredient-amount_0", placeholder: "分量-0" %>
        </div>
        <div class="delete" id='add-form'>
          <button type="button" id="ingredient-btn_0" class="delete-btn" >
            削除
          </button>
        </div>
      </div>
    </div>
  <% end %>
    
addForm.js


let formNum = 0

//ページがロードされると...
window.addEventListener("load", function () {
  
  //材料追加ボタンの要素をidから取得
  const addButton = document.getElementById("add-btn");

  //取得したボタンをクリックすると...
  addButton.addEventListener("click", function() {

    //1行目で変数宣言したformNumに1を足す。(formNumに1が+される)
    formNum += 1

    //材料と分量のフォーム、削除ボタンを取得,formListに代入
    const formList = document.getElementById("ingredient-main")

    //html要素を取り出し記入,idとplaceholderの0に指定していたところに
    //${formNum}を挿入することで、一つ目のフォームにはingredient-name_0、
    //二つ目はingredient-name_1、三つ目はingredient-name_2と足されていく
    const html = ` <div id="ingredient-form">
                    <div id="add-form">
                      <input id="ingredient-name_${formNum}" placeholder="材料-${formNum}"
                                             type="text" name="repertoire[ingredients_attributes][${formNum}][name]">
                    </div>
                    <div id="add-form">
                      <input id="ingredient-amount_${formNum}" placeholder="分量-${formNum}" 
                                             type="text" name="repertoire[ingredients_attributes][${formNum}][amount]"> 
                                        </div>
                    <div class="delete" id='add-form'>
                      <button type="button" id="ingredient-btn_${formNum}" class="delete-btn" >
                        削除
                      </button>
                    </div>
                  </div>`;

    //insertAdjacentHTMLでノードを複製、挿入場所を16行目で定義したformList内に指定する。
    //引数のbeforeendで複製場所を末尾に指定,htmlで複製するものを指定する。
    //この一行での処理を要約すると、
    //『(html)を複製(insertAdjacentHTML)し、(formList)の末尾(beforeend)に挿入する』
    formList.insertAdjacentHTML('beforeend', html);

    //全ての削除ボタンを取得、deleteBtnsに定義する
    const deleteBtns = document.querySelectorAll('.delete-btn')

    //削除ボタンをforEachで繰り返し処理
    deleteBtns.forEach((btn) => {
      //deleteBtns要素(btn)をクリックすると53行目sample関数が実行される
      btn. addEventListener('click', sample)
})
  })
  //deleteBtnsのparentNode(親ノード)のさらにparentNode(親ノード)をremove(削除)する関数
  function sample() {
    this.parentNode.parentNode.remove()
  }

})

フォームを追加する考え方自体はシンプルだと思うのですが、思うように行かずこのコード実装で何日も溶かしてしまいました...

反省を次に生かします。

最後まで読んでいただき、ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0