laravel6.2+jQuery¦画像登録時にプレビュー&デザインした画像選択ボタンを使う

2 min read読了の目安(約2600字

やりたいこと

・プロフィール画像などをアップロードする時にプレビューしたい
・画像選択ボタンを「ファイルを選択」から、画像やカスタムしたボタンにしたい

環境

・laravel 6.2
・php 7.2
・jQuery 3.2

ブラウザで画像ファイルを選択した時にプレビュー表示する方法を参考に実装しています。

①プロフィール画像などをアップロードする時にプレビューする

今回はno_image画像をstorageに保存しておいて、
・画像未登録時はno_image画像
・画像登録済みのときはDBから画像を表示
としています。(twitterのアイコンみたいな感じです🕊)

blade側の実装

画像登録済みのときはDBから画像を表示したいので、前回のlaravel6.2¦サイドバーやメニューにプロフィール画像を常に表示する!と同様$fileにbase64の画像の文字列、$mimeTypeに画像のmimeタイプを代入するように実装しています。

画像未登録時は@elseになり、no_image画像を表示させています。

@if (!empty($file))
    <img id="preview" src="data:image/{{$mimeType}};base64,{{$file}}">
@else
    <img id="preview" src="{{ asset('/storage/icon/profile_image.png') }}">
@endif
<input type="file" name="image" id="imageUpload" accept='image/*'>
no_image画像を使用しない場合

no_image画像を使用しない場合は↓のような1pxの空画像でもOKとのこと

<img id="preview" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">

JS側の実装

ブラウザで画像ファイルを選択した時にプレビュー表示する方法にある通り、元の画像を入れ替えている感じです。

$('#imageUpload').on('change', function (e) {
    let reader = new FileReader();
    reader.onload = function (e) {
        $("#preview").attr('src', e.target.result)
    }
    reader.readAsDataURL(e.target.files[0]);
});

done👏

②画像選択ボタンを「ファイルを選択」から、画像やデザインしたボタンにする

いろいろ頑張ってみたのですが<input type="file">にすると、よく見る定番のあのボタンになってしまうようなので
①inputボタンを非表示にする & ボタンにクリックイベント
②イベントが発火したらファイル選択できるようにする
...といった感じにしていきます。

blade側の実装

①のinputボタンを非表示にする & ボタンにクリックイベントを実装していきます。
単純にボタンの非表示はdisplay:noneにして、表示用のデザインしたbuttonタグを足します。

@if (!empty($file))
    <img class="c-avatar__image" id="preview" src="data:image/{{$mimeType}};base64,{{$file}}">
@else
    <img class="c-avatar__image" id="preview" src="{{ asset('/storage/icon/profile_image.png') }}">
@endif
<input type="file" name="image" id="imageUpload" accept='image/*' style="display:none">
<button class="ed-btn" id="imageUploadButton"><span class="ed-btn-text">写真を選択</span></button>

JS側の実装

②のイベントが発火したらファイル選択できるようにしていきます。
表示用のbuttonタグがクリックされたら、display:noneにしている<input type="file">のボタンもクリックされるようにしました。

$('#imageUploadButton').click(function(){
    $('#imageUpload').click();
    return false;
});

見た目的にはデザインされたボタンを押すと<input type="file">を押したのと同じ動きになっているかと思います。

おわりに

実際に実装したときは画像の登録+他の項目もまとめて編集する画面だったのですが、formタグの内にbuttonタグを実装したところ画像選択ボタンを押した時に全項目submitされてしまってしまいました( ᵕ ᵕ̩̩ )
②の実装をするときに<input type="file">のみformタグの中、buttonタグはformタグの外に書けばいいので、submitされてしまう問題も無事解決できました💫