0

I'm using this plugin: jQuery HTML5 uploader (see the demo), inside a form. I want to send uploaded files with the POST method when user submit the form.

Maybe can I create a input[type="file"], make it hidden, and dynamically add uploaded files with the plugin inside the input? It is possible?


So, if I can't do that, how can I upload files to server with this plugin, only when user click on the submit button? I know that the plugin it's already doing that with AJAX, but I want to upload them only if user clicks on a button.

Maybe should I create a variable named for example files and, when user clicks on the submit button use AJAX myself to send files and the rest of inputs data?

Something like this:

jQuery( "#dropbox" ).html5Uploader({
    onClientLoadStart: function( event, file ) {
        files[] = file;
        [...]
    }
});

[...]

jQuery("#button").on("click", function() {
    jQuery.ajax({
        data: files
    });
    [...]
});

5 Answers5

3

You can't do that for security reasons. Just imagine the possibilities. I enter a file by JavaScript in a hidden field. You press submit. I get your file. Any file. Terrifying, right?

kraftner
  • 467
  • 2
  • 19
0

You can not select file in file uploader because of Browser security .

User can only do this not the script .

Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
0

this script already upload the files to the server.. what you need is a way to get back the files name/id from the server and attach them to hidden form.. than when someone submit the form you will know which files he uploaded..

youd do this by listen to the onSuccess event..

Amir Bar
  • 3,007
  • 2
  • 29
  • 47
  • Yeah, I know, but it upload files dynamically (using `name` and `postUrl` parameters) and not when user click on the submit button. Am I wrong? I'm using PHP so I must access files data using global `$_POST` variable. –  Feb 19 '14 at 14:55
  • lets say you postUrl is post.php when image is postes to that url you add their name and folder to database and return its id(or ids)... now in you upload form you need to had js function and listen to the onSuccess event.. in that event you get back the id of the uploaded images than by javascript/jquery you add that id to hidden input field.. and when the form is submited you get tham images id – Amir Bar Feb 19 '14 at 14:58
0

For security reasons you can not dynamically change the value an input field of type file. If that were possible, a malicious user could set the value to say: "c:\maliciousfile" and harm your system

Peter-kin
  • 1
  • 1
0

Looks like your question is two-part:

  1. How to dynamically add files to a form using JavaScript

    1a. (I'll throw in a bonus - previewing images)

  2. How to perform an Ajax file upload

1 Dynamically adding files to a form

What you want to do here create an <input type="file"> field and change the form value by Javascript. You can hide the input using CSS display: none;.

As far as I know, this can only be done using the FileReader API and drag and drop, and the API is limited.

You can replace and remove all files from an input but you can't append or remove individual files.

The basic drag/drop file upload looks like this:

const dropZone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');

dropzone.addEventListener('dragover', event => {
  // we must preventDefault() to let the drop event fire
  event.preventDefault();
});
dropzone.addEventListener('drop', event => {
  event.preventDefault();
  // drag/drop files are in event.dataTransfer
  let files = event.dataTransfer.files;
  fileInput.files = files;
  console.log(`added ${files.length} files`);
});
.upload {
  border: 1px solid #eee;
  border-radius:  10px;
  padding: 20px
}

.hidden {
  opacity: 0.5; 
}
<div id="dropzone" class="upload">Drop images here</div>
<input type="file" id="file-input" class="hidden" />

1a Previewing files

Working with Javascript opens up some fun options for form interactions, such as previewing uploaded files. Take for example an image uploader which can preview multiple drag-and-dropped images.

const imageTypeFilter = /image.*/;

const dropZone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');
const previewContainer = document.getElementById('preview-container');

function generateImagePreview(file) {
    const fileReader = new FileReader();
    fileReader.addEventListener('load', event => {
      // generate an image preview
      let image = document.createElement('img');
      image.classList.add('preview-image');
      srcAttr = document.createAttribute('src');
      srcAttr.value = fileReader.result;
      image.setAttributeNode(srcAttr);
      previewContainer.append(image);
    }, false); 
    // open and read the file
    fileReader.readAsDataURL(file);
}

function processFiles(files) {
  previewContainer.innerHTML = "";
  ([...files]).forEach((file, index) => {
    if (!file.type.match(imageTypeFilter)) {
      console.error("Incorrect file type:");
      console.log(file);
    } else {
      generateImagePreview(file);
    }
  });
}

dropZone.addEventListener('dragover', event => {
  // required to fire the drop event
  event.preventDefault();
});
dropZone.addEventListener('drop', event => {
  event.preventDefault();
  const files = event.dataTransfer.files;
  fileInput.files = files;
  processFiles(files);
});

fileInput.addEventListener('change', event => {
  processFiles(event.target.files);
});
.upload {
  border: 1px solid #eee;
  border-radius:  10px;
  padding: 20px
}

.preview-image {
  max-width: 100px;
  max-height: 100px;  
}

.hidden {
  opacity: 0.5; 
}
<div id="dropzone" class="upload">
Drag images here
</div>
<input id="file-input" type="file" multiple accept="image/jpeg,image/png,image/gif" class="hidden" />
<div id="preview-container"></div>

2 Perform an AJAX upload when the user clicks the submit button.

In this case, you want to override the default the form submit event which I believe would look something like this:

const submitUrl = 'https://httpbin.org/post';
const form = document.getElementById('ajax-form');

form.addEventListener('submit', event => {
  // this line prevents the default submit
  event.preventDefault();
  // convert the form into POST data
  const serializedFormData = new FormData(event.target);
  
  // use your favorite AJAX library
  axios.post(
    submitUrl,
    serializedFormData
  ).then(response => {
    console.log("success!");
  }).catch(error => {
    console.log("falied");
    console.log(error.response);
  });
});
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<form id="ajax-form" method="post" enctype="multipart/form-data">
    <input type="text" name="name"/>
    <input name="file" type="file" />
    <button type="submit">Submit</button>
</form>
Adonis Gaitatzis
  • 3,189
  • 26
  • 24