やりたいこと
・画像を選択しlaravel側に画像データを保存する
ステップ1(formの設定)
画像選択をできるようにするためinputタグのtypeをtype="file"
にする。
そうすることで、選択されたファイルはフォーム投稿を使用してサーバーにアップロードしたり、 JavaScript コードと File API を使用して操作したりすることができる。
multiple
= 複数のファイルを一度に選択することができる
accept
= ファイル入力欄が受け付けるファイル型を定義できる
↓詳しくはこちら
https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/file
また、ファイルアップロードをする場合はformタグにenctype="multipart/form-data"
を指定する必要がある。
enctype="multipart/form-data"
を指定しない場合、添付ファイルの情報を送信できないため、サーバー側では添付ファイルを扱えない。....多分。
<form action="{{route('admin.article.update', $viewData['articleId'])}}" method="POST" enctype="multipart/form-data">
<!--セクション1-->
<div id="section_id">
<img id="img_prv" src="" alt="">
<input id="img_upload" value="" onChange="changeImage(event)" type="file" name="imagesPath[]" multiple="multiple" accept="image/*">
</div>
<!--セクション2-->
<div id="section_id">
<img id="img_prv" src="" alt="">
<input id="img_upload" value="" onChange="changeImage(event)" type="file" name="imagesPath[]" multiple="multiple" accept="image/*">
</div>
</form>
ステップ2(選択した画像を表示)
function changeImage(event) {
//FileReaderを使用することでユーザーのコンピュータに保存されているファイルの内容を非同期に読み取ることができる。
const reader = new FileReader();
// 新規ファイルデータを取得
const fileData = event.target.files[0];
//↓ちゃんと取れていればOK
console.log(fileData);
// 今回は一つの記事に対して複数のセクションがあるため画像を表示させる要素を取得する必要がある
let sectionId = this.event.path[1];
const imagPreview = $(sectionId).children('#img_prv');
// 画像を表示させる処理
// onloadは、データの読み込みが正常に完了した時に発火する
reader.onload = function (event) {
$(imagPreview).attr('src', event.target.result).css('width', '150px').css('height', '150px');
}
// 読み込みを実行
reader.readAsDataURL(event.target.files[0]);
//sendImagePath関数に引数として新規ファイルデータ,画像を表示させる要素を渡す
sendImagePath(fileData,sectionId);
}
ステップ3(Laravelに送る)
function sendImagePath(fileData,sectionId){
//$viewData['appUrl']にはlaravel側から送られた「http://localhost:81」という文字列が入っている
const appUrl = @json($viewData['appUrl']);
// 新規画像のIDを入れるinputタグを取得
let newImageId = $(sectionId).children('#img_id');
const params = new FormData();
//append()を使用してLaravel側に送るデータを設定(keyをfileとしvalueをfileDataにする)
params.append('file', fileData);
axios.post(
appUrl + '/api/v1/images',
params,
{
headers: {
'content-type': 'multipart/form-data',
},
})
.then(res => {
if(res.data){
// レスポンスで返ってきたIDをinputに代入
$(newImageId).val(res.data.id);
}else{
confirm('画像が読み込まれませんでした。もう一度選択してください');
};
}).catch((error) => {
console.log("エラー");
})
}
params.append('file', fileData);
に関して、append()ではなくset()でも可能。
set() = 同じkeyがあれば上書き
append() = 上書きせずに追加