jQuery 将 Dropzone.js 集成到具有其他字段的现有 HTML 表单中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17872417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Integrating Dropzone.js into existing HTML form with other fields
提问by Ben Thompson
I currently have a HTML form which users fill in details of an advert they wish to post. I now want to be able to add a dropzonefor uploading images of the item for sale.
我目前有一个 HTML 表单,用户可以在其中填写他们希望发布的广告的详细信息。我现在希望能够添加一个悬浮窗上载该项目用于出售的图片。
I have found Dropzone.jswhich seems to do most of what I need. However, when looking into the documentation, it appears that you need to specify the class of the whole form as dropzone
(as opposed to just the inputelement). This then means that my entire form becomes the dropzone.
我发现Dropzone.js似乎可以满足我的大部分需求。但是,在查看文档时,您似乎需要指定整个表单的类dropzone
(而不仅仅是输入元素)。这意味着我的整个表单成为dropzone。
Is it possible to use the dropzone in just part of my form, i.e. by only specifying the element as class "dropzone", rather than the whole form?
是否可以仅在我的表单的一部分中使用 dropzone,即仅将元素指定为类"dropzone",而不是整个表单?
I could use separate forms, but I want the user to be able to submit it all with one button.
我可以使用单独的表单,但我希望用户能够一键提交所有表单。
Alternatively, is there another library that can do this?
或者,是否有另一个图书馆可以做到这一点?
Many thanks
非常感谢
回答by Satinder singh
Here's another way to do it: add a div
in your form with a classname dropzone, and implement dropzone programmatically.
这是另一种方法:div
在您的表单中添加一个类名 dropzone,并以编程方式实现 dropzone。
HTML :
HTML :
<div id="dZUpload" class="dropzone">
<div class="dz-default dz-message"></div>
</div>
JQuery:
查询:
$(document).ready(function () {
Dropzone.autoDiscover = false;
$("#dZUpload").dropzone({
url: "hn_SimpeFileUploader.ashx",
addRemoveLinks: true,
success: function (file, response) {
var imgName = response;
file.previewElement.classList.add("dz-success");
console.log("Successfully uploaded :" + imgName);
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
}
});
});
Note : Disabling autoDiscover, otherwise Dropzone will try to attach twice
注意:禁用自动发现,否则 Dropzone 将尝试附加两次
Blog Article: Dropzone js + Asp.net: Easy way to upload Bulk images
回答by mrtnmgs
I had the exact same problem and found that Varan Sinayee's answer was the only one that actually solved the original question. That answer can be simplified though, so here's a simpler version.
我遇到了完全相同的问题,发现 Varan Sinayee 的答案是唯一真正解决了原始问题的答案。不过,这个答案可以简化,所以这里有一个更简单的版本。
The steps are:
步骤是:
Create a normal form (don't forget the method and enctype args since this is not handled by dropzone anymore).
Put a div inside with the
class="dropzone"
(that's how Dropzone attaches to it) andid="yourDropzoneName"
(used to change the options).Set Dropzone's options, to set the url where the form and files will be posted, deactivate autoProcessQueue (so it only happens when user presses 'submit') and allow multiple uploads (if you need it).
Set the init function to use Dropzone instead of the default behavior when the submit button is clicked.
Still in the init function, use the "sendingmultiple" event handler to send the form data along wih the files.
创建一个普通表单(不要忘记方法和 enctype args,因为这不再由 dropzone 处理)。
将一个 div 放在里面
class="dropzone"
(这就是 Dropzone 附加到它的方式)和id="yourDropzoneName"
(用于更改选项)。设置 Dropzone 的选项,设置将发布表单和文件的 url,停用 autoProcessQueue(因此它仅在用户按下“提交”时发生)并允许多次上传(如果需要)。
将 init 函数设置为在单击提交按钮时使用 Dropzone 而不是默认行为。
仍然在 init 函数中,使用“sendingmultiple”事件处理程序将表单数据与文件一起发送。
Voilà ! You can now retrieve the data like you would with a normal form, in $_POST and $_FILES (in the example this would happen in upload.php)
瞧!您现在可以像使用普通表单一样在 $_POST 和 $_FILES 中检索数据(在示例中,这将发生在 upload.php 中)
HTML
HTML
<form action="upload.php" enctype="multipart/form-data" method="POST">
<input type="text" id ="firstname" name ="firstname" />
<input type="text" id ="lastname" name ="lastname" />
<div class="dropzone" id="myDropzone"></div>
<button type="submit" id="submit-all"> upload </button>
</form>
JS
JS
Dropzone.options.myDropzone= {
url: 'upload.php',
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 5,
maxFilesize: 1,
acceptedFiles: 'image/*',
addRemoveLinks: true,
init: function() {
dzClosure = this; // Makes sure that 'this' is understood inside the functions below.
// for Dropzone to process the queue (instead of default form behavior):
document.getElementById("submit-all").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
dzClosure.processQueue();
});
//send all the form data along with the files:
this.on("sendingmultiple", function(data, xhr, formData) {
formData.append("firstname", jQuery("#firstname").val());
formData.append("lastname", jQuery("#lastname").val());
});
}
}
回答by Varan Sinayee
The "dropzone.js" is the most common library for uploading images. If you want to have the "dropzone.js" as just part of your form, you should do the following steps:
“dropzone.js”是最常用的上传图片的库。如果您想将“dropzone.js”作为表单的一部分,您应该执行以下步骤:
1) for the client side:
1)对于客户端:
HTML :
HTML :
<form action="/" enctype="multipart/form-data" method="POST">
<input type="text" id ="Username" name ="Username" />
<div class="dropzone" id="my-dropzone" name="mainFileUploader">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</div>
</form>
<div>
<button type="submit" id="submit-all"> upload </button>
</div>
JQuery:
查询:
<script>
Dropzone.options.myDropzone = {
url: "/Account/Create",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
acceptedFiles: "image/*",
init: function () {
var submitButton = document.querySelector("#submit-all");
var wrapperThis = this;
submitButton.addEventListener("click", function () {
wrapperThis.processQueue();
});
this.on("addedfile", function (file) {
// Create the remove button
var removeButton = Dropzone.createElement("<button class='btn btn-lg dark'>Remove File</button>");
// Listen to the click event
removeButton.addEventListener("click", function (e) {
// Make sure the button click doesn't submit the form:
e.preventDefault();
e.stopPropagation();
// Remove the file preview.
wrapperThis.removeFile(file);
// If you want to the delete the file on the server as well,
// you can do the AJAX request here.
});
// Add the button to the file preview element.
file.previewElement.appendChild(removeButton);
});
this.on('sendingmultiple', function (data, xhr, formData) {
formData.append("Username", $("#Username").val());
});
}
};
</script>
2) for the server side:
2)对于服务器端:
ASP.Net MVC
ASP.NET MVC
[HttpPost]
public ActionResult Create()
{
var postedUsername = Request.Form["Username"].ToString();
foreach (var imageFile in Request.Files)
{
}
return Json(new { status = true, Message = "Account created." });
}
回答by kablamus
Enyo's tutorialis excellent.
Enyo 的教程很棒。
I found that the sample script in the tutorial worked well for a button embedded in the dropzone (i.e., the form element). If you wish to have the button outside the form element, I was able to accomplish it using a click event:
我发现教程中的示例脚本对于嵌入在 dropzone 中的按钮(即表单元素)运行良好。如果您希望将按钮放在表单元素之外,我可以使用单击事件来完成它:
First, the HTML:
首先,HTML:
<form id="my-awesome-dropzone" action="/upload" class="dropzone">
<div class="dropzone-previews"></div>
<div class="fallback"> <!-- this is the fallback if JS isn't working -->
<input name="file" type="file" multiple />
</div>
</form>
<button type="submit" id="submit-all" class="btn btn-primary btn-xs">Upload the file</button>
Then, the script tag....
然后,脚本标签....
Dropzone.options.myAwesomeDropzone = { // The camelized version of the ID of the form element
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 25,
maxFiles: 25,
// The setting up of the dropzone
init: function() {
var myDropzone = this;
// Here's the change from enyo's tutorial...
$("#submit-all").click(function (e) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
}
}
回答by Codedragon
Further to what sqram was saying, Dropzone has an additional undocumented option, "hiddenInputContainer". All you have to do is set this option to the selector of the form you want the hidden file field to be appended to. And voila! The ".dz-hidden-input" file field that Dropzone normally adds to the body magically moves into your form. No altering the Dropzone source code.
除了 sqram 所说的之外,Dropzone 还有一个未公开的选项,“hiddenInputContainer”。您所要做的就是将此选项设置为要附加隐藏文件字段的表单的选择器。瞧!Dropzone 通常添加到正文的“.dz-hidden-input”文件字段会神奇地移动到您的表单中。无需更改 Dropzone 源代码。
Now while this works to move the Dropzone file field into your form, the field has no name. So you will need to add:
现在虽然这可以将 Dropzone 文件字段移动到您的表单中,但该字段没有名称。所以你需要添加:
_this.hiddenFileInput.setAttribute("name", "field_name[]");
to dropzone.js after this line:
在此行之后到 dropzone.js:
_this.hiddenFileInput = document.createElement("input");
around line 547.
在第 547 行附近。
回答by Umair Ahmed
I have a more automated solution for this.
我有一个更自动化的解决方案。
HTML:
HTML:
<form role="form" enctype="multipart/form-data" action="{{ $url }}" method="{{ $method }}">
{{ csrf_field() }}
<!-- You can add extra form fields here -->
<input hidden id="file" name="file"/>
<!-- You can add extra form fields here -->
<div class="dropzone dropzone-file-area" id="fileUpload">
<div class="dz-default dz-message">
<h3 class="sbold">Drop files here to upload</h3>
<span>You can also click to open file browser</span>
</div>
</div>
<!-- You can add extra form fields here -->
<button type="submit">Submit</button>
</form>
JavaScript:
JavaScript:
Dropzone.options.fileUpload = {
url: 'blackHole.php',
addRemoveLinks: true,
accept: function(file) {
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = function() {
let content = fileReader.result;
$('#file').val(content);
file.previewElement.classList.add("dz-success");
}
file.previewElement.classList.add("dz-complete");
}
}
Laravel:
拉拉维尔:
// Get file content
$file = base64_decode(request('file'));
No need to disable DropZone Discovery and the normal form submit will be able to send the file with any other form fields through standard form serialization.
无需禁用 DropZone Discovery,普通表单提交将能够通过标准表单序列化发送带有任何其他表单字段的文件。
This mechanism stores the file contents as base64 string in the hidden input field when it gets processed. You can decode it back to binary string in PHP through the standard base64_decode()
method.
这种机制在处理时将文件内容作为 base64 字符串存储在隐藏输入字段中。您可以通过标准base64_decode()
方法将其解码回 PHP 中的二进制字符串。
I don't know whether this method will get compromised with large files but it works with ~40MB files.
我不知道这种方法是否会因大文件而受到影响,但它适用于约 40MB 的文件。
回答by Leonid Vasilev
In order to submit all files alongside with other form data in a single request you can copy Dropzone.js temporary hidden input
nodes into your form. You can do this within addedfiles
event handler:
为了在单个请求中将所有文件与其他表单数据一起提交,您可以将 Dropzone.js 临时隐藏input
节点复制到您的表单中。您可以在addedfiles
事件处理程序中执行此操作:
var myDropzone = new Dropzone("myDivSelector", { url: "#", autoProcessQueue: false });
myDropzone.on("addedfiles", () => {
// Input node with selected files. It will be removed from document shortly in order to
// give user ability to choose another set of files.
var usedInput = myDropzone.hiddenFileInput;
// Append it to form after stack become empty, because if you append it earlier
// it will be removed from its parent node by Dropzone.js.
setTimeout(() => {
// myForm - is form node that you want to submit.
myForm.appendChild(usedInput);
// Set some unique name in order to submit data.
usedInput.name = "foo";
}, 0);
});
Obviosly this is a workaround dependent on implementation details. Related source code.
显然,这是一种依赖于实现细节的解决方法。相关源代码。
回答by shawnrushefsky
You can modify the formData by catching the 'sending' event from your dropzone.
您可以通过从放置区捕获“发送”事件来修改 formData。
dropZone.on('sending', function(data, xhr, formData){
formData.append('fieldname', 'value');
});
回答by taggart
This is just another example of how you can use Dropzone.js in an existing form.
这只是如何在现有表单中使用 Dropzone.js 的另一个示例。
dropzone.js :
dropzone.js :
init: function() {
this.on("success", function(file, responseText) {
//alert("HELLO ?" + responseText);
mylittlefix(responseText);
});
return noop;
},
Then, later in the file I put
然后,稍后在我放入的文件中
function mylittlefix(responseText) {
$('#botofform').append('<input type="hidden" name="files[]" value="'+ responseText +'">');
}
This assumes you have a div with id #botofform
that way when uploading you can use the uploaded files' names.
这假设您#botofform
在上传时有一个带有 id 的 div,您可以使用上传的文件的名称。
Note: my upload script returned theuploadedfilename.jpeg dubblenote you also would need to make a cleanup script that checks the upload directory for files not in use and deletes them ..if in a front end non authenticated form :)
注意:我的上传脚本返回了uploadedfilename.jpeg dubblenote 您还需要制作一个清理脚本来检查上传目录中是否存在未使用的文件并删除它们..如果在前端未验证的形式中:)
回答by smartworld-dm
Here is my sample, is based on Django + Dropzone. View has select(required) and submit.
这是我的示例,基于 Django + Dropzone。视图已选择(必填)并提交。
<form action="/share/upload/" class="dropzone" id="uploadDropzone">
{% csrf_token %}
<select id="warehouse" required>
<option value="">Select a warehouse</option>
{% for warehouse in warehouses %}
<option value={{forloop.counter0}}>{{warehouse.warehousename}}</option>
{% endfor %}
</select>
<button id="submit-upload btn" type="submit">upload</button>
</form>
<script src="{% static '/js/libs/dropzone/dropzone.js' %}"></script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
var filename = "";
Dropzone.options.uploadDropzone = {
paramName: "file", // The name that will be used to transfer the file,
maxFilesize: 250, // MB
autoProcessQueue: false,
accept: function(file, done) {
console.log(file.name);
filename = file.name;
done(); // !Very important
},
init: function() {
var myDropzone = this,
submitButton = document.querySelector("[type=submit]");
submitButton.addEventListener('click', function(e) {
var isValid = document.querySelector('#warehouse').reportValidity();
e.preventDefault();
e.stopPropagation();
if (isValid)
myDropzone.processQueue();
});
this.on('sendingmultiple', function(data, xhr, formData) {
formData.append("warehouse", jQuery("#warehouse option:selected").val());
});
}
};
</script>