使用 jQuery Sortables 拖动项目时单选按钮被取消选择

Posted

技术标签:

【中文标题】使用 jQuery Sortables 拖动项目时单选按钮被取消选择【英文标题】:Radio Buttons getting deselected when dragging item using jQuery Sortables 【发布时间】:2010-09-22 01:18:05 【问题描述】:

我正在使用jQuery UI sortables 插件来允许对某些列表项进行重新排序。在每个列表项中,我都有几个单选按钮,可以启用或禁用该项目。

当项目被拖动时,两个单选按钮都会被取消选择,这似乎不应该发生。这是正确的行为吗?如果不是,解决此问题的最佳方法是什么?

以下是演示此问题的代码示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>jQuery Sortables Problem</title>
    <script src="jquery-1.2.6.min.js" type="text/javascript"></script>
    <script src="jquery-ui.min.js" type="text/javascript"></script>

    <style type="text/css">
        .items
        
          margin-top: 30px;
          margin-left: 0px;
          padding-left: 25px;
          cursor: move;
        
        .items li
        
          padding: 10px;
          font-size: 15px;
          border: 1px solid #666;
          background: #eee;
          width: 400px;
          margin-bottom: 15px;
          float: left;
          clear:both;
        
    </style>

</head>
<body>

<ol id="itemlist" class="items"> 
    <li id="1" class="item">
        Item 1
        <input name="status_1" type="radio" value="1" checked="checked" />enabled
        <input name="status_1" type="radio" value="0" />disabled
    </li> 
    <li id="2" class="item">
        Item 2
        <input name="status_2" type="radio" value="1" checked="checked" />enabled
        <input name="status_2" type="radio" value="0" />disabled
    </li> 
    <li id="3" class="item">
        Item 3
        <input name="status_3" type="radio" value="1" checked="checked" />enabled
        <input name="status_3" type="radio" value="0" />disabled
    </li> 
    <li id="4" class="item">
        Item 4
        <input name="status_4" type="radio" value="1" checked="checked" />enabled
        <input name="status_4" type="radio" value="0" />disabled
    </li> 
</ol>

<script type="text/javascript">
    $('#itemlist').sortable();
</script>

</body>
</html>

只要用鼠标抓住一个列表项,两个单选按钮就会被取消选择。

如果这是一个错误,一种解决方法是在移动项目时自动选择“启用”单选按钮,因此任何关于如何实现这一点的建议也将不胜感激。

更新:我已经在 FireFox 3、Internet Explorer 7、Opera 9.5 和 Safari 3.1.2 以及 Windows XP x64 上对此进行了测试,所有这些都出现了这个问题。

【问题讨论】:

【参考方案1】:

它可能不是您想要的,但正在改变

$('#itemlist').sortable();

$('#itemlist').sortable(placeholder: ".items li");

保留单选按钮选择。

【讨论】:

在 FF3、IE7 和 Chrome 中试用过,效果相同。单选按钮被清除(FF 和 chrome)或重置(IE7) 看起来这取决于您的 jquery.ui 版本。当我使用 1.5.2 时,我得到了与你相同的结果,但我在 1.6rc2 中得到了相反的结果(在 FF 中清除单选按钮,使用助手清除 chrome 并使用占位符持久化。) IE 似乎对我不起作用要么。 你是对的。在 1.6rc2 中,默认是在占位符中复制元素 innerHtml。将占位符选项设置为任何非空字符串会覆盖此行为。【参考方案2】:

更新:这适用于 jQuery.ui 1.5.2。如果您使用的是 1.6rc2,请尝试 Ben Koehler 解决方案。


似乎 sortables 插件克隆了正在移动的节点。如果我们使用 $('#itemlist li').clone().appendTo("#itemlist"); 克隆节点,我们会看到类似的行为,因为现在有 4 个同名的单选按钮,而不是两个。

您可以使用 helper 选项覆盖 sortables 插件的工作方式。试试这个:

$('#itemlist').sortable(helper: function()
    return $("<li>").css(border: "1px solid red", background: "transparent").appendTo("#itemlist")[0];
);

我们正在创建一个没有单选按钮的新节点并将其附加到列表中。这个新节点将是动画节点。 此代码在 FF3 和 Chrome 中运行良好,但 IE7 不断将单选按钮重置为其默认状态。

【讨论】:

【参考方案3】:

这是在 Internet Explorer 中吗?众所周知,IE 在复制/移动时会丢失复选框和单选框的选择。

http://webbugtrack.blogspot.com/2007/11/bug-299-setattribute-checked-does-not.html

需要重置 defaultChecked IE 才能正常工作

【讨论】:

【参考方案4】:

单选按钮失去其状态的某种答案在这里 http://core.trac.wordpress.org/ticket/16972#comment:4

这是一个有点长的路,但只有这样我才能找到在被拖到某个地方后重新做单选按钮状态的方法

【讨论】:

【参考方案5】:

我遇到了很多相同的问题,但我在这里找到了解决方案: http://fiddyp.co.uk/how-to-fix-radio-inputs-losing-focus-when-dragging-a-jquery-ui-sortable-div/ 这似乎允许我拖放表格行,并且单选按钮保持正确。

// global script for commentluv premium settings pages
// workaround for bug that causes radio inputs to lose settings when meta box is dragged.
// http://core.trac.wordpress.org/ticket/16972
jQuery(document).ready(function()
    // listen for drag drop of metaboxes , bind mousedown to .hndle so it only fires when starting to drag
    jQuery('.hndle').mousedown(function()
        // set event listener for mouse up on the content .wrap and wait a tick to give the dragged div time to settle before firing the reclick function
        jQuery('.wrap').mouseup(function()store_radio(); setTimeout('reclick_radio();',50););
    )
);
/**
* stores object of all radio buttons that are checked for entire form
*/
function store_radio()
    var radioshack = ;
    jQuery('input[type="radio"]').each(function()
        if(jQuery(this).is(':checked'))
            radioshack[jQuery(this).attr('name')] = jQuery(this).val();
        
        jQuery(document).data('radioshack',radioshack);
    );

/**
* detect mouseup and restore all radio buttons that were checked
*/
function reclick_radio()
    // get object of checked radio button names and values
    var radios = jQuery(document).data('radioshack');
    //step thru each object element and trigger a click on it's corresponding radio button
    for(key in radios)
        jQuery('input[name="'+key+'"]').filter('[value="'+radios[key]+'"]').trigger('click');
    
    // unbind the event listener on .wrap  (prevents clicks on inputs from triggering function)
    jQuery('.wrap').unbind('mouseup');

【讨论】:

【参考方案6】:

作为 Randy,我发现的最佳解决方案是将选中的属性存储在另一个属性中,然后在移动后将选中的属性返回到无线电输入。我以一种更简单的方式做到了这一点,使用可排序的开始和停止参数,如下所示。

// First, create a function to store the properties.

// Store the checked radio properties
    function gravaSelecoes() 
      $("tbody.linhasConf").find("input:radio").each(function () 
        if ($(this).prop("checked"))
          $(this).attr("data-checked", "true");
        else
          $(this).attr("data-checked", "false");
      );
    

// Then, create a function that restore the properties

// Restore the checked radio properties
    function atualizaSelecoes() 
      $("tbody.linhasConf").find("input:radio").each(function () 
        if ($(this).attr("data-checked") == "true")
          $(this).prop("checked", true);
        else
          $(this).prop("checked", false);
      );
    

// And when declaring sortables, refer to those functions

    $('tbody.linhasConf').sortable(
      start: gravaSelecoes,
      stop: atualizaSelecoes
    ).disableSelection();

罗德里戈

【讨论】:

以上是关于使用 jQuery Sortables 拖动项目时单选按钮被取消选择的主要内容,如果未能解决你的问题,请参考以下文章

Javascript(jQuery)在拖动项目时禁用页面滚动

滚动可拖动项目的内容时禁用jQuery拖动

JQuery可拖动:使用助手时滚动不起作用:使用克隆

使用jQuery可拖动将项目拖动到可滚动的div之外

jquery可拖动隐藏内容

如何使用 jQuery 将可拖动项目居中放置在可放置的图像地图区域上?