I'm using Jquery-File-Upload for my upload page, and I'm having a problem to add extra upload fields.
I'm following that page: https://github.com/blueimp/jQuery-File-Upload/wiki/How-to-submit-additional-form-data
It works well for 1 file submission. However, with multiple files submission we are starting to see issues, because files are uploaded 1 file / POST (singleFileUploads: true).
The code I'm using as reference is the following:
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
<!-- ... -->
<td class="title"><label>Title: <input name="title[]" required></label></td>
<!-- ... -->
</tr>
{% } %}
</script>
If you submit that with 2 files, then you get 2 POSTS:
1/
$_REQUEST:
(
title:
(
[0] -> Title1
[1] -> Title2
)
)
$_FILES:
(
[0] -> ( 'name' => 'file name 1', ... )
)
2/
$_REQUEST:
(
title:
(
[0] -> Title1
[1] -> Title2
)
)
$_FILES:
(
[0] -> ( 'name' => 'file name 2', ... )
)
Then, on php side, the function handle_form_data relies on file index
<?php
// ...
protected function handle_form_data($file, $index) {
// Handle form data, e.g. $_REQUEST['description'][$index]
}
// ...
The problem is that index is always 0, because we're uploading 1 file / post. Now you see that since the $_REQUEST uploads all extra fields from all files (no matter what is it the current file), the index from $_FILES gets de-synchronized from the extra fields array.
Do you know any workaround, except turning singleFileUploads to OFF?
Ok, I will answer myself.
First, we will attribute an id to the files as soon as they are added to the UI. We maintain an incremental index for that:
//global
var current_file_index = 0;
Next, we need to play with fileuploadadd callback to add that index to the files:
$('#fileupload').bind('fileuploadadd', function (e, data) {
for (var i = 0; i < data.files.length; i++) {
data.files[i].index = current_file_index++;
}
});
That index is now accessible when adding the files on UI side. We don't want the custom input to be added to the form, so change the name by an id (so that it will not be submitted). And add the brand new index as part of that ID:
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
<!-- ... -->
<td class="title"><label>Title: <input id="title_{%=file.index%}" required></label></td>
<!-- ... -->
</tr>
{% } %}
</script>
Then, when we submit the file(s), we want to add the result of that input to the formData. We don't care about sending to much data, so we basically send the whole files array as JSON string:
$('#fileupload').bind('fileuploadsubmit', function (e, data) {
for (var i = 0; i < data.files.length; i++) {
var title = $("title_ + data.files[i].index.toString()").val();
data.files[i].title = title;
}
data.formData = {
files_data: JSON.stringify(data.files)
}
});
Don't forget the get the data back on server side in $_REQUEST["files_data"], and explode the json that now contains only 1 file's data).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With