jQuery Sortable - 允许某些项目仅被删除到某些列表中

时间:2013-05-31 21:57:21

标签: javascript jquery jquery-ui jquery-ui-sortable

我正在使用jQuery UI Sortable来实现分类选择,链接到一组单选按钮。这部分一直运作良好几年。 (See jsFiddle version.)现在,客户想要修改它:现在只允许某些项目进入某些类别,而且我完全陷入困境。

在事情的后端,很容易禁用某些单选按钮:

<ul id="L" class="L ui-sortable">
    Available (A):
    <li id='L_1'>
    <input type='radio' name='L_1' id='L_1_A' value='A'>
      <label for='L_1_A'>A</label>
    <input type='radio' name='L_1' id='L_1_B' disabled='disabled' value='B'>
      <label for='L_1_B'>B</label>
    <input type='radio' name='L_1' id='L_1_C' value='C'>
      <label for='L_1_C'>C</label>
    Item 1 can't go in B
    </li>
    <li id='L_2'>
    <input type='radio' name='L_2' id='L_2_A' value='A'>
      <label for='L_2_A'>A</label>
    <input type='radio' name='L_2' id='L_2_B' value='B'>
      <label for='L_2_B'>B</label>
    <input type='radio' name='L_2' id='L_2_C' disabled='disabled' value='C'>
      <label for='L_2_C'>C</label>
    Item 2 can't go in C
    </li>
    <!-- etc. -->
</ul>
<ul id='L_B' class='L ui-sortable cat'>Selected - B</ul>
<ul id='L_C' class='L ui-sortable cat'>Selected - C</ul>

(单选按钮是通过CSS和javascript的组合隐藏的。)这样做的副作用是无法保存不正确的分类:如果你试图将某些内容放入某个类别,它就无法进入,你的选择完全被忽略(因为禁用的单选按钮不返回值)。但是,除非你回去查看你保存的记录,否则你永远不会知道发生了什么:对你来说,看起来你按照惯例把物品放在盒子里。

我想要的是,当抓取一个项目时链接到禁用的单选按钮的目标框“变灰”,如果他们仍然试图将它放在该框中,该项目应该跳回到它的起始位置点。基本上,它应该像您设置$("ul.notallowed").sortable("option","disabled",true);时的行为一样,但只有在用户“持有”不允许的项目时才会设置

我知道有一个.is(":disabled")命令可以判断一个单选按钮是否被禁用,但我不知道在哪里放它。

这是现有实施的javascript,即所有项目都允许所有类别。 (我确信有更好/更有效的方法来编写代码,但我很高兴它的工作原理。)

$(function() {
    $("#L").sortable({
        connectWith: '.L',
        containment: '#ListContainer',
        receive: function(event, ui) {
            $(ui.item).find('input:radio')[0].checked = true;
        }
    }).disableSelection();
    $("#L_B").sortable({
        connectWith: '.L',
        containment: '#ListContainer',
        receive: function(event, ui) {
            $(ui.item).find('input:radio')[1].checked = true;
        }
    }).disableSelection();
    $("#L_C").sortable({
        connectWith: '.L',
        containment: '#ListContainer',
        receive: function(event, ui) {
            $(ui.item).find('input:radio')[2].checked = true;
        }
    }).disableSelection();
});
$(document).ready(function() {
    $('.B').closest('li').appendTo("#L_B");
    $('.C').closest('li').appendTo("#L_C");
    $('ul.ui-sortable').width("10em");
    $('ul.ui-sortable li').css({cursor:'pointer'});
});

我应该注意到我完全厌恶涉及大括号的编程语言。我写了上面的代码,但是我无法告诉你它的大部分内容,更不用说为什么它有用了。所以如果你能用最简单的术语来表达你的答案,我会非常感激。

1 个答案:

答案 0 :(得分:8)

那么,我是否曾提到我讨厌JavaScript?但是我得到了它的工作(没有变灰,但我很久以来就不再关心那个了)随着灰色和一切。

第1部分,忘记在jQuery中检测禁用的单选按钮。 ((":disabled")用作选择器,但它返回一个单选按钮,而不是其父列表项。)相反,只需在列表项中添加一个或多个类。

<li class="noB">
    <label><input type="radio" name="L1" value="A" />A</label>
    <label><input type="radio" name="L1" value="B" disabled="disabled" />B</label>
    <label><input type="radio" name="L1" value="C" />C</label>
    Item 1 can't go in B
</li>

第2部分,在目标列表的“接收”功能中,有条件地取消发件人 jQuery对象的可排序。例如,

$("#L_B").sortable({
    connectWith: '.L',
    containment: '#ListContainer',
    receive: function (event, ui) {
        if ($(ui.item).hasClass("noB")) {
            $(ui.sender).sortable("cancel");
        }
        else {
            $(ui.item).find('input:radio')[1].checked = true;
        }
    },
}).disableSelection();

.sender部分至关重要:我不知道在使用ui.itemli.noB或其他任何东西尝试各种事物时,我已经失去了多少头发。 (这对我来说没什么意义:我想要阻止的是项目放在错误的位置,为什么我需要从父项中取消删除列表?但无论如何。)

在我的案例中,第3部分是将列表标签从列表中移出,因为除了不是非常有效之外,它还使cancel做了straaaange事情。

第4部分,灰度:在“开始”功能中使用.addClass,在每个可排序框的“停止”功能中使用.removeClass。我把这些放在receive: function(...) {...}之后,但顺序无关紧要。 (毫无疑问,有一种方法可以编写这个函数并且每次都调用它,但我是否曾提到JavaScript和我不相处的方式?)

    start: function (event, ui) {
        if ($(ui.item).hasClass("noB")) {
            $("#L_B").addClass("disabled");
        }
        if ($(ui.item).hasClass("noC")) {
            $("#L_C").addClass("disabled");
        }
    },
    stop: function (event, ui) {
        if ($(ui.item).hasClass("noB")) {
            $("#L_B").removeClass("disabled");
        }
        if ($(ui.item).hasClass("noC")) {
            $("#L_C").removeClass("disabled");
        }
    }

不要忘记在CSS中定义“禁用”类,否则所有这些体操都会完全没有。

工作jsFiddle:http://jsfiddle.net/NY7Ms/4/