Reputation: 993
i use https://github.com/promosis/file-upload-with-preview to display preview for multiple image
var upload = new FileUploadWithPreview('myUniqueUploadId', {
maxFileCount: 4,
text: {
chooseFile: 'Maximum 4 Images Allowed',
browse: 'Add More Images',
selectedCount: 'Files Added',
},
});
.custom-file-container {
max-width: 400px;
margin: 0 auto;
}
<link href="https://unpkg.com/[email protected]/dist/file-upload-with-preview.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/[email protected]/dist/file-upload-with-preview.min.js"></script>
<form action="save.php" method="post" enctype="multipart/form-data">
<div class="custom-file-container" data-upload-id="myUniqueUploadId">
<label>Upload File <a href="javascript:void(0)" class="custom-file-container__image-clear" title="Clear Image">×</a></label>
<label class="custom-file-container__custom-file">
<input type="file" name="files[]" class="custom-file-container__custom-file__custom-file-input" accept="image/*" multiple aria-label="Choose File">
<input type="hidden" name="MAX_FILE_SIZE" value="10485760" />
<span class="custom-file-container__custom-file__custom-file-control"></span>
</label>
<div class="custom-file-container__image-preview" style="overflow: auto!important"></div>
</div>
<input type="submit" value="Upload Image" name="submit">
</form>
it works fine, but i can't add a extra image are remove image.
https://github.com/promosis/file-upload-with-preview/issues/30#issuecomment-563352824 enableing cachedFileArray
example
Adding
i added 3 images to input, i get 3 images in preview without submitting form i added 1 image now i get 4 images in preview, When i submit the form i get only 1 image upload(recently added file).
Removing
it happens same in removing image added 4 images and removed 1 image when i upload all 4 images are uploaded, everything happen only on preview but noting happen in <input>
----Is there any other better way to do(other codes or library) But i want to use my custom upload handler.
PHP upload handler
$desired_dir = "$_SERVER[DOCUMENT_ROOT]/upload/file/";
$thumb_directory = "$_SERVER[DOCUMENT_ROOT]/upload/thumb/";
$file = [];
$nw = 125;
$nh = 90;
if (!empty($_POST)) {
if (isset($_FILES['files'])) {
$uploadedFiles = array();
foreach ($_FILES['files']['tmp_name'] as $key => $tmp_name) {
$errors = array();
$file_name = md5(uniqid("") . time());
$file_size = $_FILES['files']['size'][$key];
$file_tmp = $_FILES['files']['tmp_name'][$key];
$file_type = $_FILES['files']['type'][$key];
if ($file_type == "image/gif") {
$sExt = ".gif";
} elseif ($file_type == "image/jpeg" || $file_type == "image/pjpeg") {
$sExt = ".jpg";
} elseif ($file_type == "image/png" || $file_type == "image/x-png") {
$sExt = ".png";
}
if (!in_array($sExt, array('.gif', '.jpg', '.png'))) {
$errors[] = "Image types alowed are (.gif, .jpg, .png) only!";
}
if ($file_size > 2097152000) {
$errors[] = 'File size must be less than 2 MB';
}
if (empty($errors)) {
if (is_dir($desired_dir) == false) {
mkdir("$desired_dir", 0700);
}
$file_name_with_ext = $file_name . $sExt;
$source = $desired_dir . $file_name_with_ext ;
if(!move_uploaded_file($file_tmp, $source)) {
echo "Couldn't upload file " . $_FILES['files']['tmp_name'][$key];
$file[] = NULL;
}else{
$size = getimagesize($source);
$w = $size[0];
$h = $size[1];
switch ($sExt) {
case '.gif':
$simg = imagecreatefromgif($source);
break;
case '.jpg':
$simg = imagecreatefromjpeg($source);
break;
case '.png':
$simg = imagecreatefrompng($source);
break;
}
$dest = $thumb_directory. $file_name_with_ext ;
$dimg = resizePreservingAspectRatio($simg, $nw, $nh);
imagepng($dimg, $dest);
// imagewebp($dimg, $dest);
compress($source, "$desired_dir" . $file_name_with_ext , 50);
compress($dest, $dest , 50);
$file[] = $file_name_with_ext ;
}
}else{
// TODO: error handling
}
}
}
$stmt = $conn->prepare("INSERT INTO allpostdata(im1, im2, im3, im4)"
. " VALUES (:im1, :im2, :im3, :im4)");
$stmt->bindParam(':im1', $file[0], PDO::PARAM_STR, 100);
$stmt->bindParam(':im2', $file[1], PDO::PARAM_STR, 100);
$stmt->bindParam(':im3', $file[2], PDO::PARAM_STR, 100);
$stmt->bindParam(':im4', $file[3], PDO::PARAM_STR, 100);
if ($stmt->execute()) {
header('Location: https://google.com');
}exit;
}
function compress($source, $destination, $quality) {
$info = getimagesize($source);
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($source);
} elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($source);
} elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($source);
}
imagejpeg($image, $destination, $quality);
return $destination;
}
function resizePreservingAspectRatio($img, $targetWidth, $targetHeight) {
$srcWidth = imagesx($img);
$srcHeight = imagesy($img);
$srcRatio = $srcWidth / $srcHeight;
$targetRatio = $targetWidth / $targetHeight;
if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight)) {
$imgTargetWidth = $srcWidth;
$imgTargetHeight = $srcHeight;
} else if ($targetRatio > $srcRatio) {
$imgTargetWidth = (int) ($targetHeight * $srcRatio);
$imgTargetHeight = $targetHeight;
} else {
$imgTargetWidth = $targetWidth;
$imgTargetHeight = (int) ($targetWidth / $srcRatio);
}
$targetImg = imagecreatetruecolor($targetWidth, $targetHeight);
$targetTransparent = imagecolorallocate($targetImg, 255, 0, 255);
imagefill($targetImg, 0, 0, $targetTransparent);
imagecolortransparent($targetImg, $targetTransparent);
imagecopyresampled($targetImg, $img, 0, 0, 0, 0, $targetWidth, $targetHeight, $srcWidth, $srcHeight);
return $targetImg;
}
?>
Upvotes: 6
Views: 2383
Reputation: 1
I think that you should just have to make sure to add the multiple parameter to your input like this:
input type="file" class="custom-file-container__custom-file__custom-file-input" accept="*" multiple
Upvotes: 0
Reputation:
I successfully got this to work using the method described by the author, but I'm using fetch()
instead of jQuery:
document.forms[0].addEventListener("submit", async function (e) {
e.preventDefault();
const url = this.getAttribute("action"); // grab endpoint from HTML
const fd = new FormData(); // create FormData object
upload.cachedFileArray.forEach((file, i) => {
fd.append("files[]", file); // append each file to FormData object
});
this.querySelectorAll("input[name], select, textarea").forEach(el => {
fd.append(el.getAttribute("name"), el.value);
});
const response = await fetch(url, {
method: 'POST',
body: fd
});
// optional processing of server response
const text = await response.text();
console.log('Success:', text);
// what happens after upload here
location = "https://google.com"; // navigate to Google
});
Add this to your script. It intercepts the form submission, creates a FormData
object based on the File array, adds the remaining form fields, then submits it to the url stated it the form's action
attribute.
Note that you should probably remove the name
attribute from the <input type="file">
on the form, since we don't want to add that to the FormData.
Upvotes: 3