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/file-upload-with-preview@4.0.2/dist/file-upload-with-preview.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/file-upload-with-preview@4.0.8/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;
}
?>
sanoj lawrence
  • 844
  • 4
  • 28
  • 64

2 Answers2

3

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.

ChrisG
  • 8,206
  • 4
  • 20
  • 34
  • it works what about `text Input` are those normal form submission??? – sanoj lawrence Dec 10 '19 at 16:32
  • @sanojlawrence Sorry, what do you mean? Which `text Input`? – ChrisG Dec 10 '19 at 17:04
  • `` i have multiple inputs are those normal form processing ? – sanoj lawrence Dec 10 '19 at 17:53
  • @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. – ChrisG Dec 10 '19 at 18:06
  • can it be done in jQuery so that i can send `` or how can i send data in above code – sanoj lawrence Dec 10 '19 at 19:08
  • @sanojlawrence I edited the code so it picks up all ``, ` – ChrisG Dec 10 '19 at 19:19
  • everything works fine, But even after clicking i see images are uploaded and `input` are sent but the page remains same no redirect, are refresh. – sanoj lawrence Dec 10 '19 at 20:11
  • @sanojlawrence Is your PHP script sending back a reply? Does it get logged in the console? – ChrisG Dec 10 '19 at 22:54
  • here is the console https://i.stack.imgur.com/nhyvY.png and now solved. https://stackoverflow.com/a/20035319/3836908 is that the correct solution. – sanoj lawrence Dec 11 '19 at 09:16
  • I thought that's a given but you need to remove `header('Location: https://google.com');` from your PHP script since you're no longer navigating there but requesting it via AJAX. Replace it with something like `echo count($_FILES['files']['size']) . " images uploaded";` – ChrisG Dec 11 '19 at 09:42
-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
Watercayman
  • 7,620
  • 10
  • 32
  • 46
saadmrb
  • 1
  • 1