11

I want to implement a multiple file uploader in a form wherein I want the files so that the user may sort the priority of the files (I am using draggable and sortable Jquery tool).

Therefore I have added a multiple file input as:

<input type = "file" multiple>

Now when I select some files, it shows say 3 files selected. But when I select 3 files, I wish to split the file uploader in 3 parts so that the user may set the priority ordering accordingly.

For that I have used the following kind of code:

$('.files').change(function(e){
var filesSelected = e.target.files;
if(filesSelected.length > 1){ //if user selects multiple files, then automatically split the files into multiple divs so that he/she may do the ordering of files
    //Here I want to create a list of  all the files and implement the draggable and sortable thing.
}
});

The situation is, that I am not able to split the array of objects of FileList and assign each object to another input.

Hope I am clear in my doubt and the question is understandable, as it is the first time I am posting in any such forum.

1
  • Please assume that the input type=file element is placed with the class files Commented Sep 6, 2016 at 9:01

4 Answers 4

5

You cannot set value for <input type="file"> programmatically. It would be a major security flow. Imagine some website automatically uploading arbitrary files from your computer.

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

3 Comments

I don't want to set the value programmatically, rather I want to use the multi-file uploader to select multiple files, which by the way created a FileList which is an array of FIle objects. Using this array I want to iterate through it and pick each element and assign in a new input field, the type of which shall also be file.
From my point of view this is exactly setting an arbitrary value to a file-type input.
Agreed. I think I figured the answer to the issue. Thanks for your response
3

You can try to iterate through the selected files and then create a div dynamically with jquery that contains the data from the file like this

$('.files').change(function(e){
var filesSelected = e.target.files;
if(filesSelected.length > 1){ 
   for(var i=0;i<filesSelected.length;i++) { // We iterate through the selected Files
      $("#idFromParentElement").append('<div> id=File'+i+'</div'); // Then we create and append the new div to the parent element of our choice
      var fileId = 'File'+i;
      $("#fileId").data("file",filesSelected[i]); //After that we include a data into the div with the selected file.
   }
}
});

3 Comments

Thanks Javier, but the data part does not seem to work for me. Rather than creating multiple divs I wish to create multiple input types in the loop and assign a file from the ones selected to each new input field.
As it was said by Zoli on the other answer, setting up an input field programatically is generaly a security risk. Maybe you could try storing the FileList in your javascript and create divs that store the position of the file on the array. That way you could get the same result without using data and maintaning good security.
Yes I guess it would be better to fetch the filenames and create another set of divs with the filenames and the sortable/draggable feature implemented in that set and then handling them accordingly at the time of saving the form.
1

From the posts I received and the brief discussions, it is evident that setting file values programmatically will pose security threat and so is not a good option. As far as solving my issue is concerned, best would be to find a way to create multiple divs/fields containing the filenames of the files that are being uploaded and then applying the drag/drop/sort feature in that set of divs. This way the user can easily prioritize the files and while saving the form the array/field containing the priority shall be considered before saving the files data in the database.

Thanks to the responders for their quick response.

Comments

0

Great that you found a workaround to your problem. Building on it, I have another problem. I want the user to be able to select multiple files, multiple times. But every time the user selects new files, old files are lost.

I am also building a multiple file uploader, for showcasing priority(sequence) and file preview (I am working with images). Since "input.files" is a read-only property, assigning new files to any input is not an option.

A workaround that has worked for me is

  1. Using a label for my input field, and hiding the input.
  2. After the user selects files, clone that input and remove the original input's ID (so that the label no longer refers to it). And adding the new input to the form.

This way the "name" of the input remains same, and when the form is submitted. All the files are sent.

This is HTML sample:

<label for="add-item-image-input" class="button">Upload Image +</label>
<input hidden multiple autocomplete="off" type="file" accept="image/jpeg, image/png" name="images" data-preview-table="add-item-image-preview-table" id="add-item-image-input" onchange="previewMyImages(this)" />

This is JavaScript snippet:

let previewTable = document.getElementById(inputElement.getAttribute("data-preview-table"));
let inputName = inputElement.getAttribute("name");
let newInput = inputElement.cloneNode();
inputElement.removeAttribute("id");

let form = inputElement.form;
let files = [];
Array.from(form.querySelectorAll(`input[name='${inputName}']`))
    .map((input) => (files = [...files, ...input.files]));
console.log(files);
inputElement.insertAdjacentElement("afterend", newInput);

However, this method introduces the risk of uploading the same file multiple times, but this can be prevented using extra logic.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.