jQuery sortColumns plugin: cómo ordenar correctamente con rowspan

Siguiendo esta clasificación de la tabla jQuery de entrada (github link: https://github.com/padolsey/jQuery-Plugins/blob/master/sortElements/jquery.sortElements.js ), estoy ordenando columnas con éxito, sin embargo, no funciona en el caso de rowspan: por ejemplo, caso como este

Grape 3,096,671M 1,642,721M Apple 2,602,750M 3,122,020M 

Cuando hago clic en la segunda columna, bash ordenar

  Apple 2,602,750M 1,642,721M Grape 3,096,671M 3,122,020M 

( El resultado esperado debería ser que solo debe clasificarse dentro de cada rowspan

  Grape 1,642,721M 3,096,671M Apple 2,602,750M 3,122,020M 

o

  Grape 3,096,671M 1,642,721M Apple 3,122,020M 2,602,750M 

)

entonces cualquiera de los dos puede ser incorrecto, cualquier jQuery gurú me ayuda a solucionar este problema. Aquí está mi código

 var inverse = false; function sortColumn(index){ index = index + 1; var table = jQuery('#resultsTable'); table.find('td').filter(function(){ return jQuery(this).index() == index; }).sortElements(function(a, b){ a = convertToNum($(a).text()); b = convertToNum($(b).text()); return ( isNaN(a) || isNaN(b) ? a > b : +a > +b ) ? inverse ? -1 : 1 : inverse ? 1 : -1; },function(){ return this.parentNode; }); inverse = !inverse; } function convertToNum(str){ if(isNaN(str)){ var holder = ""; for(i=0; i<str.length; i++){ if(!isNaN(str.charAt(i))){ holder += str.charAt(i); } } return holder; }else{ return str; } } 

Pregunta:

1. Cómo puedo ordenar esto con rowspan. EL NÚMERO DE ROWSPAN NO ES SIEMPRE EL MISMO . El ejemplo anterior, tanto Grape como Apple tienen rowspan de 2, pero este no es siempre el caso.

2. ¿Puede alguno explicar esta syntax?

  return ( isNaN(a) || isNaN(b) ? a > b : +a > +b ) ? inverse ? -1 : 1 : inverse ? 1 : -1; 

Entonces, puedo ver que si a o b no es un número, entonces la comparación de cadenas de hecho hace la comparación de números, pero no entiendo el

 inverse ? -1 : 1 : inverse ? 1 : -1; 

Casos de prueba

 
Fruit Quantity Rate
Grape 15 5
4 2
88 1
11 3
Melon 21 2
2 0
35 1
Melon 24 5
66 2
100 4
21 1
65 3
2 0

Condiciones para que el código funcione:

  • Las columnas que contienen td s con rowspan deben estar todas a la izquierda de la tabla
  • Todas las td s en estas columnas deben tener un rowspan , incluso si es 1
  • Los grupos de filas para ordenar se hacen con la derecha de estas columnas (pero se puede cambiar fácilmente)

jsFiddle: http://jsfiddle.net/5GrAC/77/

 var inverse = false; function sortColumn(index) { var trs = $('#resultsTable > tbody > tr'), nbRowspans = trs.first().children('[rowspan]').length, offset = trs.first().children('[rowspan]').last().offset().left; var tds = trs.children('[rowspan]').each(function() { $(this).data('row', $(this).parent().index()); $(this).data('column', $(this).index()); $(this).data('offset', $(this).offset().left) }).each(function() { if($(this).data('offset') != offset) return; var rowMin = $(this).data('row'), rowMax = rowMin + parseInt($(this).attr('rowspan')); trs.slice(rowMin, rowMax).children().filter(function() { return $(this).index() == index + $(this).parent().children('[rowspan]').length - nbRowspans; }).sortElements(function(a, b) { a = convertToNum($(a).text()); b = convertToNum($(b).text()); return ( isNaN(a) || isNaN(b) ? a > b : +a > +b ) ? inverse ? -1 : 1 : inverse ? 1 : -1; }, function() { return this.parentNode; }); }); var trs = $('#resultsTable > tbody > tr'); tds.each(function() { if($(this).parent().index() != $(this).data('row')) $(this).insertBefore(trs.eq($(this).data('row')).children().eq($(this).data('column'))); }); inverse = !inverse; } 

Explicaciones rápidas:

  • Encontrar todas las td con rowspan
  • Se guardan las posiciones de estas td , incluido el desplazamiento a la izquierda
  • Estas td s están filtradas por su offset original para que funcionen solo con las más a la derecha
  • tr relacionados con cada td guardado se ordenan usando la columna deseada
  • Todas las td s con rowspan finalmente vuelven a su posición original si es necesario

Sobre la pregunta 2, solo completaré la respuesta de bartlaarhoven diciendo que el código también se puede escribir como el siguiente:

 return ( (isNaN(a) || isNaN(b) ? a > b : +a > +b) ? 1 : -1 ) * (inverse ? -1 : 1); 

Puede leer fácilmente que el inverse se usa para invertir el resultado.

Teniendo en cuenta la pregunta 1, prueba este código:

 var inverse = false; var curRowSpan = 0; var curIndex = 0; var doRowSpan = false; function sortColumn(index){ index = index + 1; var table = jQuery('#resultsTable'); table.find('td').filter(function() { var result = false; // if it is a column before the sorting column, watch the rowSpan if (curRowSpan == 0 && jQuery(this).index() < index && jQuery(this).attr("rowspan") > 1) { curRowSpan = jQuery(this).attr("rowspan"); doRowSpan = true; // we are not in the sorting column so we can safely continue continue; } if(!doRowSpan) curIndex = index - (curRowSpan?1:0); else curIndex = index; if(jQuery(this).index() == curIndex) { // we are at the sorting column if(curRowSpan > 0) { curRowSpan--; } // set this to false for the following row doRowSpan = false; result = true; } return result; }).sortElements(function(a, b){ a = convertToNum($(a).text()); b = convertToNum($(b).text()); return ( isNaN(a) || isNaN(b) ? a > b : +a > +b ) ? inverse ? -1 : 1 : inverse ? 1 : -1; },function(){ return this.parentNode; }); inverse = !inverse; } function convertToNum(str){ if(isNaN(str)){ var holder = ""; for(i=0; i 

Considerando la pregunta 2; vamos a deducir de dónde viene. En primer lugar, nos gustaría comprobar si a> b, y, como ya has visto correctamente, hacemos una diferencia entre la comparación de cadenas y la comparación de números.

Entonces simplemente daríamos:

 return ( isNaN(a) || isNaN(b) ? a > b : +a > +b ) ? 1 : -1; 

Esto verifica si a> b (ya sea en forma de cadena o de número) y luego devuelve 1 en verdadero y -1 en falso.

Ahora insertamos el parámetro inverse , que debe invertir el resultado. Esto significa que si inversa == verdadero, entonces 1 se convierte en -1 y -1 se convierte en 1 . En el código, ¿esta pieza de texto audaz reemplazaría cada ocurrencia de 1 con inverse ? -1 : 1 inverse ? -1 : 1 y cada ocurrencia de -1 con inverse ? 1 : -1 inverse ? 1 : -1 . Que es exactamente lo que se hace en el código resultante.

ACTUALIZACIÓN : se agregó doRowSpan en el código porque no debe adaptarse al índice si estamos en el

que contiene el rowspan- td .