3

Basically, I'm in the process of experimenting with a web-based mock email client. for this, I've created a text editor, which when the user wishes to place or attach an image at a certain point in their message, they press a button which creates a new file-input. When uploaded, this then displays the image on their message.

When the user sends the message, the image src tags in the message are switched from the filereader template to a new src, and the file input's values are submitting and the images transfered to a new directory somewhere in the root folder of the website. This works perfectly fine. Images are unique, and a folder exists for each message with images inside them from the message itself.

The issue that I have right now is that when a user wishes to save their message as a draft, I need to do the same process. However, the only difference is that the form isn't submitted, and I simply use ajax to trigger a form upload. The issue I have is that I can't seem to access the file input's upload status. I can't submit the form because when I do I send the message out, which means I have to omit the $(form).submit( function (){}); system.

My question hence is: How do I submit an array of file inputs using ajax? This is my code so far:

JS:

$('a[data-command="save-reply"]').click(function(){
    messid = 1;
    var draftbool2 = 4;

    imgS = [];

    $("#inbox-reply-body").find("img").each(function(){
        if($(this).attr("data-sub-src")){
            var imgO = $(this).attr("data-sub-src");
            var imgN = imgO.replace("postid", messid);
            $(this).attr("src", imgN);
            $(this).removeAttr("data-sub-src");
        }
    });

    $(".image-list-reply").find("input[type='file']").each(function(){
        imgS.push($(this));
    });
    alert(imgS);
    var imgArray = JSON.stringify(imgS);
    alert(imgArray);
    var prevMessage = $('#message-body').html();
    var content = $('#inbox-reply-body').html();
    var body = content + "<hr><div id=\"reply-message\">" + prevMessage + "</div>";

    //formdata submitting id, draftbool, and body
    var fd2 = new FormData();
    fd2.append('body', body);
    fd2.append('draftbool', draftbool2);
    fd2.append('idmessage', messid);
    fd2.append('image', imgArray);

    $.ajax({
        type: 'POST',
        url: "server/saveDraft.php",
        data: fd2,
        contentType: false,
        processData: false,
        success: function(done){
            alert(done);
        }
    });
});

PHP

$images = json_decode($_POST['image']);

foreach($images as $l){
    var_dump(implode(",", $images));
    foreach($l as $f => $name){
    $movedir = ("../resources/img/inbox/".$idofdraft."/");
    $dir = ("resources/img/inbox/".$idofdraft."/");

    $allowedExts = array("gif", "jpeg", "jpg", "png", "PNG", "JPG", "JPEG", "GIF");
    $temp = explode(".", $name);
    $extension = end($temp);
    //Set file type and size
    if ((($_FILES['image-reply']['type'] == "image/gif") || ($_FILES['image-reply']['type'] == "image/GIF") 
    || ($_FILES['image-reply']['type'] == "image/jpeg") || ($_FILES['image-reply']['type'] == "image/JPEG") 
    || ($_FILES['image-reply']['type'] == "image/jpg") || ($_FILES['image-reply']['type'] == "image/JPG") 
    || ($_FILES['image-reply']['type'] == "image/png") || ($_FILES['image-reply']['type'] == "image/PNG"))
    && ($_FILES['image-reply']['size'] < 1073741824)
    && in_array($extension, $allowedExts)){
        if($_FILES['image-reply']['error'][$f] > 0){
            echo "Return Code: ".$_FILES['image-reply']['error'][$f]."<br />";

        } else {
            if(file_exists($movedir)){
                echo " Directory Exists";
            } else {
                mkdir($movedir, 0777, true);
            }
            if(file_exists($movedir.$name)){
                echo " File already exists";
                $pathname = $dir.$name;
            } else {
                $names = $_FILES['image-reply']['tmp_name'];
                if(move_uploaded_file($names, "$movedir/$name")){
                    $pathname = ($dir."/".$name);
                    echo " File has been uploaded";

                    }
                }
            }
        }           
    }
}

HTML (echo'd in the full PHP file, hence the \")

<form id=\"inbox-reply\" method=\"post\" action=\"server/replyMessage.php\" enctype=\"multipart/form-data\">
    <a href=\"#\" data-command=\"insertImage\"><i class=\"fa fa-image\"></i></a>
        <input type=\"file\" id=\"image-upload\" name=\"image\"/>
        <a href=\"#\" data-command=\"insertattach\"><i class=\"fa fa-paperclip\"></i></a>
        <input type=\"file\" id=\"file-upload\" name=\"file\"/>
        <a href=\"#\" data-command=\"save-reply\"><i class=\"fa fa-floppy-o\"></i></a>
    </div>
    <div id=\"inbox-reply-body\" class=\"reply-content\" contenteditable>
    </div>

    <div class=\"image-list-reply\">

    </div> 
    <div class=\"attach-list-reply\">

    </div>
    <input type=\"submit\" name=\"reply\" value=\"Send\">
</form>

Normally I would replace foreach($l as $f => $name) with foreach($_POST['image-reply'] as $f => $name) and that would work, but here I'm supposed to submit the $_POST['image-reply'] via ajax, which forces me to put all the file inputs in an array. My issue is getting them from the array as usable php elements. Can anyone help me?

PS sorry for my lack of clarity, I'm not sure how to approach the community with a problem, let alone this one! In short, How do i pick up usable file input data from an array of file inputs submitted via ajax?

Endless
  • 34,080
  • 13
  • 108
  • 131
Basik
  • 65
  • 1
  • 8
  • 1
    Please show your HTML code as well, it would be easier to view the question from the overall perspective. – Rajdeep Paul Dec 20 '16 at 19:28
  • Good shout. I pasted the relevant html, which was echod from a different PHP file. all files are huge anyway. Just another thing, all newly created file inputs (activated when clicking on the insert-image) appear in image-list-reply, with name image-reply, and id of image-reply as well – Basik Dec 20 '16 at 19:37
  • 1. Instead of `.click()`, bind the elements with `.change()`, so that whenever something changes, fire AJAX call with appropriate data. 2. This SO thread will guide you how to upload multiple images using jQuery/AJAX, [http://stackoverflow.com/questions/15259632/upload-multiple-images-with-jquery-ajax-and-process-them-with-php](http://stackoverflow.com/questions/15259632/upload-multiple-images-with-jquery-ajax-and-process-them-with-php) – Rajdeep Paul Dec 20 '16 at 21:32
  • The issue with that question is that doesn't tackle exactly what i'm doing. Instead of one file input supporting multiple files, i'm doing multiple file inputs supporting one file each. hence the struggle. I know it's not effective, but it's the only way I can preview the images wherever the user wants the images to display within a contenteditable div. I'm making my own text editor, only thing being weird is the image upload system, and only one bit of it. – Basik Dec 21 '16 at 02:04

1 Answers1

1

You can't stringify a DOM array.

This is what you have to do:

var fd2 = new FormData();

$(".image-list-reply").find("input[type='file']").each(function(){
  $.each(this.files, function(i, file){
    fd2.append('image', file)
  })
});

Also i still recommend you to use $(form).submit( function (){}); You can get good html5 validation from it but with the addition that you do event.preventDefault()

Endless
  • 34,080
  • 13
  • 108
  • 131
  • I get the javascript part of the solution. could you show the PHP part? it's what I'm definitely struggling with the most. Already thank you for this, I'm going to give it a shot. I'm just confused how I would submit this to a database this way? Also, I'm aware of the submit function, however I've already got another function running with a submit on the form, which is more core, so I'm trying a loophole around it. – Basik Dec 21 '16 at 01:28