2012-06-10 44 views
11

Tôi có một bảng HTML chứa cả ROWSPAN và COLSPAN.Làm cách nào để tìm "vị trí trực quan" của mỗi ô trong bảng bằng cách sử dụng jQuery?

Tôi làm cách nào để tìm "vị trí trực quan" của mỗi ô bằng jQuery?

Ví dụ, đây là một hình ảnh đại diện của bảng của tôi với mỗi tế bào dân với những gì "vị trí thị giác" thuật toán sẽ trả về:
(Lưu ý: Tôi chỉ thực sự quan tâm đến các tế bào trong <tbody> và tham chiếu cột có thể một số nguyên, không phải là một ký tự chữ cái, tôi đã chỉ làm điều này dễ dàng làm nổi bật vấn đề)

+--+--+--+--+--+ 
| |A |B |C |D | 
+--+--+--+--+--+ 
|1 |A1|B1 |D1| 
+--+--+--+--+ + 
|2 |A2 |C2| | 
+--+  +--+ + 
|3 |  |C3| | 
+--+--+--+--+--+ 
|4 |A4|B4|C4|D4| 
+--+--+--+--+--+ 
|XYZ   | 
+--+--+--+--+--+ 

tôi đã cố gắng thực hiện đầu tiên, tuy nhiên các tài liệu tham khảo cho ô C3 là không chính xác vì nó không mất vào tài khoản ROWSPANS. Liên kết thứ hai có thể được hợp nhất vào giải pháp đầu tiên, nhưng tôi không thể tìm ra cách.

Tôi đang hy vọng sẽ sử dụng như là một chức năng gọi là getCellLocation(cell) rằng sẽ trả về một mảng kết hợp trả về vị trí một cái gì đó như thế này:

function getCellLocation(cell) 
{ 
    var row_number = parseInt($(cell).parent().prevAll().length) + 1; 
    var col_number = 1; 
    $(cell).prevAll('td').each(function() { 
     col_number += $(this).attr('colspan') ? parseInt($(this).attr('colspan')) : 1; 
    }); 

    var location = new Array(); 
    location['row'] = row_number; 
    location['col'] = col_number; 
    location['index'] = $('td').index(cell) + 1; 
    return location; 
} 

$('table td').each(function(i){ 
    var cell = getCellLocation($(this)); 
    $(this).prepend('<span class="ref">R' + cell['row'] + ':C' + cell['col'] + ':D' + cell['index'] + '</span>'); 
}); 

Dưới đây là HTML của bảng ví dụ:

<table border="1" cellspacing="0"> 
    <thead> 
    <tr> 
     <th></th> 
     <th>A</th> 
     <th>B</th> 
     <th>C</th> 
     <th>D</th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr> 
     <th>1</th> 
     <td>A1</td> 
     <td colspan="2">B1</td> 
     <td rowspan="3">D1</td> 
    </tr> 
    <tr> 
     <th>2</th> 
     <td rowspan="2" colspan="2">A2</td> 
     <td>C2</td> 
    </tr> 
    <tr> 
     <th>3</th> 
     <td>C3</td> 
    </tr> 
    <tr> 
     <th>4</th> 
     <td>A4</td> 
     <td>B4</td> 
     <td>C4</td> 
     <td>D4</td> 
    </tr> 
    </tbody> 
    <tfoot> 
    <tr> 
     <td colspan="5">XYZ</td> 
    </tr> 
    </tfoot> 
</table> 
<style> span { background-color: #ffc; margin-right: .5em;} </style> 

Trả lời

7

Đây là giải pháp của tôi:

function getCellLocation(cell) { 

    var cols = cell.closest("tr").children("td").index(cell); 
    var rows = cell.closest("tbody").children("tr").index(cell.closest("tr")); 
    var coltemp = cols; 
    var rowtemp = rows; 

    cell.prevAll("td").each(function() { 
     cols += ($(this).attr("colspan")) ? parseInt($(this).attr("colspan")) - 1 : 0; 
    }); 

    cell.parent("tr").prevAll("tr").each(function() { 
     //get row index for search cells 
     var rowindex = cell.closest("tbody").children("tr").index($(this)); 
     // assign the row to a variable for later use 
     var row = $(this); 
     row.children("td").each(function() { 
      // fetch all cells of this row 
      var colindex = row.children("td").index($(this)); 
      //check if this cell comes before our cell 
      if (cell.offset().left > $(this).offset().left) { 
       // check if it has both rowspan and colspan, because the single ones are handled before 
       var colspn = parseInt($(this).attr("colspan")); 
       var rowspn = parseInt($(this).attr("rowspan")); 
       if (colspn && rowspn) { 
        if(rowindex + rowspn > rows) 
        cols += colspn;      
       } 
       if(rowspn && rowindex + rowspn > rows) cols +=1; 
      } 

     }); 
    }); 

Tôi đang kiểm tra các ô có cả colspan và rowspan, vì phần còn lại được xử lý bởi năm dòng đầu tiên của mã này. Nếu các ô có cả hai hàng và colspan, chúng sẽ ảnh hưởng đến các ô khác không nằm dưới OR sang một bên ô này, vì vậy tôi cần phải tìm kiếm các ô trước đó của ô để tương tác.

+0

và đây là jsFiddle của nó: http://jsfiddle.net/bcnEW/ –

+0

Dường như có một vấn đề nhỏ hoặc đếm đôi trong một số tình huống. Xem xét kết quả khi nó được áp dụng cho bảng này (xem ô Col3 Row2): [http://jsfiddle.net/tUn54/](http://jsfiddle.net/tUn54/) – Turgs

+0

cập nhật câu trả lời của tôi và câu đố: http: //jsfiddle.net/bcnEW/1/ –

0

cho bố cục cụ thể này (tức là nếu dòng đầu tiên của bạn không có colspan và nhiều hơn hoặc ít hơn đồng phục tế bào biên giới), bạn có thể làm theo cách này:

function getCellLocation(cell) 
{ 
    var row_number = cell.parentNode.rowIndex; 
    var col_number = ""; 
    $(cell).parents('table').find('tr:first th').each(function() 
    { 
     if (cell.offsetLeft >= this.offsetLeft) 
     { 
      col_number = $(this).text(); 
     } 
     else return false; 
    }); 
    return col_number + row_number; 
} 

nếu bạn muốn cột số thay đổi nó để

var col_number = 0; 
    ... 
if (cell.offsetLeft >= this.offsetLeft) 
{ 
    col_number++; 
} 
0

Đây là giải pháp jQuery có thể xử lý cấu trúc bảng phức tạp. Giải pháp này sử dụng số Open Source WxT Table Parser có sẵn tại đây: https://raw.github.com/wet-boew/wet-boew/master/src/js/dependencies/parserTable.js

Bạn sẽ tìm thấy tài liệu trong số Table Usability Concept Github Repository. Sử dụng tài liệu API nằm trong "Bảng phân tích cú pháp - Bản phát hành WET 3.0".

Các phân tích bảng được thực hiện bằng cách sử dụng các đánh dấu bảng HTML và các mối quan hệ thị giác giữa các tế bào dữ liệu (td) và các tế bào tiêu đề (thứ)

// Used to get the reference to the WxT table parser 
var _pe = window.pe || { 
    fn : {} 
}; 

// For each table elements 
$('table').each(function() { 

    var $tbl = $(this); 

    // Parse the table 
    _pe.fn.parsertable.parse($tbl); 

    // For each data cell 
    $('td', $tbl).each(function() { 

     var $td = $(this), 
      tblparser; 

     // Get the API structure as defined under "Table Parser - WET 3.0 release" (https://github.com/duboisp/Table-Usability-Concept/blob/master/API/td.md#table-parser---wet-30-release) 
     tblparser = $td.data().tblparser; 

     // Set the cell location (x, y) 
     $td.html(tblparser.row.rowpos + ', ' + tblparser.col.start); 


    }); 
}); 

Bạn sẽ tìm thấy một ví dụ làm việc ở đây: http://jsfiddle.net/TVttA/

Cheers

:-)

1
your solution  my proposed table design 
+--+--+--+--+--+  +--+--+--+--+--+ 
| |A |B |C |D |  | |A |B |C |D |  length 5 vs 5 
+--+--+--+--+--+  +--+--+--+--+--+ 
|1 |A1|B1 |D1|  |1 |A1|B1|//|D1| 
+--+--+--+--+ +  +--+--+--+--+--+ 
|2 |A2 |C2| |  |2 |A2|//|C2|//|  length 3 vs 5 
+--+  +--+ +  +--+--+--+--+--+ 
|3 |  |C3| |  |3 |//|//|C3|//| 
+--+--+--+--+--+  +--+--+--+--+--+ 
|4 |A4|B4|C4|D4|  |4 |A4|B4|C4|D4| 
+--+--+--+--+--+  +--+--+--+--+--+ 
|XYZ   |  |XY|//|//|//|//|  length 1 vs 5 
+--+--+--+--+--+  +--+--+--+--+--+ 
// cells labeled '//' above have this class 

td.stuffing { display: none; } 

Bạn có thấy những gì tôi đã làm ở đó không?

Đây là hàng thứ ba, ví dụ:

<tr> 
    <th>2</th> 
    <td rowspan="2" colspan="2">A2</td> 
    <td class="stuffing"></td> 
    <td>C2</td> 
    <td class="stuffing"></td> 
</tr> 

Bây giờ chức năng để lấy chỉ số đúng là rất đơn giản.

function getCellLocation(cell) { 
    return {row:cell.parentNode.rowIndex, cell:cell.cellIndex} 
} 


Và đây là một phần thưởng. Nếu bạn truy cập vào một ô bị ẩn, nó sẽ tự động đi ngang qua một ô chính xác, nằm trên những ô ẩn.

function getSmartCell(table, row, col) { 
    var cell = table.rows[row].cells[col]; 
    if (cell.className.indexOf("stuffing") == -1) return cell; 

    // traverse Left 
    while ((row>0) && (col>0) && (cell.className.indexOf("stuffing") >= 0)) { 
     cell = table.rows[row].cells[--col]; 
    } 

    // roll back one cell if no colSpan is found 
    if (cell.colSpan == 1) cell = table.rows[row].cells[++col]; 

    // traverse Up 
    while ((row>0) && (col>0) && (cell.className.indexOf("stuffing") >= 0)) { 
     cell = table.rows[--row].cells[col]; 
    } 

    return cell; 
} 

Cách sử dụng:

var tb = document.querySelector("table"); 
getCellLocation(getSmartCell(tb,3,2)); // {row: 2, cell: 1} 

ATTENTION Tôi vừa kiểm tra mã của getSmartCell và nó sẽ trả về kết quả sai nếu có hai rowspans láng giềng. Tôi cần phải sửa lỗi này.

Dưới đây là một ví dụ https://jsfiddle.net/goua3m13/

+0

có một lý do có chủ ý tại sao các ô trong đó "được hợp nhất" để span các cột và hàng trong câu hỏi của tôi. Đối với trường hợp sử dụng, nó cần phải theo cách đó và không thể sử dụng các ô trống và ẩn chúng – Turgs

+1

@Turgs Bạn vẫn có thể sử dụng colspans và rowspans trong khi cũng sử dụng các ô ẩn. – Qwerty

+0

Ý tưởng hay. Hiệu suất tốt nhất so với các thuật toán khác !!! –

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