開発環境
- Rails 6.0.3.4
- Ruby 2.6.5
- MySQL 5.6.47
目次
1)cocoon導入方法
2)動的にフォームを追加
3)追加するフォームにidやdata属性を付与する ←
#3)追加するフォームにidやdata属性を付与する
自分のclass、id名 そのままだと読み取りにくいと思うので、わかりやすくA,B,Cとしています。
$(function() {
let index = 1;
// 最初に"index"の定義を忘れないように。
$('.class-parent')
// 私の場合は、"追加するボタン"と"追加したい子供"を全部囲む形でdivを作ってclassを付与したらいけました。この辺は要調節**
.on('cocoon:after-insert', function(e, insertedItem) {
// 'cocoon:after-insert'このイベントがキモです。他にも挿入前に実行するイベント、削除前・削除後に実行するイベントがあるので、気になる方は公式サイトをご覧ください。
$(insertedItem).find('.class-a').attr('data-a', index);
$(insertedItem).find('.class-b').attr('data-b', index);
$(insertedItem).find('.class-c').attr('data-c', index);
// 挿入したアイテムにdata属性を付与しています。 idを渡したい時は.attrの後ろをdata属性からidへ変更してください。
// 例).attr('id','index') **ちなみにindexは変数なんで、なんでもOKです。
// HTMLでこのような表記になります => data-a="index"
index = index+1
// indexへ1づつ追加することで、個別の数字をdata属性に付与することができます。
$('.data-a').on('change',function(e){
// 与えたdata属性を使ってイベントを起こす。
// 今回はAにchangeが起こったら、BとCのtextにAに基づいた値を入れるというイベントです。
const dataA = $(this).attr('data-a')
// dataAのchangeが起ったindex(数字)を取得しています。
const dataB = $("option:selected", this).data("b");
const dataC = $("option:selected", this).data("c");
$(`[data-b="${dataA}"]`).text(dataB)
$(`[data-c="${dataA}"]`).text(dataC)
})
})
})
View
<!-- 材料 -->
<!-- 省略 -->
<div class="class-parent">
<div class="row"> <!-- row/colはbootstrapのレスポンシブ用の記述方法なので特に気にしないでください。 -->
<div class="col-md-3 col-2">
材料
</div>
<div class="links col-md-2 col-5">
//↓↓↓ cocoonの追加ボタン
<%= link_to_add_association "追加", f, :ingredients,
class: 'add_fields',
id: 'add-btn',
data: {
association_insertion_node: '#detail-association-insertion-point',
association_insertion_method: 'after'
}
%>
</div>
</div>
//↓↓↓ 動的に追加するフォームを挿入するポイント(お好きなところで記述してください。なくても問題ありません)
<div id="detail-association-insertion-point"></div>
//↓↓↓ 動的に追加したいフォーム(renderで飛ばされてる)
<%= f.fields_for :ingredients do |form| %>
<%= render "edit_ingredient_fields", f: form %>
<% end %>
</div>
<!-- 省略 -->
↓↓↓説明記述しすぎて見難かったので、説明削除バージョンです。コードだけ見ればわかる方はこちらから
$(function() {
// 最初に定義を忘れないように。
let index = 1;
$('.onegai')
.on('cocoon:after-insert', function(e, insertedItem) {
$(insertedItem).find('.class-a').attr('data-a', index);
$(insertedItem).find('.class-b').attr('data-b', index);
$(insertedItem).find('.class-c').attr('data-c', index);
index = index+1
$('.class-a').on('change',function(e){
const dataA = $(this).attr('data-a')
const dataB = $("option:selected", this).data("b");
const dataC = $("option:selected", this).data("c");
$(`[data-b="${dataA}"]`).text(dataB)
$(`[data-c="${dataA}"]`).text(dataC)
})
})
})
以上です。