This approach lets you hook an indefinite number of divs to their nested file inputs. Just like with ordinary visible file inputs, you will still need multipart/form-data encoding, and your file input(s) must have name attribute. You may also add multiple attribute to the file input to accept selection of multiple files. .fileText will eventually be used to list the selected files.
<form action="index.php" method="post" enctype="multipart/form-data">
<div class="fileMimic">
<input type="file" class="fileTarget" name="zeFile[]" multiple>
<div class="fileText">File "Button"</div>
</div>
</div>
<input type="submit" name="submit" value="submit">
</div>
</form>
<style>
.fileMimic {
/* your div "button" style */
/* this will not be pretty, but I just styled it to center text
* in order to display the selected files in this example
*/
border: 1px solid black;
width: 15em;
height: 8em;
text-align: center;
display: table-cell;
vertical-align: middle;
}
.fileText {
font-size: 0.8em;
}
/* do not display the actual file input */
.fileTarget {
display: none;
}
</style>
/*jslint browser:true */
/*global jQuery, $ */
$(document).ready(function (e) {
var $ft = $('.fileTarget');
/* Do not propagate clicks in order to avoid this infinite click loop:
* click on .fileMimic -> trigger click on file input ->
* propagates to .fileMimic -> trigger click on file input...
*/
$ft.on('click', function (evt) {
evt.stopPropagation();
});
/* This is to go through all selected files to be able to display their
* file names.
*/
$ft.on('change', function (evt) {
var i, fileNames = '';
// Handle the files
for (i = 0; i < evt.target.files.length; i += 1) {
fileNames += evt.target.files[i].name + " ";
}
$(this).parent().children('.fileText').html(fileNames);
});
// Add event handler to all .fileMimic
$('.fileMimic').on('click', function (e) {
/* pass the click to the invisible nested file input */
$(this).children('.fileTarget').trigger('click');
});
$('.fileTarget').on('click', function (e) {
e.stopPropagation();
});
});