前段
bootstrap_form
を使ってる場合は、下記のステップが必要です。
bootstrap_form
を使ってると、このGemがよしなにUIを作成してくれるのですが、今回の実装では逆に邪魔になります。
<%= f.file_field :image %>
なので、 bootstrapのスタイルが適用されないようにしておきます。
<%= f.file_field_without_bootstrap :image %>
画像クリックでアップロード
<%= f.label :image do %>
<%= image_tag('user.png') %>
<%= f.file_field_without_bootstrap :image, style: 'display:none' %>
<% end %>
画像と file_field
を label
で囲って、 file_field
をCSSで非表示にするだけです。
画像の部分をアイコンとかに置き換えればアイコンクリックでアップロードができます。
表示されている画像をアップロードした画像に差し替える
JSから要素を取得できるように画像とアップローダーに適当なクラス名を追加。
<%= f.label :image do %>
<%= image_tag('user.png', class: 'avatar') %>
<%= f.file_field_without_bootstrap :image, class: 'uploader', style: 'display:none' %>
<% end %>
JavaScriptで選択された画像をbase64にエンコーディングして、元の画像と差し替えます。
window.addEventListener('load', () => {
const uploader = document.querySelector('.uploader');
uploader.addEventListener('change', (e) => {
const file = uploader.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const image = reader.result;
document.querySelector('.avatar').setAttribute('src', image);
}
});
});
※見た目の細かい調整は省いてます
※フロントで画像を差し替えただけなので、フォームが送信がされないと画像はサーバーに送信されません