0

Javascriptを使用してテーブルをソートする次のコードがあります。私がしたいのは、合計のテーブルの最後の行を作成することです。したがって、コードを追加して、最後の行を並べ替えから削除する必要があります。このタスクに問題があります。

var TableSort = function ( tableId ) {
    var that = this;

    // Store a reference to the table node as a property
    this.table = document.getElementById(tableId);

    // Validate the table node
    if ( this.table && this.table.nodeType != 1 ) {
        throw new Error("TableSort: Table id is not a DOM element.");
    }
    if ( this.table.tagName != "TABLE" ) {
        throw new Error("TableSort: Table id is not a table element.");
    }

    // Set three global properties
    this.sortColumn = "";
    this.sortUp = true;
    this.imageNodes = [];


    // Get the header nodes
    var headers = this.table.getElementsByTagName("th");

    // Loop through the header nodes
    var header, columnName, imageNode, imageClick;
    for ( var i = 0; i < headers.length; i++) {
        header = headers[i];

        // Create a node for the image
        imageNode = document.createElement("img");

        // Add the "sort arrow" images to the header column
        // And set the first column as the default sort column
        columnName = header.className;
        if ( i == 0 ) {
            this.sortColumn = columnName;
            imageNode.src = "arrows_up.png";
        } else {
            imageNode.src = "arrows_off.png";
        }

        // Get the event handler for the image
        imageClick = this.imageClickHandler(columnName);

        // Add the event handler to the image
        jsLib.event.add(imageNode, "click", imageClick);

        // Add the image node to column header and to array of image nodes
        header.appendChild(imageNode);
        this.imageNodes[columnName] = imageNode;
    }

    // Sort the table
    this.sort();
}

TableSort.prototype.imageClickHandler = function (columnName) {
    var that = this;

    // return an event handler
    return function () {
        // If current sort column, toggle the sort direction
        if ( that.sortColumn == columnName ) {
            that.sortUp = ! that.sortUp;
        // Otherwise...
        } else {
            // Set the image for the old sort column
            that.imageNodes[that.sortColumn].src = "arrows_off.png";

            // Switch the current sort column and sort ascending
            that.sortColumn = columnName;
            that.sortUp = true;
        }

        // Set the appropriate arrows for the current sort column
        if ( that.sortUp ) {
            that.imageNodes[that.sortColumn].src = "arrows_up.png";
        } else {
            that.imageNodes[that.sortColumn].src = "arrows_down.png";
        }

        that.sort();
    }
}

TableSort.prototype.sort = function () {
    var that = this;
    if ( this.sortColumn == "" ) return;

    // Get the rows from the table
    var rowNodes = this.table.getElementsByTagName("tr");
    if (rowNodes.length <= 1 ) return;

    // Store a reference to each row in the rows array
    var rows = [];
    for ( var i = 0; i < rowNodes.length; i++) {
        rows.push( rowNodes[i] );
    }

    // Get a reference to the tbody node
    var tbodyNode = rows[0].parentNode;

    // Remove the header row from the array (but not the DOM)
    rows.shift();



    // Remove all rows except the header row from the DOM
    var row;
    for ( i = 0; i < (rows.length); i++ ) {
        row = rows[i];
        row.parentNode.removeChild(row);
    }   

    // Define two functions that check for data types
    var isMoney = function ( value ) {
        var m = value.replace( /[$,]/g, "" );
        return ! isNaN(m);
    }
    var isDate = function ( value ) {
        var d = new Date(value);
        return ! isNaN(d);
    }

    // Define the direction variable
    var direction = ( that.sortUp ) ? 1 : -1;

    // Define the function that compares the rows
    var compareColumnValues = function (rowA, rowB) {
        var valueA, valueB;
        var i, cell;

        // Get the cell value for row A
        var cellsA = rowA.getElementsByTagName("td");
        for ( i = 0; i < cellsA.length; i++ ) {
            cell = cellsA[i];
            if ( cell.className == that.sortColumn ) {
                valueA = cell.firstChild.nodeValue;
                break;
            }
        }

        // Get the cell value for row B
        var cellsB = rowB.getElementsByTagName("td");
        for ( i = 0; i < cellsB.length; i++ ) {
            cell = cellsB[i];
            if ( cell.className == that.sortColumn ) {
                valueB = cell.firstChild.nodeValue;
                break;
            }
        }

        // Convert the values to the appropriate data type
        if ( ! isNaN(valueA) && ! isNaN(valueB) ) {
            valueA = parseFloat(valueA);
            valueB = parseFloat(valueB);
        } else if ( isDate(valueA) && isDate(valueB) ) {
            valueA = new Date(valueA);
            valueB = new Date(valueB);
        } else if ( isMoney(valueA) && isMoney(valueB) ) {
            valueA = parseFloat(valueA.replace( /[$,]/g, "" ));
            valueB = parseFloat(valueB.replace( /[$,]/g, "" ));
        }

        // Compare the two values and return the appropriate comparison value
        if ( valueA < valueB ) {
            return -1 * direction;
        } else if ( valueB < valueA ) {
            return 1 * direction;
        } else {
            return 0;
        }
    }

    // Use the compareColumnValues function to sort the rows array
    rows.sort( compareColumnValues );

    // Add all rows back to the DOM
    for ( i = 0; i < rows.length; i++) {
        tbodyNode.appendChild( rows[i] );
    }
}
4

2 に答える 2

4

HTML マークアップでもう少し構造を使用して、ソートできるものをコードが把握できるようにすることができます。

合計行をtfoot要素に入れ、並べ替え可能な行をtbody要素に入れます...これで、並べ替え可能な行をターゲットにすることができます。

var sortableRows = this.table.getElementsByTagName('tbody'),
    rowNodes = sortableRows.getElementsByTagName('tr');

更新:マークアップを変更できないため、並べ替え配列から最後の行を削除してキャッシュします。

...
// Remove the header row from the array (but not the DOM)
rows.shift();
// And now we remove the footer row and cache it
var footerRow = rows.pop();

次に、ソートされた行を DOM に書き戻すようにコードを変更します。insertBefore

...
// Add all rows back to the DOM, before the footer row
for ( i = 0; i < rows.length; i++) {
    tbodyNode.insertBefore(rows[i], footerRow);
}

DOM に複数の書き込みを行っているため、このループは実際には少しパフォーマンスの問題です。次のように、ソートされたすべてのノードを adocumentFragmentに書き込み、DOM に 1 回だけ書き込む方がよいでしょう。

...
var sortedFragment = document.createDocumentFragment();

// Write all the sorted rows to a fragment
for ( i = 0; i < rows.length; i++) {
    sortedFragment.appendChild(rows[i]);
}

// Insert fragment containing sorted rows before footer
tbodyNode.insertBefore(sortedFragment, footerRow);
于 2013-04-23T00:17:11.763 に答える
2

仕事のコードで実際に使用した優れたソリューションを見つけました。しかし、私はそれを信用することはできませんが、正しい方向に皆さんを向けたかっただけです:

http://www.kryogenix.org/code/browser/sorttable/

"1. ここから Javascript ライブラリをダウンロードしてください: http://www.kryogenix.org/code/browser/sorttable/sorttable.js

2. 次のように、ページの HEAD に Javascript ライブラリへのリンクを配置して、Javascript ライブラリを含めます。

3.「ソート可能」のクラスを指定して、テーブルをソート可能としてマークします。

ライブラリの JavaScript ファイルは sorttable (2 つの T) と呼ばれますが、テーブルに追加するクラスは sortable (1 つの T) であることに注意してください。」

セットアップは非常に簡単で、昇順と降順の両方の並べ替えが可能です。ご不明な点がございましたら、お知らせください。

ありがとう!ポール

于 2013-11-19T13:28:23.690 に答える