具有 div table 布局的 DropzoneJS

DropzoneJS with div table layout

一般问题:

当默认情况下它被包裹在破坏我的 table 布局的元素中时,如何让我的 Dropzone 中添加的行填充 table 的整个宽度。

解释:

我正在尝试让 DropzoneJS 以 table 格式显示上传的文件。我的 Dropzone 在 table 上是正确的,但我无法正确显示 previewTemplate。 首先,问题出现是因为 Dropzone 无法将文件添加到 <td></td> 元素,所以我使用 CSS[=24 将我的 table 转换为这样的 table 布局格式=]

<div class="div-tr">
    <div class="div-td"></div>
    <div class="div-td"></div>
</div>

因此,我的目标是向 DropzoneJS 添加一个预览模板,它看起来像这样

<div class="div-tr">
    <div class="div-td">
        <i class="fa fa-file-o"></i>
    </div>
    <div class="div-td">
        <div class="dz-filename">
            <span data-dz-name></span>
        </div>
    </div>
    <div class="div-td">
        <div class="dz-size" data-dz-size></div>
    </div>
    <div class="div-td">
        <div class="dz-progress">
            <span class="dz-upload" data-dz-uploadprogress></span>
        </div>
    </div>
    <div class="div-td">
        <div class="dz-success-mark">
            <span>✔</span>
        </div>  
        <div class="dz-error-mark">
            <span>✘</span>
        </div>
    </div>
</div>

问题是 Dropzone 默认添加一组 classes dz-processing dz-image-preview dz-error dz-success 到 previewTemplate 中的 <div>。根据文档,它们将被添加到带有 class="dz-preview"<div>,但无论 class 是否存在,其他 classes 将作为第一个内部添加容器的元素,其中注入了 previewTemplate。 这意味着应该是 table 行的 previewTemplate 失去了它的属性,现在只显示第一个 <div class="div-td">

的宽度
+-------------+--------------+-----------+----------+
|             |              |           |          |   Existing row
+-------------+--------------+-----------+----------+
|             |              |           |          |   Existing row
+-------------+--------------+-----------+----------+
|             |              |           |          |   Existing row
+-------------+--------------+-----------+----------+
|             |              |           |          |   Existing row
+-------------+--------------+-----------+----------+
|   |   |  |  |                                         Row added by upload
+---+---+--+--+

发生这种情况是因为添加了一个额外的 <div> 来包裹行的内部。

我的 CSS table 看起来像这样

/* DIV table style */

.div-table{
     display: table;
     width: 100%;
     background-color: #fff;
}
.div-tr{
    display: table-row;
}
.div-th, .div-td {
    display: table-cell;
    padding: 8px 15px;
    border-bottom: 1px solid #eaeff0;
    vertical-align: middle;
}
.div-thead{
    display: table-header-group;
    font-weight: bold;
}
.div-tfoot{
    display: table-footer-group;
    font-weight: bold;
    background-color: #fff;
}
.div-tbody{
    display: table-row-group;
}

布局文档可在此处找到:http://www.dropzonejs.com/#layout

感谢任何有关更改 CSS 或 JS 的帮助。

如 dropzone 文档中所述,您可以根据需要自定义预览模板,在这种情况下,您只需将 div-trdiv-td 类 添加到预览元素根据您的需要,http://www.dropzonejs.com/#theming

这里是一个如何覆盖 dropzone 模板的例子:

Html:

<div class="dropzone" id="myDropzone"></div>

    <div class="dropzone-previews div-table"></div>

    <div id="preview-template" style="display: none;">
        <div class="dz-preview dz-file-preview div-tr">
            <div class="dz-details">
                <div class="dz-filename div-td"><span data-dz-name></span></div>
                <div class="dz-size div-td" data-dz-size></div>
                <div class="dz-image div-td">
                    <img data-dz-thumbnail />
                </div>
            </div>
            <div class="dz-progress div-td"><span class="dz-upload" data-dz-uploadprogress></span></div>
            <div class="div-td">
                <div class="dz-success-mark"><span>✔</span></div>
                <div class="dz-error-mark"><span>✘</span></div>
            </div>
            <div class="dz-error-message div-td"><span data-dz-errormessage></span></div>
        </div>
    </div>

js:

Dropzone.options.myDropzone = {
    previewsContainer: ".dropzone-previews",
    previewTemplate: document.getElementById('preview-template').innerHTML,
    url: 'upload.php',
    init: function() {
        this.on('success', function(file){
            var errordiv = document.getElementsByClassName('dz-error-mark');
            errordiv[errordiv.length - 2].style.display = 'none'; // The -2 is because there is also one in the preview-template
        });
        this.on('error', function(file){
            var succesdiv = document.getElementsByClassName('dz-success-mark');
            succesdiv[succesdiv.length - 2].style.display = 'none'; 
        });
    }
}

请注意,如果您想使用 table,您只需将预览中的元素用 <td><tr> 包裹起来,然后用作 previewsContainer table 而不是 div.

因为元素 dz-error-markdz-success-mark 默认情况下在 dropzone 中始终可见,您可能希望根据事件隐藏它们,这就是 init 函数中的代码所做的。或者最好不要在开头显示它们并相应地显示它们。

请记住,当您在模板中进行更改时,如果您不修改 dropzone 的默认行为,事情将开始无法正确显示。

Here您可以看到一个高度自定义的拖放区示例,在拖放区文档中也有提及。

我已经解决了这个问题,wallek876 的回答给了我正确的方向,所以这将是被接受的答案。

答案中的细节解决了它,是我看到 dropzone-previews 在 table 的外部而不是底部,应该添加新元素的地方.

解法:

我像这样将 upload-container 作为 id 移动到了 <div class="div-table" id="upload-container">

我按照建议保留了 <div id="preview-template">,并将 <div class="div-tr"> 应用为 previewTemplate 的第一个 child。此结构返回 table 布局,其余样式使用 CSS.

应用

我没能将预览模板放入 HTML。

使用带有 captiontrtd 等的正确 table 标签对于无障碍用户来说很重要。 可以修改 dropzone 库以更好地支持 table(即具有以 <tr> 标签开头的模板)。

重写 Dropzone.createElement 函数(如果模板是 tr,它使用 tbody 块元素而不是 div 块元素):

// Fix the createElement so it works with tables
// Creates an element from string
Dropzone.createElement = function(string){
  var ele = document.createElement(string.startsWith("<tr") ? "tbody" : "div");
  ele.innerHTML = string;
  return ele.childNodes[0];
};