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

发布于 2024-10-06 07:34:00 字数 1642 浏览 1 评论 0原文

我的表格行可以根据是否选中某些单选按钮进行排序。可排序项在 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();
});

我将以下函数附加到单选按钮(ids 前缀为“active_”)onchange,它可以添加或删除 <表行中的 code>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!
}

如果我选择一个单选按钮,该按钮应使先前不可排序的行可排序,它会起作用,并且我可以拖放行。问题是,如果我选择一个单选按钮来创建以前可排序、不可排序的行,我仍然可以拖放它。如果先前可排序,设置器 .sortable("option", "items", "tr:​​not..etc") 不会出现“取消注册”行。我也尝试过 .sortable("refresh") 但没有运气。我已经检查过类属性是否正在通过警报进行更改,确实如此。

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

I have table rows that are sortable depending on whether certain radio buttons are checked or not. The sortables are initialized on document.ready as follows:

$(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();
});

I have the following function attached to the radio buttons (ids prefixed "active_") onchange which either adds or removes the ui-state-disabled class attribute from table rows (dynamic ids prefixed "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!
}

If I select a radio button that should make a previously un-sortable row sortable, it works and I can drag and drop the row. The problem is if I select a radio button to make a row that previously was sortable, un-sortable, I can still drag and drop it. The setter .sortable("option", "items", "tr:not..etc") doesn't appear "un-register" a row if it was previously sortable. I also tried .sortable("refresh") with no luck. And I have checked to see if the class attribute is being changed with an alert and it is.

Any help with this would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

这样的小城市 2024-10-13 07:34:01

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

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

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

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;
}

I ran into the same problem, that the items option doesn't seem to remove items which had been previously enabled.

The cancel option, however, does. Note that the disabled items will shift around to make room for the sortable ones (the spot is still available as a drop target), but dragging the disabled items themselves will not work. Using a disabled class also makes it easy to change the style based on whether or not the item is sortable (see on jsfiddle).

The code here is partially based on Bah Bah the Lamb's answer, but it has been greatly tidied and simplified.

The 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>

The 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");
    }
});

The CSS:

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

.disabled {
  color:#ddd;
}
野鹿林 2024-10-13 07:34:01

我遇到了类似的问题,并找到了一个简单的解决方案(但在我的示例中,我使用的是可排序的 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>

I had a similar problem and found an easy solution (but in my example I am using a sortable ul not a table, as there is more freedom with mark-up in ul's).

The idea behind it is to leave the list and all its items sortable, but remove the handle, thus disabling the individual item's ability to sort, as seen in this code

<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>
眉目亦如画i 2024-10-13 07:34:01

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

为了解决这个问题,我简单地销毁并重新实例化了排序。我改编了 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)"
        });
});

I've been trying to do the same thing. I really wanted the items feature rather than disabled. As pointed out above, there is a weakness in the jQueryUI implementation whereby the sortable don't refresh the items list should the items matched by the selectors change.

To get around this, I simply destroyed and reinstantiated the sortabled. I've adapted Hannele's JSfiddle to demonstrate (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)"
        });
});
唔猫 2024-10-13 07:34:01

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

<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");

试图在开始/停止事件中动态地执行此操作,但这确实有效,不确定“为什么”,所以请好好测试。

I know this is old, but had a similar problem. I had my sortable items in groupings. I wanted certain groups to be sortable anywhere and some to only be sortable to a subsection of groups.

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

Items from noSort can sort anywhere. Items from canSort can only sort into other canSort blocks.

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

Then setting this rule after the init seemed to do the trick.

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

Was trying to do it dynamically in the start/stop events, but this did the trick, not sure "why", so test well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文