Tengo una lista en mi sitio web. Estoy usando el tutorial clasificable de jQuery para que los usuarios puedan cambiar el orden de los elementos de la lista.
http://jqueryui.com/demos/sortable/
El truco es que me gustaría capturar el orden de los artículos inmediatamente después de un recurso y asignar los valores del pedido a los elementos de formulario ocultos que se pasarían a mi servidor a través de un envío de formulario donde podría usar un script php para guardar el nuevo pedido. de elementos en una base de datos.
Aquí está el código fuente de la demostración:
<style>
#sortable { list-style-type: none; margin: 0; padding: 0; width: 60%; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 18px; }
#sortable li span { position: absolute; margin-left: -1.3em; }
</style>
<script>
$(function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
});
</script>
<div class="demo">
<ul id="sortable">
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 6</li>
<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 7</li>
</ul>
</div><!-- End demo -->
Y soy consciente de que también es posible asignar una función de devolución de llamada que se activa cuando se detiene la clasificación:
$( ".selector" ).sortable({
stop: function(event, ui) { ... }
});
¡Gracias!
mattsven
Escribí una respuesta a esta pregunta hace 5 años, pero esa respuesta apestaba (y esta pregunta tiene casi 38,000 visitas), así que aquí hay una respuesta mejorada.
Hay esencialmente tres partes de esta pregunta que tienes que resolver. Veremos los tres.
Responder a los cambios en el orden de clasificación (Paso 1)
El primer problema que debemos resolver es reaccionar a los cambios en el orden de los elementos ordenados. Si revisamos el Widget Ordenable de jQuery UI documentaciónvemos que tiene un change
event que se activa cada vez que cambia el orden de clasificación y es perfecto para nuestras necesidades.
Nota al margen: mi respuesta original utilizada
stop
en vez dechange
evento.change
es mejor (al menos en este caso) porque informará todos los cambios en la clasificación, ya sea que el cambio haya sido interactivo (usuario) o programático, y solo si el orden realmente ha cambiado. Por otro lado, elsort
El evento solo se activa cuando el usuario deja de ordenar (suelta el mouse o levanta el dedo).
Utilizando el sort
evento, ahora podemos responder a los cambios en la clasificación. Lo siguiente inicializará un Sortable
widget para nosotros, y nos permite configurar una función para que se llame cuando el sort
incluso incendios:
var $sortableList = $("#your-list");
var sortEventHandler = function(event, ui){
console.log("New sort order!");
};
$sortableList.sortable({
stop: sortEventHandler
});
// You can also set the event handler on an already existing Sortable widget this way:
$sortableList.on("sortchange", sortEventHandler);
Una vez hecho esto, ahora estamos listos para dar el paso 2:
Recuperando los elementos ordenados (Paso 2)
Esta parte es bastante simple. Solo necesitamos obtener una matriz de los elementos en nuestra lista ordenada. Para hacer esto, solo podemos pedir a los hijos de los ul
(lista) elemento, usando la función jQuery children()
:
var listElements = $sortableList.children();
console.log(listElements); // [ <li>, <li>, ... ]
Genial, pero necesitamos específicamente los valores del elemento:
var listValues = [];
listElement.forEach(function(element){
listValues.push(element.innerHTML);
});
console.log(listValues); // [ "Item 1", "Item 2", ... ]
Usando .sortable("toArray")
o .serialize()
también son opciones.
¡Agradable! En el bit final.
Serialización y envío del nuevo pedido clasificado (Paso 3)
La serialización es “el proceso de traducir estructuras de datos o el estado del objeto a un formato que se puede almacenar (por ejemplo, en un archivo o búfer de memoria, o transmitir a través de un enlace de conexión de red)” (gracias Wikipedia!)
La forma en que lo haga depende mucho de sus necesidades específicas, por lo que solo analizaremos algunas de las formas en que podría hacerlo usando jQuery.
AJAX:
Si usamos AJAX, podemos enviar una solicitud al servidor con el nuevo pedido. jQuery manejará automáticamente la serialización listValues
para nosotros:
$.post("your-server.com/save_order", { "items": listValues } );
O si prefieres JSON:
$.post("your-server.com/save_order", JSON.encode({ "items": listValues }) );
Forma
Crear un formulario:
<form action="your-server.com/save_order" method="POST">
<input name="items" value="" />
</form>
Actualizar el item
aporte:
var serializedValue = $.param(listValues);
$("#ourForm > input").val(JSON.encode(listValues));
Mándalo:
$("#ourForm").submit()
Respuesta antigua:
HTML:
<form action="save_order.php" method="POST" style="display: none;">
<input name="new_order" value="" type="hidden" />
</form>
JavaScript:
$(".selector").sortable({
stop: function(event, ui) {
var data = "";
$("#sortable li").each(function(i, el){
var p = $(el).text().toLowerCase().replace(" ", "_");
data += p+"="+$(el).index()+",";
});
$("form > [name="new_order"]").val(data.slice(0, -1));
$("form").submit();
}
});
Y en save_order.php, puede analizar la variable POST “new_order” y obtener los pedidos del Artículo 1, Artículo 2, Artículo 3, etc.
-
¿Puede explicar esta respuesta en lugar de simplemente pegar el código?
– Phil
21 de septiembre de 2016 a las 9:08
-
@ Phil_1984_ Reescribí esta respuesta. Avísame si te ayuda.
– mattsven
26/09/2016 a las 22:08
-
Gracias. Su “Paso 2” es la parte que me interesaba (y creo que el OP también). Inicialmente me pareció extraño que el orden de los elementos recién ordenados no estuviera disponible en ninguno de los eventos activados. los documentos oficiales continúe con las posiciones antiguas y nuevas, pero solo como valores de píxeles superiores e izquierdos inútiles. La biblioteca en sí manipula las posiciones de los elementos dentro del DOM por usted, por lo que hacer un simple selector de jquery en el controlador de eventos le dará el nuevo orden.
– Phil
27/09/2016 a las 22:37
-
hola @mattsven, soy nuevo en jquery… ¿puede proporcionar jsfiddel para esto porque tengo dificultades para entenderlo?
– Divyesh Jesadiya
25 de agosto de 2017 a las 9:02
-
¿Con qué partes tienes problemas específicamente?
– mattsven
25/08/2017 a las 11:00
Intenta usar serialize
para formatear una cadena para enviar a la secuencia de comandos de actualización de su base de datos.
Que esto ayude:
alert($( "#sortable" ).sortable( "toArray" ).toSource());
-
Necesitas tener un
id
atributo en suli
s u otro atributo específico comoalert($( "#sortable" ).sortable( "toArray", {attribute: 'data-item_number'} ).toSource());
para que esto funcione.– Lucas primos
25 de marzo de 2015 a las 14:07
-
Respuesta relevante a elementos sin ID: stackoverflow.com/a/15382832/4907950
– Justin
31 de mayo de 2020 a las 21:06
Gediminas
mayo, 2018
Este ejemplo de Javascript le dará toda la lista de DIVS en #sortableContainer cada vez que se realiza la clasificación
<div id="sortableContainer">
<div id="Element1" class="sortIt">Item 1</div>
<div id="Element2" class="sortIt">Item 2</div>
<div id="Element3" class="sortIt">Item 3</div>
<div id="Element4" class="sortIt">Item 4</div>
</div>
JS:
$( function() {
$( "#sortableContainer" ).sortable({
stop: function(event, ui) {
var itemOrder = $('#sortableContainer').sortable("toArray");
for (var i = 0; i < itemOrder.length; i++) {
console.log("Position: " + i + " ID: " + itemOrder[i]);
}
}
});
});
DEMO y Créditos:
http://www.tutorialspark.com/jqueryUI/jQuery_UI_Sortable_Getting_Order_of_Sortable.php
Fácil de resolver:
jQuery_2( function() {
var url="<?php echo base_url(); ?>planner/Planner/edit_status/";
jQuery_2('ul[id^="sort"]').sortable({
connectWith: ".sortable",
/*receive: function (e, ui) {
var status_id = jQuery_2(ui.item).parent(".sortable").data("status-id");
var task_id = jQuery_2(ui.item).data("task-id");
jQuery_2.ajax({
url: url,
method: 'POST',
data: { status_id: status_id, task_id: task_id, },
success: function(response){ }
});
},*/
update: function(e, ui) {
var status_id = jQuery_2(ui.item).parent(".sortable").data("status-id");
var task_id = jQuery_2(ui.item).data("task-id");
var order_id = jQuery_2(ui.item).index();
jQuery_2.ajax({
url: url,
method: 'POST',
data: { status_id: status_id, task_id: task_id, order_id: order_id, },
success: function(response){ }
});
}
}).disableSelection();
} );
var order_id = jQuery_2(ui.item).index(); // Obtener orden
Gana Ramas
Y tu puedes:
jQuery_2( function() {
var url="<?php echo base_url(); ?>planner/Planner/edit_status/";
jQuery_2('ul[id^="sort"]').sortable({
connectWith: ".sortable",
/*receive: function (e, ui) {
var status_id = jQuery_2(ui.item).parent(".sortable").data("status-id");
var task_id = jQuery_2(ui.item).data("task-id");
jQuery_2.ajax({
url: url,
method: 'POST',
data: { status_id: status_id, task_id: task_id, },
success: function(response){ }
});
},*/
update: function(e, ui) {
var status_id = jQuery_2(ui.item).parent(".sortable").data("status-id");
var task_id = jQuery_2(ui.item).data("task-id");
//var order_id = jQuery_2(ui.item).index();
var order_id = [];
$("#sort"+status_id+" li").each(function(index) {
order_id.push($(this).attr('data-task-id'));
});
jQuery_2.ajax({
url: url,
method: 'POST',
data: { status_id: status_id, task_id: task_id, order_id: order_id, },
success: function(response){ }
});
}
}).disableSelection();
} );
usuario1495495
Así es como lo hice Usar el controlador de eventos para capturar el evento de clasificación y luego obtener los valores ordenados a través de la función ToArray y recorrer los valores y asignarlos a la matriz. Esta matriz luego puede pasar a la publicación Ajax
var $sortableList = $("#sortable");
var sortEventHandler = function(event, ui){
var sortedIDs = $( "#sortable" ).sortable( "toArray" );
var listValues = [];
for (var i = 0; i < sortedIDs.length; i++) {
listValues.push(sortedIDs[i]);
}
console.log(listValues);
};
$sortableList.sortable({
stop: sortEventHandler
});
$sortableList.on("sortchange", sortEventHandler);