【问题标题】:Programmatically Add Existing File to Dropzone以编程方式将现有文件添加到 Dropzone
【发布时间】:2013-07-09 02:17:24
【问题描述】:

我正在尝试以编程方式将现有图像添加到我的 dropzone,使用 dropzone.js FAQ 作为指南:

// Add the existing image if it's there.
// headerDropzone is my dropzone (debug shows it as existing and initialized at this point.
var on_load_header = $( '[name="on_load_header_image"]' ).val();
var on_load_header_path = $( '[name="on_load_header_image_path"]' ).val();

if ( on_load_header ) {

    // Hardcoded size value is just for testing, see my second question below.
    var on_load_header_data = { name: on_load_header, size: 12345 };

    // Call the default addedfile event handler
    headerDropzone.options.addedfile.call( headerDropzone, on_load_header_data );

    // And optionally show the thumbnail of the file:
    headerDropzone.options. thumbnail.call( headerDropzone, on_load_header_data, on_load_header_path);

}

我的第一个问题是这不起作用。 addedfile 事件不会触发(或者至少 headerDropzone 中的 addedfile 处理程序不会触发),缩略图也是如此。

我的第二个问题/问题是:我必须提供文件大小吗?我可以在服务器端获取它,但如果我实际上不需要,我宁愿不这样做。

【问题讨论】:

    标签: dropzone.js


    【解决方案1】:

    如果您需要将多个现有文件添加到 Dropzone 中,请将现有文件声明为数组,然后在循环中以编程方式将其添加到 Dropzone...

            Dropzone.autoDiscover = false;
            var myDropzone = new Dropzone("#myDropzone", {
                url: "/file/post",
                maxFileSize: 50,
                acceptedFiles: ".pdf",
                addRemoveLinks: true,
                //more dropzone options here
            });
    
            //Add existing files into dropzone
            var existingFiles = [
                { name: "Filename 1.pdf", size: 12345678 },
                { name: "Filename 2.pdf", size: 12345678 },
                { name: "Filename 3.pdf", size: 12345678 },
                { name: "Filename 4.pdf", size: 12345678 },
                { name: "Filename 5.pdf", size: 12345678 }
            ];
    
            for (i = 0; i < existingFiles.length; i++) {
                myDropzone.emit("addedfile", existingFiles[i]);
                //myDropzone.emit("thumbnail", existingFiles[i], "/image/url");
                myDropzone.emit("complete", existingFiles[i]);                
            }
    

    【讨论】:

    • 谢谢,这有助于我将现有文件添加到我的放置区。
    • 有什么方法可以删除我以编程方式添加的那些文件??
    • @MayankMajithya,请参阅此行addRemoveLinks: true,。如果您需要进一步澄清,请发布一个新问题。
    【解决方案2】:

    Dropzone FAQ 省略了使用(一个)现有文件正确预加载 dropzone 所需的重要设置。

    我的 dropzone 的初始化方法:

    Dropzone.options.MyDropZoneID = {
        ...
        init: function () {
            var mockFile = { name: fileName, size: fileSize, type: fileMimeType, serverID: 0, accepted: true }; // use actual id server uses to identify the file (e.g. DB unique identifier)
            this.emit("addedfile", mockFile);
            this.createThumbnailFromUrl(mockFile, fileUrl);
            this.emit("success", mockFile);
            this.emit("complete", mockFile);
            this.files.push(mockFile);
            ...
    

    我不知道上面是否是一个完美的实现,但它与 maxFiles 设置一起正常工作。如果您不希望出现错误行为(例如不应该显示的默认消息或上传额外文件),这一点非常重要。您肯定需要将接受的属性设置为 true 并将文件添加到 files 属性。我认为唯一不需要的是发射成功。虽然我还没有玩弄过它,但我无法确定。

    注意:我使用了以下 NuGet 包:

    • 创建者:Matias Meno
    • ID:dropzone
    • 版本:4.2.0

    【讨论】:

    • 这在 5.9 版中非常适合我。在我的情况下,将“accepted”设置为“true”非常重要,因为只有 maxfilesexceeded 才会真正触发。坦克!
    【解决方案3】:

    查看函数headerDropzone.options.addedfileheaderDropzone.options.thumbnail 是否实际定义。它应该按照您的方式工作,但如果没有进一步的信息,就很难判断出了什么问题。

    关于文件大小:不,没有必要实际提供准确的文件大小。只是 Dropzone 会自动显示文件大小。如果您不关心是否显示了一些错误的文件大小,那么您可以提供一些随机数或0。否则,您可能希望在添加文件后使用 CSS 或 JS 隐藏文件大小。 (有问题的元素具有类dz-size

    它的 JavaScript 版本如下所示:

    var fileSizeElement = on_load_header_data.previewElement.querySelector(".dz-size");
    fileSizeElement.parentNode.removeChild(fileSizeElement);
    

    【讨论】:

    • 非常感谢您的回答。我采用了一种更适合我的特定应用程序的不同方法。感谢 dropzone,顺便说一句,很高兴与您合作。
    • 注意,dropzone 中的代码已更改,我们需要将myDropzone.options.addedFile.call(myDropzone, mockFile) 替换为myDropzone.emit("addedfile", mockFile)。请参阅updated faq 中的示例
    【解决方案4】:

    最初我是按照这些思路做的,以编程方式将预先存在的文件上传到 Dropzone:

    headerDropzone.emit("addedfile", imageFile);                                
    headerDropzone.emit("thumbnail", imageFile, imageUrl);
    headerDropzone.files.push(file);
    

    但是,参考这个Dropzone Github Issue,我找到了一种更简单的直接上传方式:

    headerDropzone.uploadFiles([imageFile])
    

    很遗憾,Dropzone Documentation 中没有对这个 uploadFiles 方法的引用,所以我想与所有 Dropzone 用户分享一些知识。

    希望这对某人有所帮助

    【讨论】:

    • 当我尝试将 uploadFiles([file]) 与分块一起使用时,出现错误:“Uncaught TypeError: Cannot read property 'chunked' of undefined”
    • 和我一样@Lokiare。这个@Cumulo 有什么更新吗?
    【解决方案5】:

    现在官方FAQ回复了这个问题

    Dropzone.options.myDropzone = {
      init: function() {
        let myDropzone = this;
    
        // If you only have access to the original image sizes on your server,
        // and want to resize them in the browser:
        let mockFile = { name: "Filename 2", size: 12345 };
        myDropzone.displayExistingFile(mockFile, "https://i.picsum.photos/id/959/600/600.jpg");
    
        // If the thumbnail is already in the right size on your server:
        let mockFile = { name: "Filename", size: 12345 };
        let callback = null; // Optional callback when it's done
        let crossOrigin = null; // Added to the `img` tag for crossOrigin handling
        let resizeThumbnail = false; // Tells Dropzone whether it should resize the image first
        myDropzone.displayExistingFile(mockFile, "https://i.picsum.photos        /id/959/120/120.jpg", callback, crossOrigin, resizeThumbnail);
        myDropzone.files.push(mockFile); // line missing in official docs
    
        // If you use the maxFiles option, make sure you adjust it to the
        // correct amount:
        let fileCountOnServer = 2; // The number of files already uploaded
        myDropzone.options.maxFiles = myDropzone.options.maxFiles - fileCountOnServer;
      }
    };
    

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题,找到了 Dropzone 的handleFiles(files) 方法。

      所以如果你有inputTypeFileRef,你可以

      // inputTypeFiles.files is an object of type FileList
      var fileArray = Object.values(inputTypeFiles.files || {});
      myDropZone.handleFiles(fileArray);
      

      这也将触发所有Dropzone 的事件并传递文件数据,这通常是通过在其上拖动文件来实现的 - 进度、文件大小等。

      希望对您有所帮助。

      【讨论】:

      • 这个适用于新的分块上传功能。虽然你可以只使用 myDropZone.handleFiles([file]);
      【解决方案7】:

      最新的 Dropzone 缺少示例,文档不清晰或不完整。您可以使用以下方法将现有图像添加到 Dropzone。

      for (var i = 0; i < imagesList.length; i++) {
        let name = imagesList[i];
        name = name.substring(name.lastIndexOf('/') + 1);
      
        fetch(imagesList[i])
          .then(res => res.blob())
          .then(blob => {
            let file = new File([blob], name, blob);
            myDropzone1.addFile(file);
          });
      }
      

      imagesList 是您要添加到 Dropzone 的图像列表。

      但是,我仍然面临一个问题:图像没有按照 imagesList 中的顺序/顺序添加或显示。它们看起来相当随机。有没有办法让图像以图像列表中的顺序/顺序显示?

      【讨论】:

      • 这个答案很有意义。请注意,Dropzone 接受直接加载 blob 而无需创建文件对象:blob.name = name; myDropzone1.addFile(blob);。不确定列表的顺序。
      • .addFile() 在此评论中似乎仍然有效。与此处的所有其他答案相比,迄今为止最简单的方法。
      【解决方案8】:

      其中许多答案都已经过时了,在撰写本文时,这在最新的 Dropzone JS 中对我有用(请注意包含的 cmets):

      init: function() {
          var dzObj = this;
      
          // In my template I looped through existing files from the database and created:
          // <div class="existing-image" data-url="/path/to/file.jpg"></div>
          $('.existing-image').each(function() {
              // I didn't have this data - works fine without
              var mockFile = { name: '', size: '', dataURL: $(this).data('url') };
      
              // Call the default addedfile event handler
              dzObj.emit("addedfile", mockFile);
      
              // The Dropzone JS FAQ incorrectly references "file" here instead of  mockFile".
              // The other parameters are outdated, dataURL goes in the object above,
              // and you need to pass through other parameters.
              // It DOES NOT WORK without the thumbnail event being triggered.
              dzObj.createThumbnailFromUrl(mockFile, dzObj.options.thumbnailWidth, dzObj.options.thumbnailHeight, dzObj.options.thumbnailMethod, true, function (dataUrl) {
                  dzObj.emit("thumbnail", mockFile, dataUrl);
              });
      
              // Make sure that there is no progress bar, etc...
              dzObj.emit("complete", mockFile);
      
              dzObj.options.maxFiles = dzObj.options.maxFiles - 1;
          });
      }
      

      【讨论】:

      • 使用此代码,我设法将现有图像添加到 dropzone。但是,当我想重新提交表单(使用 dropzone 图像)时,无法识别图像(dzObj.getUploadingFiles().length === 0 && dzObj.getQueuedFiles().length === 0),所以它没有不行。这个问题有什么解决办法吗?谢谢。
      • 这是唯一适用于最新版本的示例。互联网上到处都是不正确的答案。接受的答案应该更新为此。还有 dropzone.js 添加图像的噩梦是什么?期待 addImage() 函数...
      【解决方案9】:

      @tjbp 的回复对我来说效果很好,有以下变化:

      1. 我无法删除以编程方式添加的文件,然后再添加另一个。我通过删除将“maxFiles”设置为 0 的这一行来解决此问题。

        // If you use the maxFiles option, make sure you adjust it to the
        // correct amount:
        var existingFileCount = 1; // The number of files already uploaded
        myDropzone.options.maxFiles = myDropzone.options.maxFiles - existingFileCount;
        
      2. 为了确保“删除”按钮可见,我必须添加以下行:

        if (mockFile.previewElement) {
            mockFile.previewElement.classList.add("dz-success");
        }
        

      【讨论】:

        【解决方案10】:

        对于 5.7.0 版,这里没有任何东西对我有用,但是这样做了:

        var myDropzone = new Dropzone(document.body, {
            url: "<?= site_url('site/upload') ?>",
            acceptedFiles: "<?= $uploadFieldAcceptValue ?>",
            maxFilesize: 15,
            maxFiles: 5,
            autoQueue: false,
            thumbnailWidth: 80,
            thumbnailHeight: 80,
            init: function(){
                var that = this;
        
                that.on("addedfile", function(file) {
                    // remove the start button
                    var startButton = file.previewElement.querySelector(".start");
                    if(startButton){
                        startButton.parentNode.removeChild(startButton);
                    }
                });
        
                <?php if(is_array($userUploads) && count($userUploads) > 0) { ?>
                    <?php foreach($userUploads as $userUpload) { ?>
                        <?php $file = $userUpload['file']; ?>
        
                        var mockFile = {
                            name: '<?= basename($file) ?>', 
                            size: <?= filesize($file) ?>
                        };
        
                        var fileUrl = '<?= base_url() . str_replace('\\', '/', preg_replace('~^'. preg_quote(FCPATH) .'~', '', $file)) ?>';
                        var callback = null;
                        var crossOrigin = null;
                        var resizeThumbnail = true;
                        that.displayExistingFile(mockFile, fileUrl, callback, crossOrigin, resizeThumbnail);
        
                        that.emit("success", mockFile);
                        that.emit('complete', mockFile);
        
                    <?php } ?>
        
                    that.options.maxFiles = that.options.maxFiles - <?= count($userUploads) ?>;
        
                <?php } ?>
            }
        });
        
        【解决方案11】:

        在 Dropzone 5.7.0 上有一个“displayExistingFile”功能。我在初始化部分调用它,工作正常。

             /**
             * Called when dropzone initialized
             * You can add event listeners here
             */
            init: function init() {
              var mockFile = { name: "Filename 1.pdf", size: 12345678 }; 
              this.displayExistingFile(mockFile,  "../../assets/site/wp-content/uploads/cropped-ic_credifisco-1-192x192.png");     
            },
        

        【讨论】:

          猜你喜欢
          • 2014-10-30
          • 1970-01-01
          • 2016-02-16
          • 1970-01-01
          • 2016-10-31
          • 2021-11-19
          • 2014-04-03
          • 1970-01-01
          • 2014-06-11
          相关资源
          最近更新 更多