2012-10-15 26 views
5

Tiếp theo bài này jQuery table sort (github liên kết: https://github.com/padolsey/jQuery-Plugins/blob/master/sortElements/jquery.sortElements.js), tôi đang sắp xếp thành công cột, tuy nhiên nó không hoạt động trong trường hợp rowspan: Ví dụ, trường hợp như thế nàyjQuery sortColumns plugin: Làm thế nào để sắp xếp một cách chính xác với rowspan

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

Khi tôi bấm vào cột thứ hai, nó cố gắng sắp xếp

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

(kết quả mong đợi nên nó chỉ nên loại trong mỗi rowspan

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

hoặc

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

)

do đó, hoặc mà như bạn có thể thấy là không đúng, xin vui lòng bất kỳ guru jQuery giúp tôi khắc phục vấn đề này. Đây là mã của tôi

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

Câu hỏi:

1.How để tôi sắp xếp này với rowspan. SỐ ROWSPAN KHÔNG PHẢI LÀ MỘT SỐ. Ví dụ trên cả Grape và Apple có rowpan của 2, nhưng điều này không phải luôn luôn như vậy.

2.Có bất kỳ giải thích cú pháp sau:

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

Vì vậy, tôi có thể thấy rằng nếu một trong hai a hoặc b không phải là một con số, sau đó làm chuỗi so sánh nếu không làm được so sánh số lượng, nhưng tôi không hiểu được

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

trường hợp thử nghiệm

<table id="resultsTable"> 
     <thead> 
      <tr> 
       <th>Fruit</th> 
       <th onclick="sortColumn(1)">Quantity</th> 
       <th onclick="sortColumn(2)">Rate</th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td rowspan="4">Grape</td> 
       <td>15</td> 
       <td>5</td> 
      </tr> 
      <tr> 
       <td>4</td> 
       <td>2</td> 
      </tr> 
      <tr> 
       <td>88</td> 
       <td>1</td> 
      </tr> 
      <tr>      
       <td>11</td> 
       <td>3</td> 
      </tr> 
      <tr> 
       <td rowspan="3">Melon</td> 
       <td>21</td> 
       <td>2</td> 
      </tr> 
      <tr> 
       <td>2</td> 
       <td>0</td> 
      </tr> 
      <tr> 
       <td>35</td> 
       <td>1</td> 
      </tr> 
      <tr> 
       <td rowspan="6">Melon</td> 
       <td>24</td> 
       <td>5</td> 
      </tr> 
      <tr> 
       <td>66</td> 
       <td>2</td> 
      </tr> 
      <tr> 
       <td>100</td> 
       <td>4</td> 
      </tr> 
      <tr> 
       <td>21</td> 
       <td>1</td> 
      </tr> 
      <tr> 
       <td>65</td> 
       <td>3</td> 
      </tr> 
      <tr> 
       <td>2</td> 
       <td>0</td> 
      </tr> 
     </tbody> 
<table> 
+0

Kết quả mong đợi là gì? –

+0

@ Newbo.O: Chỉ nên sắp xếp trong mỗi hàng. Tôi đã cập nhật câu hỏi của mình với kết quả mong đợi. –

+0

Chỉ sắp xếp trong một hàng hoặc: ** sắp xếp từng nhóm hàng và sau đó sắp xếp các nhóm theo giá trị đầu tiên **? –

Trả lời

3

điều kiện cho mã để làm việc:

  • Cột chứa td s với rowspan tất cả phải ở bên trái của bảng
  • Tất cả các td s trong các cột phải có một rowspan , ngay cả khi đó là 1
  • Các nhóm hàng để sắp xếp được tạo với phần ngoài cùng bên phải của các cột này (nhưng có thể dễ dàng thay đổi)

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

giải thích nhanh:

  • Tìm tất cả td s với rowspan
  • Positions các td s được lưu, bao gồm trái bù đắp
  • Những td s được lọc bởi gốc offset họ chỉ làm việc với những người ngoài cùng bên phải
  • tr s liên quan đến từng giữ td đều được sắp xếp sử dụng cột truy nã
  • Tất cả td s với rowspan cuối cùng được chuyển trở lại ban đầu của họ vị trí nếu cần thiết

thiệu về câu hỏi 2, tôi sẽ trả lời duy nhất hoàn chỉnh bartlaarhoven bằng cách nói, mã cũng có thể được viết như t anh ấy theo dõi:

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

Bạn có thể dễ dàng đọc rằng inverse được sử dụng để đảo ngược kết quả.

+0

Vì vậy, srry, bởi vì cách tôi vượt qua trong chỉ mục, tôi cần 'index = index + 1', tuy nhiên, trong trường hợp của bạn, hãy lấy nó ra. Ngoài ra, tôi đã sử dụng mã của bạn nhưng bảng bị hỏng, tôi đặt bảng tôi sử dụng để thử nghiệm trong câu hỏi của tôi, bạn có thể xem nó không. Cảm ơn bạn rất nhiều. Tôi cũng đang điều tra nó.Cảm ơn bạn –

+0

Sai lầm của tôi, đôi khi tôi chuyển 'td' vào' thead' ... Tôi đã cập nhật câu trả lời của mình để sửa lỗi đó. Tôi cũng đã tạo một jsfiddle với mẫu dữ liệu của bạn (tôi đã không đặt bất kỳ CSS nào để nó hơi xấu xí nhưng nó hoạt động) –

+0

Cảm ơn bạn, bạn thật tuyệt vời, một điều nữa. Khối mmiddle (khối giữa 'Melon'), phân loại của nó ngược lại với mọi người khác. Bạn có thể xem nó không? Cảm ơn bạn rất nhiều: D –

2

Xét câu 1, hãy thử mã này:

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<str.length; i++){         
       if(!isNaN(str.charAt(i))){ 
        holder += str.charAt(i); 
       } 
      } 
      return holder; 
     }else{ 
      return str; 
     } 
    } 

Xem xét câu hỏi 2; chúng ta hãy khấu trừ nó đến từ đâu. Trước hết, chúng tôi muốn kiểm tra xem a> b, và, như bạn đã thấy chính xác, chúng tôi tạo sự khác biệt giữa so sánh chuỗi và so sánh số.

Chúng tôi sau đó chỉ cần cung cấp cho:

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

này kiểm tra xem a> b (hoặc chuỗi khôn ngoan hoặc số-khôn ngoan) và sau đó trả về 1 trên đúng sự thật và -1 trên sai.

Bây giờ, chúng tôi chèn thông số inverse, sẽ đảo ngược kết quả. Điều này có nghĩa là nếu nghịch đảo == đúng, thì 1 trở thành -1 và -1 trở thành 1. Trong mã, đoạn văn bản in đậm này sẽ thay thế mỗi lần xuất hiện của 1 với inverse ? -1 : 1 và mỗi lần xuất hiện của -1 với inverse ? 1 : -1. Đó là chính xác những gì được thực hiện trong mã kết quả.

CẬP NHẬT: Thêm doRowSpan trong mã vì nó không nên điều chỉnh chỉ số nếu chúng tôi đang trong <tr> chứa rowspan- td.

+0

Cảm ơn bạn rất nhiều. Khi tôi cắm mã của bạn, tôi nhận được lỗi javascript 'Uncaught SyntaxError: Câu lệnh tiếp tục bất hợp pháp'. Bạn có thể kiểm tra, tôi sử dụng 'http: // ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js' –

+0

vì cách tôi chuyển vào chỉ mục, tôi cần index = index + 1, tuy nhiên, trong trường hợp của bạn, hãy lấy nó ra. Ngoài ra, tôi đã sử dụng mã của bạn (không có tiếp tục) nhưng bảng bị hỏng, tôi đặt bảng mà tôi sử dụng để thử nghiệm trong câu hỏi của tôi, bạn có thể xem nó không. Cảm ơn bạn rất nhiều. Tôi cũng đang điều tra nó. Cảm ơn bạn –

Các vấn đề liên quan