Rails / jQuery sortable => 将 Item 拖放到彼此之上以嵌套 Model

Posted

技术标签:

【中文标题】Rails / jQuery sortable => 将 Item 拖放到彼此之上以嵌套 Model【英文标题】:Rails / jQuery sortable => drag Item on top of each other for nesting Model 【发布时间】:2016-05-07 07:19:23 【问题描述】:

好吧,我在包装器<div id="notecards"> 中将记事卡列为<div>(不包括<ul><li>)。使用 jQueryUI sortable() 对它们进行排序非常有效。

我希望笔记可以嵌套:

class Note < ActiveRecord::Base
    has_many    :subnotes,      class_name: "Note", foreign_key: "parent_id", dependent: :destroy
    belongs_to  :parent_note,   class_name: "Note", foreign_key: "parent_id"
end

但我不希望排序像通常使用 &lt;ul&gt;&lt;li&gt; 标记那样可嵌套。 我希望您可以将 Notecards 拖到彼此上,并且在笔记顶部掺杂的那个通过 ajax 提交到服务器(以更新 parent_id)并在当前视图中消失。

我尝试使用第二个列表(在wrapper #notecard 之外)并将它们与sortable.( connectWith: 'bal..' ) 连接起来 然后在外部列表中,我可以运行 ajax 代码以将新父级发送到服务器,并 .remove() 注释。

=> 但这不是我想要的行为。

所以一个想法是,每个便笺在其&lt;div&gt; 中都有它自己的列表,可以将便笺放到其中,但是每个便笺都需要生成自己的 jQueryUI.sortable() 代码???? ~> 不知道 + 在我的脑海中如何实现这一点的线索。

这是当前状态的伪代码(有错误的行为/不是我正在寻找的笔记行为):

html

<div id="dropToParent">
</div>

<div id="notecards">
    <div class="note">
        note one
    <div>
    <div class="note">
        note two
    <div>
    <div class="note">
        note three
    <div>
</div>

JQuery UI 可排序代码(当前状态不是我正在寻找的行为)

( function($)     

    // Drop Zone for parent => Not the behavior I'm looking for
    $('#dropToParent').sortable(
        connectWith: '#notecards',
        receive: function(event, ui) 
            $(ui.item).hide()
            $.ajax( 'sending the new parent id to server' );
            ui.item.remove();
        
    );


    // #notecards div is sortable
    $('#notecards').sortable(
        connectWith: '#dropToParent'
        update: function() 
            $.ajax( 'sending data to Server to reposition remaining notecards ...' )
        
    );

)(jQuery);

【问题讨论】:

我认为问题在于 sortable 实际上将 移开,因此嵌套会有点困难。我认为您最好使用某种拖动库和碰撞检测来确定某物被掉落到某物上...... 我发现了这个顺便说一句:mjsarfatti.com/sandbox/nestedSortable 是的,我也找到了,但这不是我要寻找的行为(我不想显示嵌套树)。也许你是对的,我必须查看拖动库 - 虽然我仍然希望我的笔记列表是可排序的...... ??? 您可以自己创建排序功能,使用 jQuery dragstart 和 dragstop 并不难。 看来 draggable() 是为 sortable() 设计的 jqueryui.com/draggable/#sortable 我希望能解决这个问题 【参考方案1】:

哇,找到了解决该问题的方法。想分享我在解决这个问题时得到的见解。

首先,这是一个小提琴:https://jsfiddle.net/vs6ho3yq/

1) 在一个可排序对象中可以有多个可放置目标

2) 当您在 note2 之后将 note1 排序并且您仍然持有 note1 时,会出现一种奇怪的行为。 note2 将显示在位置一,但 note2 的可放置目标仍然在中间,现在 note1 已被移动 (在小提琴中,这种奇怪的行为已用 [3] 中描述的行进行了纠正)

3) 要解决此问题,您只需将refreshPositions: true, 添加到可排序选项(!!!SORTABLE 不可删除)(/javascript 部分/小提琴中的第 21 行)。

如果您想自己查看奇怪的行为,只需在 /JavaScript Part/ fiddle 中注释第 21 行

希望这对将来的任何人都有帮助。 干杯

这是小提琴的代码:

HTML

<div id="notecards">
    <div class="note">
        note1
    </div>
    <div class="note">
        note2
    </div>
    <div class="note">
        note3
    </div>
</div>

CSS

#notecards 
    display: block;
    position: relative;
    margin: 60px 0;
    padding: 0;
    border: 1px solid blue;


.note 
    display: inline-block;
    position: relative;
    margin: 0;
    padding: 1rem 1.5rem;
    vertical-align: top;
    border: 1px solid #ccc;


.note-on-note 
    background-color: red;

JS

(function($) 

    $('.note').droppable(
        tolerance: 'pointer',
        over: function() 
            $(this).toggleClass('note-on-note');
        ,
        out: function() 
            $(this).toggleClass('note-on-note')
        ,
        drop: function() 
            $('.note').each().removeClass('note-on-note');

            // do ajax, eg. move note as subnote
        
    );

    // #notecards div is sortable
    $('#notecards').sortable(
        revert: 200,
        refreshPositions: true,
        update: function() 
            // do ajax eg. Update posiotions
        
    );


)(jQuery);

【讨论】:

以上是关于Rails / jQuery sortable => 将 Item 拖放到彼此之上以嵌套 Model的主要内容,如果未能解决你的问题,请参考以下文章

jquery-ui sortable - 在列表之间移动任务

jquery-ui-sortable 的拖动事件

jquery Sortable connectWith 两次调用更新方法

jQuery Sortable的自身序列化

为啥 jQuery.sortable 的这个 ajax 会多次执行更新?

jQuery UI:sortable('toArray') 返回一个空数组