【问题标题】:jQuery Sortable - allow some items to be dropped only into certain listsjQuery Sortable - 允许某些项目仅被拖放到某些列表中
【发布时间】:2013-05-31 21:57:21
【问题描述】:

我正在使用 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'});
});

我应该指出,我完全不擅长涉及花括号的编程语言。我写了上面的代码,但我无法告诉你它的大部分功能,更不用说它为什么起作用了。因此,如果您能以最简单的方式回答您的问题,我将不胜感激。

【问题讨论】:

  • 我在 codecademy 课程中做了类似的事情......我将发布代码和练习链接。

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


【解决方案1】:

那么,我有没有提到我讨厌 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 部分,在目标列表的“接收”函数中,有条件地取消 sender 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 做了很多事情。

第 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/

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 2014-02-15
    • 1970-01-01
    • 2014-07-07
    • 2019-09-07
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2020-09-01
    相关资源
    最近更新 更多