6

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">&times;</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;
}
?>
20
  • 2
    Can you show the PHP code that is handling the upload? Because that code is most likely the reason for your issue. Commented Dec 5, 2019 at 12:49
  • show are your PHP script Commented Dec 5, 2019 at 12:51
  • @ChrisG yes i even thought about that and tried with stackoverflow.com/a/24895361/3836908 and my custom upload script stackoverflow.com/a/59141067/3836908 Commented Dec 5, 2019 at 12:51
  • @ahmednawazbutt added php script also tried with this code too stackoverflow.com/a/24895361/3836908 but nothing works Commented Dec 5, 2019 at 12:54
  • what is the output for $_FILES array? There is a chance that you only get 1 file there Commented Dec 5, 2019 at 12:56

2 Answers 2

3
+50

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.

Sign up to request clarification or add additional context in comments.

10 Comments

it works what about text Input are those normal form submission???
@sanojlawrence Sorry, what do you mean? Which text Input?
<input type="text"> i have multiple inputs are those normal form processing ?
@sanojlawrence If you have additional inputs, you need to add their name and .value to the FormData object. The form is not sent the regular way; you have to use AJAX instead for the images, so everything has to be handled by the code I posted.
can it be done in jQuery so that i can send <input type="text"> or how can i send data in above code
|
0

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

1 Comment

If you look at OP's code, the multiple attribute is already in there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.