动态启用/禁用jquery可排序项

时间:2010-12-05 20:15:46

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

我有可以排序的表行,具体取决于是否检查了某些单选按钮。可排序在document.ready上初始化如下:

$(document).ready(function() {
    // Return a helper with preserved width of cells
    // handy code I got from http://lanitdev.wordpress.com/2009/07/23/make-table-rows-sortable-using-jquery-ui-sortable/
    var fixHelper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    };
    // #opts = table id; tr.ui-state-disabled class = rows not sortable
    $("#opts tbody").sortable({
        items: 'tr:not(.ui-state-disabled)',
        cursor: 'crosshair',
        helper: fixHelper
    }).disableSelection();
});

我在单选按钮(带有前缀“active_”)onchange的附加按钮上附加了以下功能,它可以从表行添加或删除ui-state-disabled类属性(动态ID为前缀“opt_”):

    var toggleDrag = function(i){
    if ($('#active_'+i+'-0').is(':checked')) {
        $('#opt_'+i).addClass('ui-state-disabled');
    }
    if ($('#active_'+i+'-1').is(':checked')) {
        $('#opt_'+i).removeClass();
    }
    $("#opts tbody").sortable("option", "items", "tr:not(.ui-state-disabled)");
    //$("#opts tbody").sortable("refresh");
    //alert($('#opt_'+i).attr('class')); - alert indicates that the class attribute is being changed
    //$("#opts tbody").sortable("option", "cursor", "auto"); - this works!
}

如果我选择一个单选按钮,该按钮应该可以对以前不可排序的行进行排序,那么它可以工作,我可以拖放该行。问题是如果我选择一个单选按钮来创建一个以前可排序,不可排序的行,我仍然可以拖放它。如果以前可排序,则setter .sortable("option", "items", "tr:not..etc")不会出现“取消注册”。我也试过.sortable(“刷新”)没有运气。我已经检查了是否正在使用警报更改类属性,它是。

对此的任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:15)

我遇到了同样的问题,items选项似乎没有删除之前启用的项目。

cancel选项可以。请注意,禁用的项目将移动以为可排序的项目腾出空间(该点仍然可用作放置目标),但拖动禁用的项目本身将不起作用。使用disabled类还可以根据项目是否可排序来轻松更改样式(请参阅jsfiddle)。

这里的代码部分基于Lamb Bah的答案,但它已被大大整理和简化。

html:

<ul id="sorted-list">
   <li>
       <p><input type="checkbox" checked="true" /> Item 1</p>
    </li>
   <li>
       <p class="disabled"><input type="checkbox" /> Item 2</p>
   </li>
   <li>
       <p><input type="checkbox" checked="true" /> Item 3</p>
   </li>
</ul>

jQuery:

$("#sorted-list").sortable({
    cancel:".disabled"
});

// add or remove the 'disabled' class based on the value of the checkbox
$("#sorted-list input").click(function() {
    if (this.checked) {
        $(this.parentElement).removeClass("disabled");
    } else { 
        $(this.parentElement).addClass("disabled");
    }
});

CSS:

li {
  border: 1px solid #aaa;
  background-color: #eee;
  color:#555;
  padding: 5px;
}

.disabled {
  color:#ddd;
}

答案 1 :(得分:6)

我有一个类似的问题,并找到了一个简单的解决方案(但在我的例子中,我使用的是可排序的ul而不是表格,因为在ul中有更多的自由标记)。

它背后的想法是让列表及其所有项目可排序,但删除句柄,从而禁用单个项目的排序能力,如此代码所示

<ul id="sorted-list">
    <li>
        <div class="handle sortable">
            <p>Item 1</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
    <li>
        <div class="handle sortable">
            <p>Item 2</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
    <li>
        <div class="handle sortable">
            <p>Item 3</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
    <li>
        <div class="handle sortable">
            <p>Item 4</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
</ul>
<script>
    $("#sorted-list").sortable({
        items: "li",
        handle: ".handle.sortable"
    });
    $("#sorted-list").find("input").click(function() {
        if ($(this).closest(".handle").hasClass("sortable"))
            $(this).val("Enable Sort").closest(".handle").removeClass("sortable");
        else $(this).val("Disable Sort").closest(".handle").addClass("sortable");
    });
</script>

答案 2 :(得分:4)

答案 3 :(得分:2)

我一直试图做同样的事情。我真的想要项目功能而不是禁用。如上所述,jQueryUI实现存在一个缺点,即如果选择器匹配的项目发生更改,则可排序项不会刷新项目列表。

为了解决这个问题,我只是简单地销毁并重新安排了sortabled。我已经让Hannele的JSfiddle演示了(http://jsfiddle.net/Sxg8D/140/)。

$("#sorted-list").sortable({
    items:"li:not(.disabled)"
});

$("#sorted-list input").click(function() {
    if (this.checked) {
        $(this.parentElement).removeClass("disabled");
    } else { 
        $(this.parentElement).addClass("disabled");
    }

    $("#sorted-list")
        .sortable( "destroy" )
        .sortable({
            items:"li:not(.disabled)"
        });
});

答案 4 :(得分:0)

我知道这是旧的,但有类似的问题。我在分组中有可分类的项目。我希望某些组可以在任何地方进行排序,而某些组只能对组的子部分进行排序。

<div id="sortBlock">
    <div id="noSort class="itemBlock">
        <div class="item">
        <div class="item">
    </div>
    <div id="canSort" class="itemBlock">
        <div class="item">
        <div class="item">
    </div>
</div>

来自noSort的项目可以在任何地方排序。 canSort中的项目只能排序到其他canSort块中。

$("#sortBlock").sortable({
    items: "> div.itemBlock > .item"   // this makes sure only the sub items will be sortable
});

然后在init之后设置此规则似乎可以解决问题。

$("#sortBlock").sortable( "option", "items", "> div:not(#noSort) > .item");

试图在开始/停止事件中动态执行此操作,但这样做了,不确定“为什么”,所以测试得很好。