ℙ𝕚𝕜𝕠𝔹𝕝𝕠𝕘 | プログラミングについて知ろう!

【HTML/CSS/JavaScript/jQuery/Ruby/Swift/MySQL/AWS】 プログラミングを 「今始めたばかりの方」や 「これから始めるか悩んでいる方」、 好きか嫌いかも分からない、 できるかどうかも分からない、 向いてるか向いてないかも分からない、 そんな思いを抱えた方へ届くような ブログを執筆していきます。

スポンサーリンク

Rails 画像複数投稿のやり方(js、jQueryでフォーム作成)

スポンサーリンク

f:id:kakikazu:20200207153312j:plain

 

こんにちは!

 

今回は前回記事でお話しした

 

Rails 画像複数投稿のやり方(carrierwaveとmini_magick)

 

から先に進めた画像の「複数枚投稿機能」実装について書いていきます。

 

 

実装内容は、

①画像投稿用のinputボタンに、フォームで画像を選択したタイミングでイベントをセットする。

 

②①のイベントが発生したら、新しい画像投稿フォームを生成する、というjs(JavaScript)のメソッドを動かす。

 

③生成した画像投稿フォームを画面に追加する。

 

 

 

です!

 

 

 

 

 

まず、タイトルにも書いてあるようにjjQueryを利用しますので

そのの準備から始めます。

 

GemfileにGem追加。

Gemfile
1
gem 'jquery-rails'

 

bundle installを忘れずに。

 

できたら次に

application.jsを変更

application.js
1
2
3
4
//= require turbolinks
//= require jquery
//= require jquery_ujs
//= require_tree .

これでjquery を使う準備ができました!

 

 

ここから4つに分けて進めます。

 

1.複数画像の投稿機能を実装。←今回はここまで

2.編集機能の実装。

3.プレビュー機能を実装。

4.削除の実装。

 

 

 

 

1つ目は、メインの複数枚投稿できる仕組み作りです。

 

まず、

投稿したい情報を載せる「基本フォーム」内の記述を修正。

_form.html.erb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<%= form_for @product do |f| %>
  商品名<%= f.text_field :name %><br>
  価格<%= f.number_field :price %><br>
  <div id="image-box">
    <%= f.fields_for :images do |image| %>
      <div data-index="<%= image.index %>" class="js-file_group">
        <%= image.file_field :src, class: 'js-file' %><br>
        <span class="js-remove">削除</span>
      </div>
    <% end %>
  </div>
  <%= f.submit %>
<% end %>

Jsで利用するためのclassやidをつけます。

Jsで使うものとわかるようにクラスは、「js-file_group」,「js-remove」,「js-file」 

IDは、jsで使うコード全体を包むものとし「image-box」とします。

 

またfield_forの中でimage.indexとするとビルドされた際にindexを取得することができます。

 

これらをカスタムデータとして持たせることで今後のjsの処理で特定していきます。

 

 

 

 

次にjsファイルに触れていきます。

products.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$(document).on('turbolinks:load', ()=> {

  const buildFileField = (index)=> {
    const html = `<div data-index="${index}" class="js-file_group">
                    <input class="js-file" type="file"
                    name="product[images_attributes][${index}][src]"
                    id="product_images_attributes_${index}_src"><br>
                    <div class="js-remove">削除</div>
                  </div>`;
    return html;
  }

let fileIndex = [1,2,3,4,5,6,7,8,9,10]; $('#image-box').on('change', '.js-file', function(e) { $('#image-box').append(buildFileField(fileIndex[0])); fileIndex.shift(); fileIndex.push(fileIndex[fileIndex.length - 1] + 1) }); $('#image-box').on('click', '.js-remove', function() { $(this).parent().remove(); if ($('.js-file').length == 0) $('#image-box').append(buildFileField(fileIndex[0])); }); });

 buildFileField関数には、field_forが生成するコードと同じ中身になるよう記述してあります。

またこの関数には、配列していく際の「先頭の数字」を渡すという記述を14行目に書いています。

 

 以上の記述で

「複数画像投稿の機能」実装ができました。

 

※ここで実装していて問題が発生。

「見本通りに書いたのにjsが機能していない」

 

いろいろ調べてみたところ

今回は、jsコードの始めの一文に問題があったようです。

 

参考資料:Rails5でjqueryを動かす方法

 

 

products.js
 
1
$(document).on('turbolinks:load', ()=> {

 上記の「 ( )=> 」の部分を修正します。

products.js
 
1
$(document).on('turbolinks:load', function() {

 

これで動くはずです。

 

 

 

 

今回も最後まで読んでくださりありがとうございます!

次回もよろしくお願いします。

 

スポンサーリンク