2

すべてのcolspanおよびrowspan定義に関して、特定のhtmlテーブル構文が正しいかどうかを検証したいと思います。

JSFiddleの例

次の表は構文的に正しいです。

<table id="correct">
    <tr>
        <td>a</td>
        <td>b</td>
        <td rowspan="2">c</td>
    </tr>
    <tr>
        <td colspan="2">d</td>
    </tr>
</table>

列と行の両方が一致していないため、次のテーブルは間違っています。

<table id="wrong1">
    <tr>
        <td>a</td>
        <td>b</td>
        <td rowspan="1">c</td>
    </tr>
    <tr>
        <td colspan="1">d</td>
    </tr>
</table>

テーブルが正しいか間違っているかを検証できるようにしたい。与えられたコードは単なる例であり、複雑さに関係なく、与えられたテーブルで検証する必要があります。

自分でバリデーターを書き始めることもできますが、その前に、ライブラリやすでに機能しているソリューションがあるかどうかを知りたいと思います。これについて私を助けてくれませんか?

/編集

このオンラインバリデーターを見つけました:

http://wet-boew.github.com/wet-boew/demos/tableparser/validator-htmltable.html

私の最初の間違ったテーブル#wrong1はエラーをスローしますが、エラーをスロー#wrong2しません(fiddleを参照)。あまりにも多くの数をサポートしていないようです。

4

2 に答える 2

1

さあ、ここに動作するコードがあります:

function validateTable(id){
    var rows = document.getElementById(id).tBodies[0].rows;
    var totalCells=0;
    // total rows and columns
    var totalRows=rows.length;;
    var totalColumns=0;;
    var foundCells=new Array();    
    var maxRows=rows.length;
    var maxColumns=0;
    var maxCellIndex = 0;
    // First we get totalRows and totalColumns
    for(var i=0;i<rows.length;i++){     
        totalColumns = Math.max(totalColumns,rows[i].cells.length);
    }

    // The matrix now should be totalRows x totalColumns
    for(var i=0;i<totalRows;i++){
        for(var j=0;j<totalColumns;j++){
            maxCellIndex = (i*totalColumns)+j;
            foundCells[ maxCellIndex ] = 0;
        }
    }

    for(var i=0;i<rows.length;i++){     
        maxColumns = Math.max(rows[i].cells.length,maxColumns);
        for(var j = 0;j<rows[i].cells.length;j++){
            var cellPosition = (i*totalColumns)+j;
            var cols=0;
            var tcells=0;
            cols = parseInt( rows[i].cells[j].rowSpan );           
            tcells = parseInt( rows[i].cells[j].colSpan );
            if(tcells>0){
                for(var k=0;k<tcells;k++){
                     foundCells[cellPosition + k] = 1; 
                }
            }
            if(cols > 0){
               for(var k=0;k<cols;k++){
                     foundCells[cellPosition + (k*totalColumns)  ] = 1;
                }
            }
           // totalCells += ( tcells * cols) ;
        }        
    }     
    // This is the updated part
    var allCellsAlignedCorrectly=true;
    for(var n=0;n<=maxCellIndex;n++){        
       if(isNaN(foundCells[n]) || parseInt(foundCells[n]) == 0){
          allCellsAlignedCorrectly = false;
       }
    }
    for(var n=0;n<=foundCells.length;n++){
        if(!isNaN(foundCells[n])){
           totalCells+=foundCells[n];
        }
    }
    // alert(foundCells);
    // alert(totalCells+":"+totalColumns+":"+totalRows);
    return (((totalCells) == (maxRows*maxColumns)) && allCellsAlignedCorrectly);
}

再度更新再度確認

あなたはそれがここで生きているのを見ることができます:

http://jsfiddle.net/UkV35/8/

于 2013-01-26T11:52:35.400 に答える
1

Shehabixの回答に基づいて、バリデーターを書き直しました。主な改善点:

  • すべてのcolspanとrowspanの組み合わせを正しく計算します(うまくいけば)
  • オーバーラップ、テーブルディメンションの外側のセル、および欠落しているセルを検出します
  • 特定のエラーメッセージを出力します

デモ

(出力については、開発者コンソールを参照してください)

JavaScript

function validateTable(id){
    console.log('[validating table #' + id + ']');
    var rows = document.getElementById(id).tBodies[0].rows;
    var hasErrors = false;

    // total rows and columns
    var totalRows = rows.length;
    var totalColumns= 0;
    for(var row=0; row<rows.length; row++) {
        var cells = rows[row].cells;
        var cols = 0;
        for(var col=0; col<cells.length; col++) {
            var cell = rows[row].cells[col];
            var colspan = parseInt(cell.colSpan);
            if(colspan > 1) {
                cols += colspan;
            } else {
                cols++;
            }
        }
        totalColumns = Math.max(totalColumns, cols);
    }

    var cells = {};
    cells.init = function(row, col, options) {
        cells[row + ':' + col] = $.extend({
            row: row,
            col: col,
            count: 0
        }, options);
    }
    cells.update = function(row, col, options) {
        var cell = cells[row + ':' + col];
        if(!cell) {
            hasErrors = true;
            console.log('cell outside of table dimensions (cell ' + (row+1) + ':' + (col+1) + ' is outside of allowed table size ' + totalRows + ':' + totalColumns + ')');
            return;
        }
        cells[row + ':' + col].count++;
        if(options) {
            cells[row + ':' + col] = $.extend(cells[row + ':' + col], options);
        }
    }
    cells.get = function(row, col) {
        return cells[row + ':' + col];
    }

    var colspans = {};
    colspans.add = function(row, col, count) {
        for(var coladd=0; coladd<count; coladd++) {
            colspans[row + ':' + (col+coladd)] = true;
        }
    };
    colspans.check = function(row, col) {
        return colspans[row + ':' + col];
    };

    var rowspans = {};
    rowspans.add = function(row, col, count) {
        for(var rowadd=0; rowadd<count; rowadd++) {
            rowspans[(row+rowadd) + ':' + col] = true;
        }
    };
    rowspans.check = function(row, col) {
        return rowspans[row + ':' + col];
    };

    // init cell matrix
    for(var row=0; row<totalRows; row++) {
        for(var col=0; col<totalColumns; col++) {
            cells.init(row, col);
        }
    }

    for(var row=0; row<rows.length; row++) {
        var colskip = 0;
        var rowskip = 0;
        for(var col=0; col<totalColumns; col++) {
            // check if this cell is pushed by a colspan
            if(colspans.check(row, col)) continue;

            // check if this cell is pushed by a rowspan
            if(rowspans.check(row, col)) {
                rowskip++;
                continue;
            }

            console.log("row: " + row + " - col: " + (col-colskip-rowskip));
            var cell = rows[row].cells[col-colskip-rowskip];
            if(!cell) continue;

            var rowspan = parseInt(cell.rowSpan);
            var colspan = parseInt(cell.colSpan);

            cells.update(row, col, {
                element: cell
            });
            if(colspan > 1){
                colskip += colspan-1;
                colspans.add(row, col+1, colspan-1);
                for(var coladd=1; coladd<colspan; coladd++) {
                    cells.update(row, col+coladd, {
                                 element: cell
                                 });
                }
            }
            if(rowspan > 1){
                rowspans.add(row+1, col, rowspan-1);
                for(var rowadd=1; rowadd<rowspan; rowadd++) {
                    cells.update(row+rowadd, col, {
                                 element: cell
                                 });
                }
            }
        }
    }

    for(var row=0; row<totalRows; row++) {
        for(var col=0; col<totalColumns; col++) {
            var cell = cells.get(row, col);
            if(cell.count == 1) {
                // everything is fine
            } else if(cell.count == 0) {
                hasErrors = true;
                console.log("cell " + (row+1) + ':' + (col+1) + " is missing");
            } else {
                hasErrors = true;
                console.log("cell " + (row+1) + ':' + (col+1) + " is overlapping with rowspan (cell usage count of " + cell.count + ")");
            }
        }
    }

    console.log('table is ' + (hasErrors ? 'invalid' : 'valid'));
    return hasErrors;
}

-

于 2013-01-29T00:37:55.110 に答える