<!DOCTYPE html>
<html lang=zh-Hant>
<head>
<title>picture upload with bootstrap and jQuery</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" ></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script>
</head>
<style>
.image-preview-wrapper{
display: block;
max-width: 310px;
max-height: 310px;
width: 100%;
border: 2px solid #cccccc;
margin: 0 auto;
position: relative;
cursor: pointer;
}
.spinner-wrapper {
opacity: 0;
margin: 0;
padding: 0;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.opacity-1 {
opacity: 1;
}
#idSubmit{
cursor:pointer;
}
#file-uploader, #idFilePath{
cursor:pointer;
}
</style>
<body>
<br /><br />
<div class="row">
<div class="col-12 col-md-6 mx-auto">
<a style="float:left" href="https://pjchender.blogspot.com/2019/01/js-javascript-input-file-upload-file.html">程式來源</a>
</div></div>
<br /><br />
<label class="text-center mb-5 image-preview-wrapper" for="file-uploader">
<img src="https://via.placeholder.com/500x300?text=click to upload" alt="image-placehoder" class="img-thumbnail" data-target="image-preview">
<!-- loading --->
<div class="spinner-wrapper position-absolute" data-target="spinner">
<div class="spinner-border text-secondary" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</label>
<div class="row">
<div class="col-12 col-md-6 mx-auto">
<div class="custom-file">
<form action="後台程式名.php" method="post" enctype="multipart/form-data">
<input type="file" class="custom-file-input" id="file-uploader" multiple accept="image/gif, image/jpeg, image/png" data-target="file-uploader" onchange="setFilePath()" >
<label class="custom-file-label" id="idFilePath">點按上傳檔案</label>
<br /><br />
<input type="submit" id="idSubmit" value="Submit">
</form>
</div>
</div>
</div>
</body>
<script>
function setFilePath(){
document.getElementById("idFilePath").innerText=document.getElementById("file-uploader").value;
}
</script>
<script>
// STEP 1: select element and register change event
const imagePreview = document.querySelector('[data-target="image-preview"]');
const spinner = document.querySelector('[data-target="spinner"]');
const fileUploader = document.querySelector('[data-target="file-uploader"]');
fileUploader.addEventListener("change", handleFileUpload);
async function handleFileUpload(e) {
try {
const file = e.target.files[0];
setUploading(true);
if (!file) return;
const beforeUploadCheck = await beforeUpload(file);
if (!beforeUploadCheck.isValid) throw beforeUploadCheck.errorMessages;
const arrayBuffer = await getArrayBuffer(file);
const response = await uploadFileAJAX(arrayBuffer);
alert("File Uploaded Success");
showPreviewImage(file);
} catch (error) {
alert(error);
console.log("Catch Error: ", error);
} finally {
e.target.value = ''; // reset input file
setUploading(false);
}
}
// STEP 2: showPreviewImage with createObjectURL
// If you prefer Base64 image, use "FileReader.readAsDataURL"
function showPreviewImage(fileObj) {
const image = URL.createObjectURL(fileObj);
imagePreview.src = image;
}
// STEP 3: change file object into ArrayBuffer
function getArrayBuffer(fileObj) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
// Get ArrayBuffer when FileReader on load
reader.addEventListener("load", () => {
resolve(reader.result);
});
// Get Error when FileReader on error
reader.addEventListener("error", () => {
reject("error occurred in getArrayBuffer");
});
// read the blob object as ArrayBuffer
// if you nedd Base64, use reader.readAsDataURL
reader.readAsArrayBuffer(fileObj);
});
}
// STEP 4: upload file throguth AJAX
// - use "new Uint8Array()"" to change ArrayBuffer into TypedArray
// - TypedArray is not a truely Array,
// use "Array.from()" to change it into Array
function uploadFileAJAX(arrayBuffer) {
// correct it to your own API endpoint
return fetch("https://jsonplaceholder.typicode.com/posts/", {
headers: {
version: 1,
"content-type": "application/json"
},
method: "POST",
body: JSON.stringify({
imageId: 1,
icon: Array.from(new Uint8Array(arrayBuffer))
})
})
.then(res => {
if (!res.ok) {
throw res.statusText;
}
return res.json();
})
.then(data => data)
.catch(err => console.log("err", err));
}
// STEP 5: Create before upload checker if needed
function beforeUpload(fileObject) {
return new Promise(resolve => {
const validFileTypes = ["image/jpeg", "image/png"];
const isValidFileType = validFileTypes.includes(fileObject.type);
let errorMessages = [];
if (!isValidFileType) {
errorMessages.push("You can only upload JPG or PNG file!");
}
const isValidFileSize = fileObject.size / 1024 / 1024 < 2;
if (!isValidFileSize) {
errorMessages.push("Image must smaller than 2MB!");
}
resolve({
isValid: isValidFileType && isValidFileSize,
errorMessages: errorMessages.join("\n")
});
});
}
function setUploading(isUploading) {
if (isUploading === true) {
spinner.classList.add("opacity-1");
} else {
spinner.classList.remove("opacity-1");
}
}
</script>
</html>