6

Estoy usando el complemento jQuery UI sortables para permitir el reordenamiento de algunos elementos de la lista. Dentro de cada elemento de la lista, tengo un par de botones de opción que permiten activar o desactivar el elemento.Botones de radio que se anulan al arrastrar elementos usando jQuery Sortables

Cuando se arrastra el elemento, se anula la selección de ambos botones de radio, lo que no parece que deba suceder. ¿Es este comportamiento correcto, y si no, cuál es la mejor manera de evitar esto?

Este es un ejemplo de código que muestra este problema:

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

Tan pronto como un elemento de la lista se agarró con el ratón, tanto los botones de radio desmarcará.

Si se trata de un error, una solución alternativa sería seleccionar automáticamente el botón de opción 'activado' cuando se mueve el elemento, por lo que cualquier consejo sobre cómo lograr esto también sería muy apreciado.

Actualización: He probado esto en FireFox 3, Internet Explorer 7, Opera 9.5 y Safari 3.1.2, todo en Windows XP x64, y este problema ocurre en todos ellos.

Respuesta

1

Puede que no sea exactamente lo que está buscando, pero cambiando

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

a

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

mantiene las selecciones del botón de radio.

+0

juzgado en FF3, IE7 y Chrome y funciona de la misma. Los botones de radio se borran (FF y cromo) o se reinician (IE7) – Serxipc

+0

Parece que depende de su versión de jquery.ui. Obtuve los mismos resultados que cuando uso 1.5.2, pero obtengo exactamente lo opuesto con 1.6rc2 (los botones de radio se borran en FF y Chrome usando helper y persisten usando marcador de posición). IE no parece funcionar de ninguna manera para mí ya sea. –

+0

Tienes razón. Con 1.6rc2, el valor predeterminado es copiar el elemento innerHtml en el marcador de posición. Establecer la opción de marcador de posición a cualquier cadena no vacía anula este comportamiento. – Serxipc

1

ACTUALIZACIÓN: Esto se aplica a jQuery.ui 1.5.2. Si está utilizando 1.6rc2 intente con la solución de Ben Koehler.


Parece que el complemento ordenable clona el nodo que se está moviendo. Si clonamos los nodos usando $('#itemlist li').clone().appendTo("#itemlist"); veremos un comportamiento similar, porque ahora hay 4 botones de opción con el mismo nombre, en lugar de dos.

Puede anular la manera en que el complemento ordenable funciona con la opción de ayuda. Pruebe esto:

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

Estamos creando un nuevo nodo sin botones de opción y anexándolo a la lista. Este nuevo nodo será el animado.
Este código funciona bien en FF3 y Chrome, pero IE7 sigue restableciendo los botones de radio a su estado predeterminado.

0

I estaba teniendo muchos de los mismos problemas, pero encontré una solución aquí: http://fiddyp.co.uk/how-to-fix-radio-inputs-losing-focus-when-dragging-a-jquery-ui-sortable-div/ Esto parece permitirme arrastrar y soltar las filas de la tabla, y los botones de radio permanecen en su lugar correctamente.

// 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'); 
} 
0

Como Randy, la mejor solución que encontré fue para almacenar la propiedad de control en otro atributo y, a continuación, después del movimiento devolver la característica sea comprobada a la entrada de radio. Lo hice de una manera más simple, usando los parámetros de inicio y parada ordenables, como sigue.

// 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(); 

Rodrigo

Cuestiones relacionadas