質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

86閲覧

field_forで1対多のフォーム登録の際に子要素が複数登録されない。

takuya-siro

総合スコア6

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2024/11/13 03:03

編集2024/11/17 02:40

実現したいこと

親(日報)、子(日報明細)の新規登録フォームの作成を目指しております。
子要素は訪問件数に伴い、増減が可能なフォームを想定しております。しかし子要素が1つしか登録されず、複数登録ができない状況となります。

発生している問題・分からないこと

パラメーターにおいて子要素が一つしか送信できないことが現在発生している問題となります。
View上でのフォーム送信画面は下記動画の通りとなります。

フォーム送信画面

ソースコードに現在のフォームのパラメーター記載しておりますが、下記の様なパラメーター送信されることがが理想となります。{"report_details_attributes"=>{"0"=>{"customer_id"=>"1", "content"=>"shott提案", "plan"=>"サンプリング"}}, "1"=>{"customer_id"=>"2", "content"=>"コーヒー提案", "plan"=>"後追い"}},}

該当のソースコード

Processing by ReportsController#create as HTML Parameters: {"authenticity_token"=>"H4buJGXUTDLbpTyVNoxJmRJuZvvrbLZBN88rDzT7c8tGqTF2wn8/aVEgqRjY25IP9M0VAoShrLptirzNSkGH2A==", "report"=>{"report_details_attributes"=>{"0"=>{"customer_id"=>"1", "content"=>"shott提案", "plan"=>"サンプリング"}}, "date"=>"2024-11-13T10:19", "employee_id"=>"1"}, "commit"=>"登録"}

new.html.erb

1<header class="ms-4 col-12"> 2 <%= render "shared/header" %> 3<header> 4<body> 5 <div id="customers" data-customers="<%= @customers.to_json %>"></div> 6 <br> 7 <h1 class="ms-4">新規日報作成</h1> 8 <br> 9 <!-- 追加ボタンの実装 --> 10 <button id="add">追加</button> 11 <!-- 日報フォーム部分の実装 --> 12 <%= form_with model: @report, local:true do |f| %> 13 <!-- 日報テンプレート部分 --> 14 <%= f.fields_for :report_details, @report.report_details.build do |report_detail| %> 15 <template id="field"> 16 <div> 17 <div id="search-view" > 18 <input type="text" id="search-input" placeholder="得意先を検索"> 19 <div id="test"> 20 </div> 21 </div> 22 <div id="result-view" class="mt-2"> 23 得意先名 24 <%= report_detail.text_field :customer_id, id:"report-detail-customer" %> 25 今回の内容 26 <%= report_detail.text_field :content, id:"report-detail-content" %> 27 次回の目標 28 <%= report_detail.text_field :plan, id:"report-detail-plan" %> 29 </div> 30 </div> 31 <!-- 日報詳細削除ボタンの実装 --> 32 <button id="delete">削除</button> 33 </template> 34 <% end %> 35 <!-- 日報詳細テンプレート部分はここまで --> 36 <!-- 日報詳細追加フィールド --> 37 <div id="add-field"> 38 </div> 39 <div> 40 日報日付 41 <%= f.datetime_field :date, class:"mt-4", id:"report-date" %> 42 </div> 43 <div> 44 <%= f.hidden_field :employee_id, :value => current_employee.id %> 45 </div> 46 <div> 47 <%= f.submit '登録', class: 'mt-4' %> 48 </div> 49 <% end %> 50 <!-- 日報フォーム部分はここまで --> 51</body>

add_element.js

1window.addEventListener('DOMContentLoaded', function() { 2 //追加ボタンの取得 3 let add = document.getElementById("add"); 4 //フォーム部分の取得 5 let field = document.getElementById("field"); 6 //追加先の取得 7 let addField = document.getElementById("add-field"); 8 //得意先情報の取得 9 let searchTargets = $('#customers').data('customers'); 10 11 add.addEventListener('click', function() { 12 event.preventDefault(); 13 //フォーム要素の追加 14 addField.appendChild(field.cloneNode(true).content); 15 16 //追加ボタンがされた際に各要素を取得 17 //検索欄の全取得 18 let searchInputs = document.querySelectorAll("#search-input"); 19 //検索結果親要素の全取得 20 let results = document.querySelectorAll("#test"); 21 //日報詳細欄の全取得 22 let reportDetails = document.querySelectorAll("#report-details-content") 23 //日報詳細の得意先名欄の取得 24 let roportDetailCustomers = document.querySelectorAll("#report-detail-customer"); 25 //削除ボタンの全取得 26 let deletes = document.querySelectorAll("#delete"); 27 28 29 30 //検索欄それぞれの処理 31 searchInputs.forEach(function(search) { 32 //検索欄に文字入力された際の処理 33 search.addEventListener("input", function() { 34 console.log("テスト"); 35 for (let i = 0; i < results.length; i++) { 36 //再度検索欄の全取得 37 let inputs = document.querySelectorAll("#search-input"); 38 //入力された文字の取得 39 let inputsValue = inputs[i].value.trim().toLowerCase(); 40 //検索結果表示欄の親情報の取得 41 let result = results[i]; 42 //日報詳細の得意先名欄の取得 43 let roportDetailCustomer = roportDetailCustomers[i]; 44 //検索結果を挿入する配列を作成 45 let array = [] 46 //入力された文字が得意先にマッチするかの処理 47 searchTargets.forEach((target) => { 48 //一度検索結果を全削除 49 let deleteName = document.querySelectorAll("#test-child"); 50 let deleteId = document.querySelectorAll("#customer-id"); 51 deleteName.forEach((name) => { 52 name.remove(); 53 }); 54 deleteId.forEach((id) => { 55 id.remove(); 56 }); 57 //検索欄が空欄の際の処理 58 if(!inputsValue) { 59 let newElement = document.createElement('div'); 60 newElement.setAttribute("id","test-child"); 61 newElement.innerHTML = "検索欄が空欄です"; 62 result.appendChild(newElement); 63 64 //入力された文字と得意先名がマッチした際の処理 65 } else if(target.name.includes(inputsValue)) { 66 array.push(target); 67 for (let i =0; i < array.length; i++) { 68 //検索結果の子情報を作成 69 let newEle = document.createElement('div'); 70 let customerId = document.createElement('div'); 71 //検索結果の子情報に命名 72 newEle.setAttribute("id","test-child"); 73 customerId.setAttribute("id","customer-id"); 74 //検索結果の子情報に値を挿入 75 newEle.innerHTML = array[i].name; 76 customerId.innerHTML = array[i].id; 77 customerId.style.display = 'none'; 78 //検索結果の子情報を表示 79 result.appendChild(newEle); 80 result.appendChild(customerId); 81 //検索結果の子情報を全取得 82 let customerNameAll = document.querySelectorAll("#test-child"); 83 let customerIdAll = document.querySelectorAll("#customer-id"); 84 //検索結果の子情報がクリックされた際の処理 85 for (let n=0; n < customerNameAll.length; n++) { 86 //クリックされた子情報を日報明細に挿入 87 customerNameAll[n].addEventListener('click', function() { 88 roportDetailCustomer.value = customerIdAll[n].innerHTML; 89 newEle.style.display = 'none'; 90 }); 91 }; 92 }; 93 }; 94 }); 95 }; 96 }); 97 }); 98 //検索欄から日報明細への登録の処理ここまで 99 }); 100});

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

追加ボタンが押された際に、cloneNodeでフォームを複製している為、理想的なパラメーターが送信されていないと考えました。その為、gemのcocoonを使用しフォーム追加する仕様にしましたが、複数登録のパラメーターが送信されませんでした。

補足

現在、学習の為、至らない箇所多いと考えられます。
その為、足りないソースコード等ありましたら追記します為、コメントいただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

2,3詳細を追加したところで htmlを覗いてみてください。
入力fieldの name がみな同じになってることでしょう。
同じ name のfieldが複数有ると一つしか送信しません。
cloneしたあとで nameを触ってからaddしてください。

投稿2024/11/17 15:38

winterboum

総合スコア23549

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takuya-siro

2024/11/19 12:41

コメントいただきありがとうございます。いただいアドバイスを元に試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問