将 Dropzone.js 集成到具有其他字段的现有 HTML 表单中

IT技术 javascript jquery html file-upload dropzone.js
2021-01-30 20:46:25

我目前有一个 HTML 表单,用户可以在其中填写他们希望发布的广告的详细信息。我现在希望能够添加一个悬浮窗上载该项目用于出售的图片。

我发现Dropzone.js似乎可以满足我的大部分需求。但是,在查看文档时,您似乎需要指定整个表单的类dropzone(而不仅仅是输入元素)。这意味着我的整个表单成为dropzone

是否可以仅在我的表单的一部分中使用 dropzone,即仅将元素指定为类"dropzone",而不是整个表单?

我可以使用单独的表单,但我希望用户能够通过一个按钮提交所有表单。

或者,是否有另一个图书馆可以做到这一点?

非常感谢

6个回答

这是另一种方法:div在您的表单中添加一个类名 dropzone,并以编程方式实现 dropzone。

HTML :

<div id="dZUpload" class="dropzone">
      <div class="dz-default dz-message"></div>
</div>

查询:

$(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");
        }
    });
});

注意:禁用自动发现,否则 Dropzone 将尝试附加两次

@Su4p:很高兴它对您有所帮助,您也可以查看博客文章链接以获取详细说明以及上传时调整图像大小选项
2021-03-26 20:46:25
但这仍然没有使用原始表单提交
2021-03-30 20:46:25
这是我的问题,你解决了,ty @Satindersingh
2021-04-07 20:46:25
有了这个,他就不能使用默认的提交按钮,它不会回答他的问题
2021-04-09 20:46:25
这很有帮助,如果您手动设置 url,您可以将任何元素设置为放置区。我使用成功处理程序将文件名发布到主表单中的隐藏/禁用字段。
2021-04-10 20:46:25

我遇到了完全相同的问题,发现 Varan Sinayee 的答案是唯一真正解决了原始问题的答案。不过,这个答案可以简化,所以这里有一个更简单的版本。

步骤是:

  1. 创建一个普通表单(不要忘记方法和 enctype args,因为这不再由 dropzone 处理)。

  2. 在里面放置一个 div class="dropzone"(这就是 Dropzone 附加到它的方式)和id="yourDropzoneName"(用于更改选项)。

  3. 设置 Dropzone 的选项,设置将发布表单和文件的 url,停用 autoProcessQueue(因此它仅在用户按下“提交”时发生)并允许多次上传(如果需要)。

  4. 将 init 函数设置为在单击提交按钮时使用 Dropzone 而不是默认行为。

  5. 仍然在 init 函数中,使用“sendingmultiple”事件处理程序将表单数据与文件一起发送。

瞧!您现在可以像使用普通表单一样在 $_POST 和 $_FILES 中检索数据(在示例中,这将发生在 upload.php 中)

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

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());
        });
    }
}
+1 这似乎是唯一可行的解​​决方案。而不是一个一个的做formData.append,你也可以做 $(":input[name]", $("form")).each(function () { formData.append(this.name, $(':input[name=' + this.name + ']', $("form")).val()); }); (对不起我不知道如何在这里放置换行符)
2021-03-19 20:46:25
此解决方案很好且有效,但由于阻止了默认提交行为,因此不再重定向到下一页。
2021-03-25 20:46:25
不知道为什么,但我必须使用 $('#myDropzone').dropzone({...}) 而不是 Dropzone.options.myDropzone。除此之外,工作得很好。
2021-03-31 20:46:25
@TIIUNDER - 它准备通过 ajax 调用发送表单信息而无需重新加载页面 - 这就是为什么有 e.preventDefault();
2021-04-01 20:46:25
@TIUNDER 您可以在成功事件中添加重定向
2021-04-05 20:46:25

“dropzone.js”是最常用的上传图片的库。如果您想将“dropzone.js”作为表单的一部分,您应该执行以下步骤:

1)对于客户端:

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>

查询:

    <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)对于服务器端:

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." });
    }
@Sato 在提交按钮的单击事件中,您可以使用 galleryfile.getAcceptedFiles().length 检查 dropzone 上已接受文件的长度,如果没有上传文件,则应提交表单。
2021-03-20 20:46:25
@EdwardChopuryan 这与dropzone提交数据的方法无关。问题可能出在您的平台(例如 ASP.Net MVC)上输入标签的“命名约定”上。
2021-03-21 20:46:25
谢谢你的帖子!解决了我的问题。另一个快速问题,当没有选择图像(上传)时,这不起作用,如何解决这个问题?
2021-03-25 20:46:25
顺便说一句:如果您将控制器操作与模型绑定一起使用并像这样提交表单,则模型将为空。出于某种原因,此方法不会将实际数据绑定到模型。
2021-03-29 20:46:25
当 autoProcessQueue= false 没有事件被触发
2021-04-10 20:46:25

我有一个更自动化的解决方案。

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:

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'));

无需禁用 DropZone Discovery,普通表单提交将能够通过标准表单序列化发送带有任何其他表单字段的文件。

这种机制在处理时将文件内容作为 base64 字符串存储在隐藏输入字段中。您可以通过标准base64_decode()方法将其解码回 PHP 中的二进制字符串

我不知道这种方法是否会因大文件而受到影响,但它适用于约 40MB 的文件。

你能分享一些 html、javascript 的示例代码以及如何在 laravel php 中检索吗?
2021-03-21 20:46:25
您如何解码和处理将与图​​像一起提交的其他字段的数据?
2021-03-22 20:46:25
@sam 无需解码其他字段。他们首先没有被编码,只有文件被编码。
2021-03-23 20:46:25
这不会可靠地工作,因为输入字段值具有浏览器上限的最大大小。在我的情况下,上传的文件上限为 384kb,因为 base64 字符串不完全适合该值。
2021-03-29 20:46:25
如果要添加多个图像,则必须删除 html 文件输入并为每个图像添加 quing js $('#fileUpload').append('<input hidden name="files[]" value='+content+' />') 其中内容是 base64 编码的图像。
2021-04-07 20:46:25

Enyo 的教程很棒。

我发现教程中的示例脚本对于嵌入在 dropzone 中的按钮(即表单元素)运行良好。如果您希望将按钮放在表单元素之外,我可以使用单击事件来完成它:

首先,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>

然后,脚本标签....

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();
        }); 
    }
}
这并没有回答最初的问题。最初的问题是如何将 Dropzone 与现有表单一起使用,而不是关于触发操作的按钮位置。
2021-03-20 20:46:25
您不能在表单中包含表单并提交。
2021-03-29 20:46:25
当我尝试这个时, dropzone-previews 容器似乎被忽略了。Dropzone 只是将预览添加到表单的底部。您需要将“previewsContainer: '.dropzone-previews',”添加到您的配置中。
2021-04-10 20:46:25