7

このポストjQueryテーブルソート(githubリンク:https ://github.com/padolsey/jQuery-Plugins/blob/master/sortElements/jquery.sortElements.js )に続いて、列を正常にソートしていますが、行スパンの場合:例えばこんな場合

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

2 番目の列をクリックすると、並べ替えが試行されます

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

(期待される結果は、各行スパン内でのみソートする必要があるということです

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

また

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

)

ご覧のとおり、どちらも正しくありません。jQueryの第一人者がこの問題を解決するのを手伝ってください。これが私のコードです

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

質問:

1.これをrowspanでソートするにはどうすればよいですか。ROWSPAN の数は常に同じではありません。上記の例では、Grape と Apple の両方の行スパンが 2 ですが、常にそうとは限りません。

2.この構文を説明できますか:

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

したがって、a または b のいずれかが数値でない場合は文字列比較を行い、それ以外の場合は数値比較を行うことがわかりますが、

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

テストケース

<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>
4

2 に答える 2

3

コードが機能するための条件:

  • を含む列は、すべてテーブルの左側にある必要がありtdますrowspan
  • tdこれらの列のすべての には、たとえ 1 であってもが必要ですrowspan
  • 並べ替える行のグループは、これらの列の右端で作成されます (ただし、簡単に変更できます)。

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

簡単な説明:

  • tdですべての s を見つけるrowspan
  • これらtdの の位置は、左オフセットを含めて保存されます
  • これらtdの はオリジナルによってフィルタリングされoffset、一番右のものだけで機能します
  • tr保持されたそれぞれに関連するは、必要なtd列を使用してソートされます
  • 必要に応じて、すべてtdrowspanが最終的に元の位置に戻されます

質問 2 については、bartlaarhoven の回答を完成させるだけです。コードは次のように書くこともできます。

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

inverse結果を逆にするために使用されていることを簡単に読み取ることができます。

于 2012-10-18T09:34:32.337 に答える
2

質問 1 を考慮して、次のコードを試してください。

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

質問2を考慮してください。それがどこから来たのかを差し引きましょう。まず第一に、a > b かどうかをチェックしたいと思います。そして、すでに正しく見たように、文字列比較と数値比較を区別します。

次に、単純に次のようにします。

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

これは、a > b (文字列または数値のいずれか) かどうかをチェックし、true の場合は 1 を返し、false の場合は -1 を返します。

inverse次に、結果を逆にするパラメーターを挿入します。これは、inverse == true の場合、 1 が -1 になり、-1 が 1 になることを意味します。コードでは、この太字のテキストは、 with の各出現と with の各出現を置き換え1ます。これはまさに結果のコードで行われることです。inverse ? -1 : 1-1inverse ? 1 : -1

UPDATE : rowspan- が含まれているdoRowSpan場合、インデックスを適応させないため、コードに追加されました。<tr>td

于 2012-10-17T19:04:12.013 に答える