Gridstack:将小部件从一个网格拖到另一个网格中,嵌套一个

Posted

技术标签:

【中文标题】Gridstack:将小部件从一个网格拖到另一个网格中,嵌套一个【英文标题】:Gridstack: Dragging widget from one grid into another, nested one 【发布时间】:2019-09-13 01:47:17 【问题描述】:

我正在尝试创建此行为,但不确定 Gridstack 是否支持它。我有 3 个 Gridstack 网格:Grid1Grid2Grid3Grid1 是一个独立的网格,Grid3 嵌套在 Grid2 中。我需要能够将小部件从 Grid1 拖到 Grid2(外部网格)和 Grid3(嵌套网格)中。以下示例我能够在 2 个***网格之间拖动小部件并创建一个嵌套网格,但不能将这 2 个组合在一起。如果支持 - 任何指针表示赞赏。

注意:将 sn-p 扩展到全屏

$(document).ready(function() 
  $('.grid-stack').gridstack();
);
.grid-stack 
  background: lightgoldenrodyellow;


.grid-stack-item-content 
  color: #2c3e50;
  text-align: center;
  background-color: #18bc9c;


.grid-stack .grid-stack 
  /*margin: 0 -10px;*/
  background: rgba(255, 255, 255, 0.3);


.grid-stack .grid-stack .grid-stack-item-content 
  background: lightpink;
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.4.0/gridstack.min.css" />


<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script type="text/javascript" src='//cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.4.0/gridstack.min.js'></script>
<script type="text/javascript" src='//cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.4.0/gridstack.jQueryUI.min.js'></script>


<div class="container-fluid">
  <h1> Multilevel Nested grids demo</h1>
  <div class="grid-stack" id="container-stack">
    <div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs- data-gs->
      <div class="grid-stack-item-content">
        <span>Grid One</span>
        <div class="grid-stack" id="grid-one">
          <div class="grid-stack-item widget" data-gs-x="0" data-gs-y="0" data-gs- data-gs->
            <div class="grid-stack-item-content">1</div>
          </div>
          <div class="grid-stack-item widget" data-gs-x="3" data-gs-y="0" data-gs- data-gs->
            <div class="grid-stack-item-content">2</div>
          </div>
        </div>
      </div>
    </div>
    <div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs- data-gs->
      <div class="grid-stack-item-content">
        <span>Grid Two</span>
        <div class="grid-stack" id="grid-two">
          <div class="grid-stack-item widget" data-gs-x="0" data-gs-y="0" data-gs- data-gs->
            <div class="grid-stack-item-content">3</div>
          </div>
          <div class="grid-stack-item widget" data-gs-x="3" data-gs-y="0" data-gs- data-gs->
            <div class="grid-stack-item-content">4</div>
          </div>
          <div class="grid-stack-item" data-gs-x="6" data-gs-y="0" data-gs- data-gs->
            <div class="grid-stack-item-content">
              <span>Grid Three</span>
              <div class="grid-stack" id="grid-three">
                <div class="grid-stack-item widget" data-gs-x="0" data-gs-y="0" data-gs- data-gs->
                  <div class="grid-stack-item-content">5</div>
                </div>
                <div class="grid-stack-item widget" data-gs-x="6" data-gs-y="0" data-gs- data-gs->
                  <div class="grid-stack-item-content">6</div>
                </div>
              </div>
            </div>
          </div>

        </div>

      </div>
    </div>
  </div>
</div>

【问题讨论】:

您可以添加一些您尝试过的示例代码吗? @RachelGallen 我几乎下载并使用了这两个示例:1 - 将小部件从网格拖动到网格:gridstackjs.com/demo/two.html 和 2 - 嵌套网格:gridstackjs.com/demo/nested.html。但我无法让这两部分一起工作。 从演示中我可以看到,该库似乎只支持重新排列图块,但你不能将一个放在另一个或任何东西中(就像一个小的放在一个大的里面),它们是并非所有可拖动和可放置的区域。我没有看嵌套示例,我没有看到它。如果这是您想要的,您可能可以调整网格堆栈 J 以使它们同时拖放。昨晚在js里看到了设置的地方。 谢谢,我看看能不能装上我一直在试验的小提琴 sn-ps。并感谢您的建议。你是对的,我可能不得不在 gridstack API 之外使用更通用的东西。 @Towkir 仍在使用各种方法进行调整,但我研究得越多,如果我想至少模仿这种行为,这似乎就是一种黑客行为。例如。在放置期间,从小部件中取出内部网格(DOM 方式)并将其附加到文档的主体(同时将其位置保持在同一位置)。 【参考方案1】:

以下示例我能够在 2 个***网格之间拖动小部件并创建一个嵌套网格,但不能将这 2 个组合在一起。如果支持的话

悲伤但真实,那是不可能。至少,不是gridstack

这种拖动机制背后的关键是通过acceptWidgets 选项完成的。但这不能处理多级.grid-stack 元素。因此,出现错误。

您可以尝试将sn-p中添加的脚本修改为如下内容:

$("#container-stack").gridstack(
   acceptWidgets: '.grid-stack-item'
)

但遗憾的是,一旦您开始拖动任何小部件,这将导致 错误。但它适用于单层嵌套,这绝对不是您想要的。

该文档也没有说明任何有关嵌套级别拖动的内容。

但我认为这是不可能的原因是issue,也是this one。

我想这(几乎)正是您想要的。但没有任何官员的回应。而且,它已经三岁了。另一个表明该项目即将死去的缺陷是,当您尝试访问他们的一些文件(例如script)时,您会收到一个安全警告,这使我暂时无法添加此 sn-p。


因此,如果我是你,我会选择 jqueryUI 并自定义代码。


更新

这是一个类似于我猜想的东西的 sn-p,如果这正确,请告诉我,然后我会再次改进它,比如添加调整大小、对齐兄弟小部件和其他一些东西:

再次检查全屏模式下的 sn-p。

$("#gridThree").draggable(
  snap: '#gridTwo',
  snapMode: 'inner',
  zIndex: 5,
  containment: 'parent'
);

$(".widgetInOne, .widgetInTwo, .widgetInThree").draggable(
  snap: '#gridOne, #gridTwo, #gridThree',
  snapMode: 'inner',
  zIndex: false,
  stack: 'div',
  cursor: 'grab',
  // grid: [ 100, 100 ]
);

$("#gridOne, #gridTwo, #gridThree").droppable(
  accept: '.widgetInOne, .widgetInTwo, .widgetInThree',
  drop: function(event, ui) 
    if ($(event.target).find($(event.toElement)).length == 0) 
      $(event.toElement).css(
        'left': '',
        top: ''
      );
      $(event.target).append($(event.toElement));
    
  
);
* 
  margin: 0;
  padding: 0;
  box-sizing: border-box;


#gridOne 
  background: #cecece;
  width: 40%;
  height: 400px;
  display: inline-block;
  margin-right: 4%;
  vertical-align: top;


.widgetInOne,
.widgetInTwo,
.widgetInThree 
  width: 100px;
  height: 100px;
  padding: 0.5em;


#gridTwo 
  background: #bfe9f3;
  width: 50%;
  height: 400px;
  display: inline-block;
  margin-left: 4%;
  vertical-align: top;
  position: relative;


#gridThree 
  background: #ffdda9;
  width: 300px;
  height: 300px;
  display: inline-block;
  vertical-align: top;
  position: absolute;
  right: 100px;
  top: 0;
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://jqueryui.com/resources/demos/style.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>



<div id="gridOne">
  <div class="ui-widget-content widgetInOne">
    <p>One</p>
  </div>
</div>


<div id="gridTwo">
  <div class="ui-widget-content widgetInTwo">
    <p>Two</p>
  </div>
  <div id="gridThree">
    <div class="ui-widget-content widgetInThree">
      <p>Three</p>
    </div>
  </div>
</div>

一些值得注意的

当您将小部件拖到网格中时,小部件元素实际上会在该网格中移动(在 DOM 结构中),因此任何依赖于父级的 css 选择器可能在此处不起作用。仅将 css 应用于小部件类。 1234563对于这个。

此处尚未添加可调整大小的选项,希望您可以根据需要进行调整

【讨论】:

不知道域上的证书问题,但它们似乎在 GitHub 上很活跃。是的,我已经看到了较旧的问题,但从那时起已经发布了几个版本,所以我希望有一些变化。我会考虑一下我的一些想法,但最终如果没有任何效果,我会接受你的建议。 对,顺便说一句,我仍在尝试解决这个问题,在某个地方,我相信这是可能的,我的意思是 gridstack 非常酷。你注意到demo two 中的配置选项了吗? removableaccept-widget 这些是实现这一目标的关键,无论如何,如果我能想出什么办法,我会更新答案 这看起来与我需要的行为非常接近。几点:当“小部件 1”被拖入内部网格时 - 它应该坚持使用它(当我移动它时移动)到目前为止,这似乎只适用于“小部件 3” - 我可以将它拖出内部网格,然后回到 - 它会依附于它。此外,理想情况下,小部件会表现出 Gridstack 行为(对齐位置等),但我想我可以稍后添加。看起来很酷! @YuriyGalanter 现在请检查一下,捕捉仍然有点棘手,检查我在 sn-p 正下方添加的 几件事情列表 好的,谢谢!!。顺便说一句,我认为可以改进一个小的 UX 限制,即:当您将小部件放在另一个网格中时,小部件会到达静态位置,而不是您放置它的位置。这是因为 jQuery draggable 使用相对位置来实现这一点,而不是绝对位置。我打算修改它,但我意识到它只会破坏更多的东西。【参考方案2】:

这是我编写的一个旧的拖放小提琴的代码(很久以前!),具有可拖动和可放置的区域。可以拉到任一可放置区域的项目可以再次从一个区域拖动到另一个区域并上下拖动。虽然这些项目的大小与您的示例中的不同,但它表明只需使用 jquery/jquery-ui 即可实现相同的用户体验,而无需坚持使用 gridstack。通过在电网外工作,您可以节省一些费力的时间! ;)

希望对你有帮助

fiddle

$("#launchPad").height($(window).height() - 20);
var dropSpace = $(window).width() - $("#launchPad").width();
$("#dropZone").width(dropSpace - 70);
$("#dropZone").height($("#launchPad").height());

$(".card").draggable(
  appendTo: "#launchPad",
  cursor: "move",
  helper: 'clone',
  revert: "invalid",

);

$("#launchPad").droppable(
  tolerance: "intersect",
  accept: ".card",
  activeClass: "ui-state-default",
  hoverClass: "ui-state-hover",
  drop: function(event, ui) 
    $("#launchPad").append($(ui.draggable));
  
);

$(".stackDrop1").droppable(
  tolerance: "intersect",
  accept: ".card",
  activeClass: "ui-state-default",
  hoverClass: "ui-state-hover",
  drop: function(event, ui) 
    $(this).append($(ui.draggable));
  
);

$(".stackDrop2").droppable(
  tolerance: "intersect",
  accept: ".card",
  activeClass: "ui-state-default",
  hoverClass: "ui-state-hover",
  drop: function(event, ui) 
    $(this).append($(ui.draggable));
  
);
body 
  margin: 0;


#launchPad 
  width: 200px;
  float: left;
  border: 1px solid #eaeaea;
  background-color: #f5f5f5;


#dropZone 
  float: right;
  border: 1px solid #eaeaea;
  background-color: #ffffcc;


.card 
  width: 150px;
  padding: 5px 10px;
  margin: 5px;
  border: 1px solid #ccc;
  background-color: #eaeaea;


.stack 
  width: 180px;
  border: 1px solid #ccc;
  background-color: #f5f5f5;
  margin: 20px;


.stackHdr 
  background-color: #eaeaea;
  border: 1px solid #fff;
  padding: 5px


.stackDrop1,
.stackDrop2 
  min-height: 100px;
  padding: 15px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>




<body>
  <div id="launchPad">
    <div class="card draggable">
      apple
    </div>
    <div class="card draggable">
      orange
    </div>
    <div class="card draggable">
      banana
    </div>
    <div class="card draggable">
      car
    </div>
    <div class="card draggable">
      bus
    </div>
  </div>

  <div id="dropZone">
    <div class="stack">
      <div class="stackHdr">
        Drop here
      </div>
      <div class="stackDrop1 droppable">

      </div>
    </div>

    <div class="stack">
      <div class="stackHdr">
        Or here
      </div>
      <div class="stackDrop2 droppable">

      </div>
    </div>
  </div>

【讨论】:

这是我发现的另一个老小提琴 - 它有 boxes 这看起来很有希望,谢谢!让我来评估一下,但我认为这与我们需要的答案最接近。 顺便说一句 @YuriyGalanter 你不是说 grid3grid2 里面吗?我的意思是grid3 本身可以在grid2 内部拖动,还可以包含小部件?

以上是关于Gridstack:将小部件从一个网格拖到另一个网格中,嵌套一个的主要内容,如果未能解决你的问题,请参考以下文章

GridStack 如何禁用移动或拖动网格小部件

如何将小部件动态添加到网格?

将小部件移动到另一个文件后,Flutter Localization功能无法正常工作?

将小部件名称与小部件一起添加到主屏幕

GridStack - 重新初始化现有网格

扑。将一个 Draggable 项目拖到另一个 Draggable 项目上