画像をドラッグ&ドロップでアップロード
&
画像をドラッグ&ドロップで並び替える
方法をご紹介します!
用途
webサイトとかで、施設に画像を結びつけて、かつ、それをソート順で表示したいとかあるときに使えるよ。
ついでに画像も削除できます。
ついでに画像に説明文も登録できます。
参考サイト
https://codepen.io/malkafly/pen/gbVYZb
↑ほぼこれを丸パクリです。ありがとうございます!!!
使うプラグイン
- みんな大好きDropzoneJS
- jQuey UIのSortable
私はここからyarnで追加しました
コード
html側
<form method="post" action="/api/v1/facility-image/upload/" id="my-awesome-dropzone" class="image-upload-area dropzone">
<input type="hidden" name="client_id" value="{{ $facility->id }}"></div>
</form>
<ul class="visualizacao sortable dropzone-previews"></ul>
<div class="preview" style="display:none;">
<li>
<div>
<div class="dz-preview dz-file-preview">
<img class="facility-image" data-dz-thumbnail />
<input type="text" class="caption">
<button type="button" class="btn btn-info caption-button" data-image-id="">説明文登録</button>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
</div>
</div>
</li>
</div>
javascript側
import Dropzone from 'dropzone'
require('es-jquery-sortable')
let myDropzone = {}
dropzoneSetting()
//画像の並び替え
$(document).ready(function(){
let group = $('.sortable').sortable({
group: 'sortable',
onDrop: function($item, container, _super) {
var data = group.sortable('serialize').get()
_super($item, container)
//DB上の並び順を更新する
axios.post('/api/v1/facility-image/update-order/', {
data: data,
})
.catch((error) => {
swal('', '並び順の更新に失敗しました', 'error')
console.log(error)
})
}
})
})
/**
* dropzone.jsの処理
*
*/
async function dropzoneSetting() {
Dropzone.autoDiscover = false
//最大ファイルアップロードサイズ
let maxFileSize = 3
//企業ID
let clientId = $('#client-id').data('clientId')
myDropzone = new Dropzone('.image-upload-area', {
url: '/api/v1/facility-image/upload/',
params: {
client_id: clientId,
},
dictDefaultMessage: 'ここにファイルをドラッグ&ドロップ、または、クリックしてファイルを選択',
dictRemoveFile: '',
dictCancelUpload: '',
dictFileTooBig: 'ファイルサイズは' + maxFileSize + 'MBまで',
dictInvalidFileType: 'JPEG,PNGのみ可能',
addRemoveLinks: true,
maxFilesize: maxFileSize,
acceptedFiles: 'image/*',
parallelUploads: 1,
uploadMultiple: false,
previewsContainer: '.visualizacao',
previewTemplate : $('.preview').html(),
renameFile: (file) => {
let fileName = new Date().getTime() + '_' + file.size
let extension = file.name.split('.').pop()
return fileName + '.' + extension
},
})
//アップロードに失敗した場合
myDropzone.on('error', async function(file, errorMessage) {
//ファイル数が多い場合
if(errorMessage === '最大8ファイルまでしか添付できません') {
myDropzone.removeFile(file)
swal('', errorMessage, 'warning')
} else if(errorMessage === 'セッションが切れました。もう一度ログインしてください。') {
await swal('', 'セッションが切れました。もう一度ログインし直してください。', 'warning')
location.replace(location.href)
}
})
//画像を削除したときに、サーバー上のファイルも削除する
myDropzone.on("removedfile", function(file) {
let imageId = file.imageId
//画像ID
axios.get('/api/v1/facility-image/delete-by-image-id/' + imageId)
.catch((error) => {
console.log(error)
})
})
//既存の画像が表示されたときに情報を追加する
myDropzone.on("addedfile", function(file) {
$('.dz-preview').each(function() {
let imageId = $(this).children('.caption-button').data('imageId')
//画像IDが設定されていない場合のみ追加する
if(!imageId) {
let imageId = file.imageId
//今回追加した画像の場合は飛ばす
if(!imageId) {
return
}
$(this).children('.caption-button').data('imageId', imageId)
let caption = file.caption
$(this).children('.caption').val(caption)
$(this).parents('li').data('imageId', imageId)
}
})
})
//新しい画像がアップロードされたときに、画像IDを追加する
myDropzone.on("success", function(file, response) {
$('.dz-preview').each(function() {
let existImageId = $(this).children('.caption-button').data('imageId')
//画像IDが設定されていない場合のみ追加する
if(!existImageId) {
let imageId = response
$(this).children('.caption-button').data('imageId', imageId)
$(this).parents('li').data('imageId', imageId)
}
})
})
//すでに保存されている画像を表示する
$('.exist-image').each(function() {
let path = $(this).data('path')
let info = {
name: '',
size: '',
imageId: $(this).data('id'),
caption: $(this).data('caption')
}
myDropzone.emit("addedfile", info)
if(path) {
myDropzone.emit("thumbnail", info, path)
} else {
let base64 = 'data:' + $(this).data('type') + ';base64,' + $(this).data('binary')
myDropzone.emit("thumbnail", info, base64)
}
myDropzone.emit("complete", info)
})
//画像の説明文を登録
$(document).on('click', '.caption-button', function() {
let input = $(this).prev()
axios.post('/api/v1/facility-image/save-caption/', {
caption: input.val(),
image_id: $(this).data('imageId'),
})
.then(() => {
swal('', '説明文を登録しました', 'success')
})
.catch((error) => {
swal('', '説明文の登録に失敗しました', 'error')
console.log(error)
})
})
}
#まとめ
php側(私はLaravel使用しています)は、自分で実装してくださいね。
cssも自分で書いてね。
全然コードの説明してなくて、すみません。
いや、こういうの毎回やろうと思ったときに、過去のソースひっぱってくるの大変なので、Qiitaに置きました...