はじめに
画像投稿する際、投稿画像選択時に選択した画像(今回は1枚のみ)をプレビュー表示するまでを解説したいと思います。
完成イメージ
#環境
MacOS 10.15.7
ruby 2.6.5
Ruby on Rails 6.0.0
前提条件
jQueryの導入が完了済みであること。
作業していきましょう!
①画像投稿フォームを作成
はじめに、画像の投稿フォームを作成していきます。
▼フォームの完成イメージ
<div class='image'>
<label class="labelName" for="imageSpace">Photo </label>
<input class='imageInput' placeholder='写真を選択してください' type='file'>
</div>
<div class="prevImageBox">
</div>
.image {
color: #ffffff;
padding: 10px 16px 8px;
margin-top: 8px;
display: flex;
}
.imageInput {
color: #000000;
background-color: #fff;
border-radius: 5px;
border: 1px solid #ccc;
margin-left: 10px;
}
上記の記述で出来上がりです。
(フォームの背景の設定については今回省略しております)
htmlの
<div class="prevImageBox">
</div>
の部分については、選択した画像をプレビュー表示させるための要素(箱)になります。
②jQueryで実装していく
まずはjsファイルを作成します。ファイル名はなんでも良いですが今回は「image.js」というファイルを作成して、jQueryの記述をしていきます。
$(function(){
// <div class='image'>の直後の兄弟要素(今回の場合は<div class='prevImageBox'>がそれに該当)を取得。
const prevImage = $('.image').next();
// プレビュー表示部分のhtml
function buildHTML(id,image) {
let html = `<div class="prevImageBox">
<div class="upper-box">
<img src=${image} alt="preview">
</div>
<div class="lower-box">
<div class="delete-box">
<div class="delete-btn" data-delete-id= ${id}>削除</div>
</div>
</div>
</div>`
return html;
}
// ===========================================
// imageInputの値が変更したとき(画像が選択された時)の処理
// ===========================================
$(document).on('change', '.imageInput', function() {
//imageInputのidを取得
let id = $(this).attr('id');
//選択したfile(画像)のオブジェクトを取得
let file = this.files[0];
// PC内にあるファイルをアプリケーションに非同期で読み込む
let reader = new FileReader();
//readAsDataURLで指定したFileオブジェクトを読み込む
reader.readAsDataURL(file);
//読み込み時に発火するイベント
reader.onload = function() {
// 直前に実行されたイベント(imageファイルの読み込み)を変数imageに代入
let image = this.result;
//htmlを作成
let html = buildHTML(id,image);
//<div class='prevImageBox>にプレビュー画像を追加
$(prevImage).append(html);
//画像が選択された状態(プレビュー画像表示中)だと、画像選択フォームを隠す
$('.imageInput').hide();
}
});
// ==================================
// プレビュー画像を削除する場合の処理
// ==================================
$(document).on('click', '.delete-btn', function() {
let id = $(this).attr('data-delete-id')
//画像を消去
$(this).parent().parent().parent().remove();
//画像選択フォームの中身を空にする
$('.imageInput').val("");
//画像選択フォームを表示
$('.imageInput').show();
});
});
以上が、jQueryの記述となります。
プレビュー画像部分のCSSも載せておきます。
.prevImageBox {
display: block;
width: 10vw;
margin: 0 15px 10px 0;
padding-left: 45px;
.upper-box {
height: 100%;
width: 100%;
img {
width: 100%;
height: 100%;
}
}
.lower-box {
display: flex;
text-align: center;
.delete-box {
color: #00b0ff;
width: 100%;
height: 50px;
line-height: 50px;
border: 1px solid #eee;
background: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
.delete-btn {
background-color: #f5f5f5;
line-height: 40px;
width: 60px;
}
}
}
}
プレビュー画像のサイズについては.prevImageBoxのwidthで調整してみてください。
簡単に解説
4行目で
const prevImage = $('.image').next();
として、「nextメソッド」を使って、imageクラスの兄弟要素にあたるprevImageBoxを取得して、それを変数prevImageに格納しています。
nextメソッドについては以下が参考になります。
http://js.studio-kingdom.com/jquery/traversing/next
6〜19行目の
function buildHTML(id,image) {
let html = `<div class="prevImageBox">
<div class="upper-box">
<img src=${image} alt="preview">
</div>
<div class="lower-box">
<div class="delete-box">
<div class="delete-btn" data-delete-id= ${id}>削除</div>
</div>
</div>
</div>`
return html;
}
に関しては、実際に表示させるプレビュー画像部分のhtmlとなります。
構造としては、PrevImageBoxという大枠の中に、upper-boxとlower-boxの2段に分けた構造になります。
upper-boxにはイメージ画像を導入し、lower-boxには画像削除用ボタンを搭載する形となっております。
あとは、
画像を選択する時の処理
// ===========================================
// imageInputの値が変更したとき(画像が選択された時)の処理
// ===========================================
$(document).on('change', '.imageInput', function() {
//imageInputのidを取得
let id = $(this).attr('id');
//選択したfile(画像)のオブジェクトを取得
let file = this.files[0];
// PC内にあるファイルをアプリケーションに非同期で読み込む
let reader = new FileReader();
//readAsDataURLで指定したFileオブジェクトを読み込む
reader.readAsDataURL(file);
//読み込み時に発火するイベント
reader.onload = function() {
// 直前に実行されたイベント(imageファイルの読み込み)を変数imageに代入
let image = this.result;
//htmlを作成
let html = buildHTML(id,image);
//<div class='prevImageBox>にプレビュー画像を追加
$(prevImage).append(html);
//画像が選択された状態(プレビュー画像表示中)だと、画像選択フォームを隠す
$('.imageInput').hide();
}
});
プレビュー画像を削除する時の処理
// ==================================
// プレビュー画像を削除する場合の処理
// ==================================
$(document).on('click', '.delete-btn', function() {
let id = $(this).attr('data-delete-id')
//画像を消去
$(this).parent().parent().parent().remove();
//画像選択フォームの中身を空にする
$('.imageInput').val("");
//画像選択フォームを表示
$('.imageInput').show();
});
を分けて記述しております。