我有一个带有上传字段的表单,允许用户选择多个文件。但是,我需要能够允许用户从文件夹1中选择文件1,然后从文件夹2中选择文件2,依此类推。
目前,当用户从文件夹1中选择文件1然后点击“打开”时,选择窗口关闭(将用户留在我的表单上)。然后,如果用户从文件夹2中选择文件2并点击“打开”按钮,则删除文件1,仅保留文件2.
基本上,用户无法选择多个文件,除非它们都位于同一位置。有没有办法让文件1在选择文件2后保持选中状态?
答案 0 :(得分:5)
这个怎么样?
该解决方案使用HTML,jQuery / Javascript和PHP(用于服务器端处理此数据)。这个想法是:1。)HTML表单:包含一个"浏览"允许用户选择多个文件的按钮(在一个目录中)。 2.)jQuery:在表单中创建一个新按钮的选项,允许用户选择多个文件(在不同的目录中 - 甚至是同一个目录!),能够创建新按钮"无限& #34 ;. 3.)PHP:作为奖励,我考虑了很好地打包服务器端处理数据。
以下是HTML表单的外观(我使用了可点击对象的find-icon,但您可以轻松地将其替换为您选择的图形)。
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" enctype='multipart/form-data'>
Select files: <br/>
<input type='file' name='files0[]' id="files0" multiple><br/><br/><br/>
<span style="font-size: 10pt;">Click "+" for more files
<i id="more_files" class="general foundicon-plus" style="color: blue;cursor: pointer;"></i></span>
<br/><br/><br/>
<input type="submit" name="submit" value="Submit">
</form>
这是jQuery / Javascript创建一个新的&#34;浏览&#34;触发事件后按钮(这甚至将它放在最后一次&#34;浏览&#34;按钮!):
<script type="text/javascript">
//jQuery
$(document).ready(function() {
$(document).on('click','#more_files', function() {
var numOfInputs = 1;
while($('#files'+numOfInputs).length) { numOfInputs++; }//once this loop breaks, numOfInputs is greater than the # of browse buttons
$("<input type='file' multiple/>")
.attr("id", "files"+numOfInputs)
.attr("name", "files"+numOfInputs+"[]")
.insertAfter("#files"+(numOfInputs-1));
$("<br/>").insertBefore("#files"+numOfInputs);
});
});
</script>
<script>
//vanilla javascript version
var location = document.getElementById("fileBrowsers");
var br = document.createElement("BR");
location.appendChild(br);
var input = document.createElement("input");
input.type = "file";
input.name = "files"+numOfInputs+"[]";
input.id = "files"+numOfInputs;
input.multiple = true;
location.appendChild(input);
</script>
最后,也许最重要的是,如何以熟悉的格式包装服务器上的数据:
<?php
if(isset($_POST['submit']) && !empty($_FILES)) {
$files = array();
$files = $_FILES['files0'];
//var_dump($files);//this array will match the structure of $_FILES['browser']
//Iterate through each browser button
$browserIterator = 1;
while(isset($_FILES['files'.$browserIterator])) {
//Files have same attribute structure, so grab each attribute and append data for each attribute from each file
foreach($_FILES['files'.$browserIterator] as $attr => $values) {//get each attribute
foreach($_FILES['files'.$browserIterator][$attr] as $fileValue) {//get each value from attribute
$files[$attr][] = $fileValue;//append value
}
}
$browserIterator++;
}
//Use $files like you would use $_FILES['browser'] -- It is as though all files came from one browser button!
$fileIterator = 0;
while($fileIterator < count($files['name'])) {
echo $files['name'][$fileIterator]."<br/>";
$fileIterator++;
}
}
?>
更新注意: jQuery脚本和vanilla Javascript实现了同样的目标。我遇到了一个需要vanilla版本的问题。 您只需要其中一个。
答案 1 :(得分:3)
如果人们必须选择的文件夹数量非常少,您可以提供多个上传字段。
答案 2 :(得分:1)
另一种解决方案是使用旧式(非多个)文件输入。在这种情况下,您不能选择多个文件上载,但可以删除任何文件并添加另一个。最初页面上只有一个文件输入,但是当您选择文件时,它会隐藏并用删除按钮替换为文件名,然后会出现新文件输入。
var fileInput = document.getElementById('fileInput_0');
var filesList = document.getElementById('fileList');
var idBase = "fileInput_";
var idCount = 0;
var inputFileOnChange = function() {
var existingLabel = this.parentNode.getElementsByTagName("LABEL")[0];
var isLastInput = existingLabel.childNodes.length<=1;
if(!this.files[0]) {
if(!isLastInput) {
this.parentNode.parentNode.removeChild(this.parentNode);
}
return;
}
var filename = this.files[0].name;
var deleteButton = document.createElement('span');
deleteButton.innerHTML = '×';
deleteButton.onclick = function(e) {
this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
}
var filenameCont = document.createElement('span');
filenameCont.innerHTML = filename;
existingLabel.innerHTML = "";
existingLabel.appendChild(filenameCont);
existingLabel.appendChild(deleteButton);
if(isLastInput) {
var newFileInput=document.createElement('input');
newFileInput.type="file";
newFileInput.name="file[]";
newFileInput.id=idBase + (++idCount);
newFileInput.onchange=inputFileOnChange;
var newLabel=document.createElement('label');
newLabel.htmlFor = newFileInput.id;
newLabel.innerHTML = '+';
var newDiv=document.createElement('div');
newDiv.appendChild(newFileInput);
newDiv.appendChild(newLabel);
filesList.appendChild(newDiv);
}
}
fileInput.onchange=inputFileOnChange;
#fileList > div > label > span:last-child {
color: red;
display: inline-block;
margin-left: 7px;
cursor: pointer;
}
#fileList input[type=file] {
display: none;
}
#fileList > div:last-child > label {
display: inline-block;
width: 23px;
height: 23px;
font: 16px/22px Tahoma;
color: orange;
text-align: center;
border: 2px solid orange;
border-radius: 50%;
}
<form enctype="multipart/form-data" method="post">
<div id="fileList">
<div>
<input id="fileInput_0" type="file" name="file[]" />
<label for="fileInput_0">+</label>
</div>
</div>
</form>
答案 3 :(得分:1)
document.querySelector("input").addEventListener("change", list_files);
function list_files() {
var files = this.files;
for (var i = 0; i < files.length; i++) {
console.log(files[i].name);
}
}
<input type="file" multiple>