LoginSignup
1
0

More than 1 year has passed since last update.

画像をクリックしてファイルを選択して即時変更する

Posted at

意外と参照できる記事がなかったので記述(基本的すぎて書いてないだけかも...)
通常の場合はファイルを選択するボタンを押して、submitボタンを押すことで変更が適用されます。
これを画像をクリックして、ファイルを開いたと同時に変更が適用されるようにしていきます。

求める挙動

画像をクリックしてファイルを選択して即時変更する

qiita_file.gif

実装手順

①「ファイルを選択」を押して、ファイルを選択して、submitを押せば画像が変更できるようになる
②画像をクリックして、ファイルを選択して、submitを押せば画像が変更できるようになる
③画像をクリックして、ファイルを選択して、submitを押さなくても変更が即時適用される

実装

①「ファイルを選択」を押して、ファイルを選択して、submitを押せば画像が変更できるようになる

→active storageで画像の取得、表示をする

active storageを使って画像の取得と表示をします。active storageについてはlink先のガイドの通りです。詳細は省きます。
https://railsguides.jp/active_storage_overview.html

モデルやコントローラのコーディングはlink先のガイドをみていただいて、ビューページに関しては以下のように記述すればファイルから画像を選択できます。

= form_with url: user_update_path, local: true do |f|  
    = f.file_field :image           #imageという名前で画像取得
    - if @user.image.attached?   #画像が保存されているか確認
        = image_tag @user.image   #@user.imageで画像表示
    - else
        = image_tag "user_images/twittericon.jpeg"   #なければ適当な画像を表示
    = f.submit              #submitを押すと画像をrecordに保存

とても簡単ですね。この段階ではファイルを選択が表示され、押すとファイルの選択ができ、submitを押すと変更が適用されます。

スクリーンショット_-_11月30日_午後9_06.png

このままではスタイリッシュさに欠けるのでファイルを選択を非表示にします。

②画像をクリックして、ファイルを選択して、submitを押せば画像が変更できるようになる

→1.file_fileddisplay:noneを追加  2.file_fieldimage_tagをlabelの下にネストする

まずfile_fieldのstyle属性にdisplay: noneを追記することでファイルを選択の表示を消します。

そのままでは画像をクリックしても何も起きません。そこでlabelをつくり、その下にfile_fieldimage_tagをネストさせます。そうするとfile_field image_tagをひとかたまりで扱えます。
まとめると以下のようなコードになります。

= form_with url: user_update_path, local: true do |f|
    = f.label :image  #<= 追記部分
        = f.file_field :image, style:"display:none;" #<= 追記部分
        - if @user.image.attached?
          = image_tag @user.image
        - else
          = image_tag "user_images/twittericon13.jpeg"
        = f.submit

ここまでで画像を選択して、ファイルを選択、submitを押せば変更が適用されるようになりました。
あとはsubmitを消すだけです

③画像をクリックして、ファイルを選択して、submitを押さなくても変更が即時適用される

→イベント属性にonchange: "submit(this.form)"追加

onchangeイベントを指定すると値が変化したときに実行されます。javascriptなど使っていれば馴染みがあるかもしれません。file_fieldにもイベントを指定できます。今回の場合はimageの中身が変わった時に変更が適用されるようにしたいです。
以下のようなコードになります。

= form_with url: user_update_path, local: true do |f|
    = f.label :image 
        = f.file_field :image, style:"display:none;", onchange: "submit(this.form)" #<= 追記部分
        - if @user.image.attached?
          = image_tag @user.image
        - else
          = image_tag "user_images/twittericon13.jpeg"
# submitは削除

ここまでで冒頭に挙げたような求める挙動になります。

他に使えるイベントについてはドキュメントを参照してください
https://railsdoc.com/form

まとめ

  • style: "display:none"でファイル選択を非表示に
  • onchangeがfile_fieldにもつかえる
1
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
1
0