使用 JqueryUI 拖放多个文件

Posted

技术标签:

【中文标题】使用 JqueryUI 拖放多个文件【英文标题】:Drag and Drop multiple files using JqueryUI 【发布时间】:2020-10-22 21:56:07 【问题描述】:

我遇到了以下问题

我有一个页面,用户可以将文件拖放到另一个 DIV 中。用户现在想要一次拖放多个文件。然而问题是,我在网上找到了一个coden-p(可悲的是找不到了),定制了代码以满足设计要求,现在我坚持启用多文件拖放。

如果涉及到 JqueryUI,我是一个完整的初学者。

这个想法是在文件/图片的角落添加复选框。所有选定的项目都应通过拖放立即移动。 理想情况下,用户应该能够使用鼠标拖放来标记必要的文件,但这很好,并不是关键要求。

我不想向某人寻求完整的解决方案,而是寻求可能的来源或示例,我可以尝试从中创建个人自定义解决方案。

代码:

html

<ul class="gallery col-md-8 borderBoxes" id="gallery">
    @foreach (var item in Model.PageList)
    
    <li class="imageListItem ui-icon-zoomin" id="@item.ID">
        <img class="pages small" src="data:image/jpeg;base64,@item.ImageBaase64" onclick="imageLarger(this)" />
    </li>
    
</ul>
<div id="trash" class="col-md-3">
</div>

<div id="documentContainer" class="document-container">
    <div class="row justify-content-between">
        <button id="addNewDocument" class="col-2 btn btn-primary add-doc-button">new document</button>
        <form method="post" class="col-md-2 offset-md-10 forward-form">
        </form>
    </div>
    <ul id="newDocuments"></ul>
</div>

<div style="display: none;">
    <div id="docDescription" class='col-md-4 form-group documentDescription'>
        <label class='control-label input-label'>Dokumenttyp</label>
        <select>
            <!--stuff that is not important for this post-->
        </select>
    </div>
</div>

javascript

function imageLarger(image, liID) 
        if ($(image).width() === 700) 
            $(image).width(100);
            setTimeout(function () 
                $(image).removeClass("largePages");
            , 300);
            
         else 
            $(image).width(700);
            $(image).addClass("largePages");
        

    ;


$("#addNewDocument").click(function () 
    var uid = Math.floor(Math.random() * 26) + Date.now()
    var newDocumentBox = $("<li class='row documentContainer justify-content-between' id='" + uid + "'></li>").prependTo("#newDocuments");
    var newDocumentDescription = $("#docDescription").clone(true);
    newDocumentDescription.appendTo(newDocumentBox);
    var newDroppableBox = $("<div class='documents col-md-7 droppableBox' ></div>").appendTo(newDocumentBox);
    var newDeleteButton = $("<div class='close-container deleteButton' onclick='deleteDocument(" + uid + ")'><div class='leftright'></div><div class='rightleft'></div></div>").appendTo(newDroppableBox);
    
    newDroppableBox.droppable(
        accept: "#gallery > li",
        drop: function (event, ui) 
            ui.draggable.appendTo(this).fadeIn(function () 
                ui.draggable
                    .animate()
                    .find("img")
            );
        
    );
);

function deleteDocument(elementID) 
    var element = document.getElementById(elementID);
    var listOfPages = element.getElementsByClassName("imageListItem");
    var amounOfPages = listOfPages.length;
    if (element.style.display !== "none") 
        element.style.display = "none";
        for (var i = 0; i < amounOfPages; i++) 
            $("#gallery").append(listOfPages[0]); // 0 because removing an object decreases $children.length by 1
        
    
; 
$(function () 
 
    var $gallery = $("#gallery"),
        $trash = $("#trash"),
        $document = $("#document"),
        trash_icon = "<a href='link/to/trash/script/when/we/have/js/off' title='Delete this image' class='ui-icon ui-icon-trash'>Delete image</a>",
        recycle_icon = "<a href='link/to/recycle/script/when/we/have/js/off' title='Recycle this image' class='ui-icon ui-icon-refresh'>Recycle image</a>";

    $("li", $gallery)
        .draggable(
            cancel: "a.ui-icon",
            revert: "invalid",
            containment: "document",
            helper: "clone",
            cursor: "move"
        );

    $trash
        .droppable(
            accept: "li",
            drop: function (event, ui) 
                deleteImage(ui.draggable);
            
        );

    $gallery
            .droppable(
            accept: "li",
            drop: function (event, ui) 
                recycleImage(ui.draggable);
            
        );

    $document
        .droppable(
            accept: "li",
            drop: function (event, ui) 
                ui.draggable.appendTo(this).fadeIn(function () 
                    $item
                        .animate()
                        .find("img")
                );
                deleteImage(ui.draggable);
            
        );

   
    function deleteImage($item) 
        $item.fadeOut(function () 
            var $list = $("ul", $trash).length ?
                $("ul", $trash) :
                $("<ul class='gallery ui-helper-reset'/>").appendTo($trash);

            $item.find("a.ui-icon-trash").remove();
            $item.append(recycle_icon).appendTo($list).fadeIn(function () 
                $item.addClass('removedPage');
                $item
                    .animate()
                    .find("img")
            );
        );
    
   
    function recycleImage($item) 
        $item.fadeOut(function () 
            $item.removeClass('removedPage');
            $item
                .find("a.ui-icon-refresh")
                .remove()
                .end()
                .find("img")
                .end()
                .appendTo($gallery)
                .fadeIn();
        );
    

    $("#recycleAllDocuments")
        .on("click", function () 
            if ($('#trash').children().length > 0) 
                var listOfDeletedItems = document.getElementById("trash").getElementsByClassName("imageListItem");
                for (var i = 0; i < listOfDeletedItems.length; i++) 
                    var $item = $(listOfDeletedItems[i]);
                    recycleImage($item);
                
            
        );
    

    $("deleteButton")
        .on("click", function () 
            var $item = $(this);
            recycleImages($item);
        );

    $("ul.gallery > li")
        .on("click", function (event) 
            var $item = $(this),
                $target = $(event.target);

            if ($target.is("a.ui-icon-trash")) 
                deleteImage($item);
             else if ($target.is("a.ui-icon-zoomin")) 
                viewLargerImage($target);
             else if ($target.is("a.ui-icon-refresh")) 
                recycleImage($item);
            

            return false;
        );
);

【问题讨论】:

欢迎来到 Stack Overflow。这个例子让我想起了jqueryui.com/droppable/#photo-manager关于你的问题,用户如何选择多个项目?然后我建议使用自定义帮助器来表示被拖动的 itrems,然后在 Drop 回调中,您可以分离和附加项目。 我会试试你的建议。是的,这正是我基于代码的示例,但我再也找不到它了。我打算让用户选择带有复选框的项目。因为我已经设置了点击甚至放大项目。 【参考方案1】:

考虑以下示例。

$(function() 
  var $gallery = $("#gallery"),
    $trash = $("#trash"),
    $document = $("#document"),
    trash_icon = "<a href='link/to/trash/script/when/we/have/js/off' title='Delete this image' class='ui-icon ui-icon-trash'>Delete image</a>",
    recycle_icon = "<a href='link/to/recycle/script/when/we/have/js/off' title='Recycle this image' class='ui-icon ui-icon-refresh'>Recycle image</a>";

  $("li", $gallery)
    .draggable(
      cancel: "a.ui-icon",
      revert: "invalid",
      containment: "document",
      helper: function() 
        var help = $("<div>", 
          class: "ui-draggable-helper"
        );
        if ($(".ui-selected").length) 
          help.data("items", $(".ui-selected"));
          help.addClass("multiple");
         else 
          help.data("items", $(this));
        
        return help;
      ,
      cursor: "move"
    );

  $gallery.selectable();

  $trash
    .droppable(
      accept: "li",
      drop: function(event, ui) 
        deleteImage(ui.helper.data("items"));
      
    );

  $gallery
    .droppable(
      accept: "li",
      drop: function(event, ui) 
        recycleImage(ui.draggable);
      
    );

  $document
    .droppable(
      accept: "li",
      drop: function(event, ui) 
        ui.draggable.appendTo(this).fadeIn(function() 
          $item
            .animate()
            .find("img")
        );
        deleteImage(ui.draggable);
      
    );


  function deleteImage($item) 
    $item.fadeOut(function() 
      var $list = $("ul", $trash).length ?
        $("ul", $trash) :
        $("<ul class='gallery ui-helper-reset'/>").appendTo($trash);

      $item.find("a.ui-icon-trash").remove();
      $item.append(recycle_icon).appendTo($list).removeClass("ui-selected").fadeIn(function() 
        $item.addClass('removedPage');
        $item
          .animate()
          .find("img")
      );
    );
  

  function recycleImage($item) 
    $item.fadeOut(function() 
      $item.removeClass('removedPage');
      $item
        .find("a.ui-icon-refresh")
        .remove()
        .end()
        .find("img")
        .end()
        .appendTo($gallery)
        .fadeIn();
    );
  

  $("#recycleAllDocuments")
    .on("click", function() 
      if ($('#trash').children().length > 0) 
        var listOfDeletedItems = document.getElementById("trash").getElementsByClassName("imageListItem");
        for (var i = 0; i < listOfDeletedItems.length; i++) 
          var $item = $(listOfDeletedItems[i]);
          recycleImage($item);
        
      
    );

  $("deleteButton")
    .on("click", function() 
      var $item = $(this);
      recycleImages($item);
    );

  $("ul.gallery > li")
    .on("click", function(event) 
      var $item = $(this),
        $target = $(event.target);
      if ($target.is("a.ui-icon-trash")) 
        deleteImage($item);
       else if ($target.is("a.ui-icon-zoomin")) 
        viewLargerImage($target);
       else if ($target.is("a.ui-icon-refresh")) 
        recycleImage($item);
      
      return false;
    );
);
.gallery 
  list-style: none;


.gallery .ui-selecting 
  background: #ccc;
  border-color: #999;


.gallery .ui-selected 
  background: #eee;
  border-color: #222


.imageListItem 
  width: 100px;
  height: 100px;
  border: 1px solid #ccc;
  border-radius: 3px;
  display: inline-block;
  margin: 3px;


.ui-draggable-helper 
  background: #fff;
  width: 50px;
  height: 65px;
  border: 1px solid #999;
  border-radius: 3px;
  position: relative;
  z-index: 100;


.ui-draggable-helper:after 
  content: "";
  width: 0;
  height: 0;
  border-bottom: 20px solid #999;
  border-right: 20px solid #fff;
  position: absolute;
  left: 29px;
  top: -1px;


.ui-draggable-helper.multiple:before 
  content: "";
  width: 50px;
  height: 65px;
  border-left: 1px solid #999;
  border-bottom: 1px solid #999;
  border-radius: 3px;
  position: absolute;
  top: 5px;
  left: -5px;
  z-index: 0;


#trash 
  border: 1px solid #ccc;
  width: 200px;
  height: 200px;
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul class="gallery col-md-8 borderBoxes" id="gallery">
  <li class="imageListItem ui-icon-zoomin" id="item-1">
    <img class="pages small" src="data:image/jpeg;base64,@item.ImageBaase64" onclick="imageLarger(this)" />
  </li>
  <li class="imageListItem ui-icon-zoomin" id="item-2">
    <img class="pages small" src="data:image/jpeg;base64,@item.ImageBaase64" onclick="imageLarger(this)" />
  </li>
  <li class="imageListItem ui-icon-zoomin" id="item-3">
    <img class="pages small" src="data:image/jpeg;base64,@item.ImageBaase64" onclick="imageLarger(this)" />
  </li>
</ul>
<div id="trash" class="col-md-3">
</div>
<div id="documentContainer" class="document-container">
  <div class="row justify-content-between">
    <button id="addNewDocument" class="col-2 btn btn-primary add-doc-button">new document</button>
    <form method="post" class="col-md-2 offset-md-10 forward-form">
    </form>
  </div>
  <ul id="newDocuments"></ul>
</div>
<div style="display: none;">
  <div id="docDescription" class='col-md-4 form-group documentDescription'>
    <label class='control-label input-label'>Dokumenttyp</label>
    <select>
      <!--stuff that is not important for this post-->
    </select>
  </div>
</div>

借助 Draggable,您可以通过函数调用创建自己的 helper

允许使用辅助元素来拖动显示。支持多种类型:

字符串:如果设置为"clone",则将克隆元素并拖动克隆。 函数:将返回一个 DOMElement 以在拖动时使用的函数。

所以如果你想代表多个项目,你可以让一个助手看起来像这样,你可以使用.data()来携带所有项目。当您drop 助手时,您可以对每个项目执行所需的操作。

在这个例子中,利用 Selectable,用户可以选择图库中的多个项目,然后将它们拖到回收站中。

【讨论】:

以上是关于使用 JqueryUI 拖放多个文件的主要内容,如果未能解决你的问题,请参考以下文章

如何让 jQueryUI 拖放与触摸设备一起使用

jQueryUI:限制拖放元素的容器高度

结构-行为-样式-JqueryUI拖放使用实例(全)

jQueryUI:在拖放元素上限制容器高度

如何在 php 页面中插入 jqueryUi(显示效果 -> 拖放)

HTML 5 拖放相对于 jQuery UI 拖放的优势