sanoj lawrence
sanoj lawrence

Reputation: 993

Unable to add or remove image from multiple html input field

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;
}
?>

Upvotes: 6

Views: 2383

Answers (2)

saadmrb
saadmrb

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

user5734311
user5734311

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

Related Questions