2016-08-11 30 views
0

我的工作与父母项目和分项的排序名单上。用户应该能够在两者之间移动项目,还可以移动父项目及其子项目。jQuery的可排序列表连接AJAX调用

我想出如何做一个连接排序列表做到这一点:

https://jsfiddle.net/ron_s/fovah76v/1/

要做到这一点,我没有使用列表ID:

$('#id_of_the_list').sortable({ ... }) 

但一般。分类:

$('.sortable').sortable({ ... }) 

我现在的问题是,AJA X调用只抓取父项的ID,而不是子项。

<script type="text/javascript"> 
$(document).ready(function() { 
$('.sortable').sortable({ 
    connectWith: 'ul.sortable', 
    update: function() { 
    $.ajax({ 
     type: 'post', data: $('.sortable').sortable('serialize'), dataType: 'script', 
     complete: function (request) { 
     $('.sortable'); 
     }, url: '/tasks/sort_goal_task' 
    }) 
    } 
    }); 
}); 
</script> 

我觉得有一个非常类似的问题here,但我不能让这段代码的工作。

感谢您的帮助, 罗恩

+0

欢迎堆栈溢出。更新函数将'event'和'ui'传递给回调函数。目前还不清楚你想用数据做什么......但我怀疑'ui'属性会有帮助。 – Twisty

+0

再看看这个,我认为'div'和extra' ul'正在抛弃它。你想排序任务和子任务吗?或者只是将子任务排序为任务? – Twisty

回答

0

这可能是一种复杂的答案,而不是正是你要找的人,或不止。初次发行

部分原因是,它是非常难以达到的嵌套列表。由于他们有他们没有的项目,基本上呈现给ul与0 height。我建议你制作block至少有一些高度。

我还除去填充和手动在li添加回给任务和子任务之间的空间关系。我开始有更多的类,parentchild分开列表,这样我可以知道我的风格,并与工作。

这个parentchild关系有助于本质上2个可排序列表,这恰好是嵌套的。所以我为$(".parent").sortable()$(".child").sortable()创建了选项,试图帮助组织它们。这也可以使我们有能力接受或拒绝(取消)可分类物品,这些物品可以根据它们是哪一类型的任务或它们的起源地。

这绝非完美,我发现很多在这里和那里有点古怪的bug,但核心元素进行排序任务和子任务,并拖动一个子课题负责人到另一个任务的能力。

工作实例迄今:https://jsfiddle.net/Twisty/sv9qdpLb/

HTML

<div id="container"> 
    <h2>Tasks</h2> 
    <ul id="list" class="parent sortable"> 
    <li id="t1" class="task" data-id="l1"> 
     Task 1 <span class="add-subTask-button ui-icon ui-icon-plus"></span> 
     <ul class="child sortable"></ul> 
    </li> 
    <li id="t2" class="task" data-id="l2"> 
     Task 2 <span class="add-subTask-button ui-icon ui-icon-plus"></span> 
     <ul class="child sortable"> 
     <li id="t2_1" class="subTask" data-id="l2-1"> 
      Sub Task 1 <span class="remove-subTask-button ui-icon ui-icon-minus"></span> 
     </li> 
     <li id="t2_2" class="subTask" data-id="l2-2"> 
      Sub Task 2 <span class="remove-subTask-button ui-icon ui-icon-minus"></span> 
     </li> 
     </ul> 
    </li> 
    <li id="t3" class="task" data-id="l3"> 
     Task 3 <span class="add-subTask-button ui-icon ui-icon-plus"></span> 
     <ul class="child sortable"></ul> 
    </li> 
    </ul> 
</div> 

如果您查看演示,你会看到他们在很大程度上是所有ulli风格列表。是的,你可以使用其他的东西,但是把每个列表项目当作它们,列表中的对象项目,以及调整它的数据和标识符的属性等,很容易。

CSS

#container { 
    width: 600px; 
    margin: 30px auto; 
} 

ul.parent { 
    font-size: 18px; 
    width: 200px; 
    margin: 0; 
    padding: 0; 
} 

ul.parent li { 
    list-style: none; 
    margin-bottom: 2px; 
    padding-left: 3px; 
    border: 1px solid #999; 
    border-radius: 6px; 
    position: relative; 
} 

ul.parent li span.ui-icon { 
    position: absolute; 
    top: .25em; 
    right: 2px; 
    left: auto; 
    cursor: pointer; 
} 

ul.child { 
    display: block; 
    font-size: 14px; 
    padding-left: 30px; 
    min-height: 1em; 
} 

ul.child li { 
    list-style: none; 
    border: 1px solid #bbb; 
    margin-bottom: 1px; 
} 

.placeholder { 
    background: yellow; 
    height: 1em; 
} 

.handle { 
    background: orange; 
    width: 20px; 
    height: 20px; 
    float: left; 
    margin: 0 5px 10px 5px; 
} 

.container { 
    overflow: hidden 
} 

我这里没有发生很大的变化只是做一些事情更具体。我还添加了边框,以便为用户提供视觉排队或对分组及其关系的了解。

jQuery的

$(document).ready(function() { 
    // Make tasks sortable 
    function fullSerial() { 
    var par = {}; 
    $.each($("#list").sortable("toArray"), function(key, val) { 
     par[val] = $("#" + val + " .child").sortable("toArray"); 
    }); 
    return par; 
    } 

    $(".parent").sortable({ 
    placeholder: 'placeholder', 
    connectWith: ".sortable", 
    over: function(e, ui) { 
     if (ui.item.hasClass("subTask")) { 
     $(".parent").sortable("cancel"); 
     } 
    } 
    }); 

    $(".child").sortable({ 
    placeholder: 'placeholder', 
    accept: ".child", 
    connectWith: ".sortable", 
    }).disableSelection(); 

    $(".sortable").on("sortupdate", function() { 
    //console.log($(".sortable").sortable("serialize")); 
    console.log(fullSerial()); 
    }); 

    $(".add-subTask-button").click(function() { 
    var task = $(this).parent(); 
    var taskName = prompt("Enter Sub Task Name."); 
    var newId = task.attr("id") + "_" + (task.find("ul.child li").length + 1); 
    var subTask = $("<li>", { 
     id: newId, 
     class: "subTask", 
     "data-id": newId 
    }).html(taskName + "<span class='remove-subTask-button ui-icon ui-icon-minus'></span>"); 
    task.find(".child").append(subTask).sortable("refresh"); 
    }); 

    $(".remove-subTask-button").click(function() { 
    var subTask = $(this).parent(); 
    var ulElem = subTask.parent(); 
    subTask.remove(); 
    ulElem.sortable("refresh"); 
    }); 
}); 

通过测试,我发现serialize方法不使用嵌套排序列表打好。所以我创建了一个函数来构建一个任务对象,其中包含一系列子任务作为每个任务的元素。我怀疑使用JSON.serialize()可能会让你传递一些东西,但是你总是可以操作fullSerial从对象而不是对象本身返回一个序列化的字符串。

你可以看到两个排序。由于您的操作系统不清楚您是否允许将子任务设置为任务,因此有人试图阻止此类操作。我尝试了receive中的相同代码,它应该恢复排序...但是都没有。另外,如果您足够狡猾,您可以拖动整个任务,并将其子任务拖入子任务位置。

为了能够执行更深入的测试,我添加了一种即时添加项目并动态生成/删除子任务的方法。

我希望有帮助。正如我刚才所说,这可能比你需要的多,但你的问题导致了一个复杂的答案。即使没有添加的元素。

UPDATE

防止任务从被拖入子任务的示例:https://jsfiddle.net/Twisty/sv9qdpLb/4/

$(".child").sortable({ 
    placeholder: 'placeholder', 
    connectWith: ".sortable", 
    receive: function(e, ui) { 
    if (ui.item.hasClass("task")) { 
     ui.sender.sortable("cancel"); 
    } 
    } 
}); 
+0

嗨Twisty,非常感谢您的回答! CSS部分确实比我所需要的要多(该列表是完整样式的应用程序的一部分,我只是简化了它以使问题更加清晰),但您的'fullSerial'功能正是我所期待的。 用户应该能够将子任务转换为任务,所以我剪掉了$(“。parent”)中的相应部分。作为一个很好的人:你能想出一种如何禁用将父母与childern列表拉到另一个孩子上的方法,因为这很难解析? 再次感谢! Ron – Ron

+0

我会看看能做些什么。在'receive'中,可以检查该项目是否具有父类'并且执行'取消'。这应该恢复排序。 – Twisty

+0

@Ron查看更新。 – Twisty

相关问题