admin管理员组文章数量:1023538
Following this post jQuery table sort (github link: .sortElements.js), I am successfully sort columns, however it does not work in the case of rowspan: For example, case like this
Grape 3,096,671M
1,642,721M
Apple 2,602,750M
3,122,020M
When I click on the second column, it try to sort
Apple 2,602,750M
1,642,721M
Grape 3,096,671M
3,122,020M
(Expected result should be that it should only sort within each rowspan
Grape 1,642,721M
3,096,671M
Apple 2,602,750M
3,122,020M
or
Grape 3,096,671M
1,642,721M
Apple 3,122,020M
2,602,750M
)
so either which as you can see is not correct, please any jQuery guru help me fix this problem. Here is my code
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;
}
}
Question:
1.How do I sort this with rowspan. THE NUMBER OF ROWSPAN IS NOT ALWAYS THE SAME. The above example both Grape and Apple have rowspan of 2, but this is not always the case.
2.Can any explain this syntax:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
So I can see that if either a or b is not a number, then do string parison otherwise do number parison, but I dont understand the
inverse ? -1 : 1 :
inverse ? 1 : -1;
Test cases
<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>
Following this post jQuery table sort (github link: https://github./padolsey/jQuery-Plugins/blob/master/sortElements/jquery.sortElements.js), I am successfully sort columns, however it does not work in the case of rowspan: For example, case like this
Grape 3,096,671M
1,642,721M
Apple 2,602,750M
3,122,020M
When I click on the second column, it try to sort
Apple 2,602,750M
1,642,721M
Grape 3,096,671M
3,122,020M
(Expected result should be that it should only sort within each rowspan
Grape 1,642,721M
3,096,671M
Apple 2,602,750M
3,122,020M
or
Grape 3,096,671M
1,642,721M
Apple 3,122,020M
2,602,750M
)
so either which as you can see is not correct, please any jQuery guru help me fix this problem. Here is my code
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;
}
}
Question:
1.How do I sort this with rowspan. THE NUMBER OF ROWSPAN IS NOT ALWAYS THE SAME. The above example both Grape and Apple have rowspan of 2, but this is not always the case.
2.Can any explain this syntax:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
So I can see that if either a or b is not a number, then do string parison otherwise do number parison, but I dont understand the
inverse ? -1 : 1 :
inverse ? 1 : -1;
Test cases
<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>
Share
Improve this question
edited May 23, 2017 at 10:28
CommunityBot
11 silver badge
asked Oct 15, 2012 at 15:30
Thang PhamThang Pham
38.7k79 gold badges208 silver badges289 bronze badges
2
- @Newbo.O: It should only sort within each rowspan. I have updated my question with expected result. – Thang Pham Commented Oct 18, 2012 at 0:47
- Sort only within a rowspan or: sort each rowspan group and then sort groups according to first value? – Robert Koritnik Commented Oct 19, 2012 at 11:38
2 Answers
Reset to default 3 +500Conditions for the code to work:
- Columns containing
td
s withrowspan
must all be on the left of the table - All the
td
s in these columns must have arowspan
, even if it's 1 - The groups of rows to sort are made with the rightmost of these columns (but it can easily be changed)
jsFiddle: http://jsfiddle/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;
}
Quick explanations:
- Finding all
td
s withrowspan
- Positions of these
td
s are saved, including left offset - These
td
s are filtered by their originaloffset
to work only with the rightmost ones tr
s related to each kepttd
are sorted using the wanted column- All
td
s withrowspan
are finally moved back to their original position if necessary
About question 2, I will only plete bartlaarhoven's answer by saying, the code can also be written like the following:
return (
(isNaN(a) || isNaN(b) ? a > b : +a > +b) ? 1 : -1
) * (inverse ? -1 : 1);
You can easily read that inverse
is used to inverse the result.
Considering question 1, try this code:
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;
}
}
Considering question 2; let's deduct where it es from. First of all we would like to check whether a > b, and, as you already saw correctly, we make a difference between string parison and number parison.
We would then simply give:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ? 1 : -1;
This checks whether a > b (either string-wise or number-wise) and then returns 1 on true and -1 on false.
Now we insert the inverse
parameter, which should inverse the result. This means that if inverse == true, then 1 bees -1 and -1 bees 1. In code, this bold piece of text would replace each occurrence of 1
with inverse ? -1 : 1
and each occurrence of -1
with inverse ? 1 : -1
. Which is exactly what is done in the resulting code.
UPDATE: Added doRowSpan
in the code because it should not adapt the index if we are in the <tr>
that contains the rowspan-td
.
Following this post jQuery table sort (github link: .sortElements.js), I am successfully sort columns, however it does not work in the case of rowspan: For example, case like this
Grape 3,096,671M
1,642,721M
Apple 2,602,750M
3,122,020M
When I click on the second column, it try to sort
Apple 2,602,750M
1,642,721M
Grape 3,096,671M
3,122,020M
(Expected result should be that it should only sort within each rowspan
Grape 1,642,721M
3,096,671M
Apple 2,602,750M
3,122,020M
or
Grape 3,096,671M
1,642,721M
Apple 3,122,020M
2,602,750M
)
so either which as you can see is not correct, please any jQuery guru help me fix this problem. Here is my code
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;
}
}
Question:
1.How do I sort this with rowspan. THE NUMBER OF ROWSPAN IS NOT ALWAYS THE SAME. The above example both Grape and Apple have rowspan of 2, but this is not always the case.
2.Can any explain this syntax:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
So I can see that if either a or b is not a number, then do string parison otherwise do number parison, but I dont understand the
inverse ? -1 : 1 :
inverse ? 1 : -1;
Test cases
<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>
Following this post jQuery table sort (github link: https://github./padolsey/jQuery-Plugins/blob/master/sortElements/jquery.sortElements.js), I am successfully sort columns, however it does not work in the case of rowspan: For example, case like this
Grape 3,096,671M
1,642,721M
Apple 2,602,750M
3,122,020M
When I click on the second column, it try to sort
Apple 2,602,750M
1,642,721M
Grape 3,096,671M
3,122,020M
(Expected result should be that it should only sort within each rowspan
Grape 1,642,721M
3,096,671M
Apple 2,602,750M
3,122,020M
or
Grape 3,096,671M
1,642,721M
Apple 3,122,020M
2,602,750M
)
so either which as you can see is not correct, please any jQuery guru help me fix this problem. Here is my code
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;
}
}
Question:
1.How do I sort this with rowspan. THE NUMBER OF ROWSPAN IS NOT ALWAYS THE SAME. The above example both Grape and Apple have rowspan of 2, but this is not always the case.
2.Can any explain this syntax:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
So I can see that if either a or b is not a number, then do string parison otherwise do number parison, but I dont understand the
inverse ? -1 : 1 :
inverse ? 1 : -1;
Test cases
<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>
Share
Improve this question
edited May 23, 2017 at 10:28
CommunityBot
11 silver badge
asked Oct 15, 2012 at 15:30
Thang PhamThang Pham
38.7k79 gold badges208 silver badges289 bronze badges
2
- @Newbo.O: It should only sort within each rowspan. I have updated my question with expected result. – Thang Pham Commented Oct 18, 2012 at 0:47
- Sort only within a rowspan or: sort each rowspan group and then sort groups according to first value? – Robert Koritnik Commented Oct 19, 2012 at 11:38
2 Answers
Reset to default 3 +500Conditions for the code to work:
- Columns containing
td
s withrowspan
must all be on the left of the table - All the
td
s in these columns must have arowspan
, even if it's 1 - The groups of rows to sort are made with the rightmost of these columns (but it can easily be changed)
jsFiddle: http://jsfiddle/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;
}
Quick explanations:
- Finding all
td
s withrowspan
- Positions of these
td
s are saved, including left offset - These
td
s are filtered by their originaloffset
to work only with the rightmost ones tr
s related to each kepttd
are sorted using the wanted column- All
td
s withrowspan
are finally moved back to their original position if necessary
About question 2, I will only plete bartlaarhoven's answer by saying, the code can also be written like the following:
return (
(isNaN(a) || isNaN(b) ? a > b : +a > +b) ? 1 : -1
) * (inverse ? -1 : 1);
You can easily read that inverse
is used to inverse the result.
Considering question 1, try this code:
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;
}
}
Considering question 2; let's deduct where it es from. First of all we would like to check whether a > b, and, as you already saw correctly, we make a difference between string parison and number parison.
We would then simply give:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ? 1 : -1;
This checks whether a > b (either string-wise or number-wise) and then returns 1 on true and -1 on false.
Now we insert the inverse
parameter, which should inverse the result. This means that if inverse == true, then 1 bees -1 and -1 bees 1. In code, this bold piece of text would replace each occurrence of 1
with inverse ? -1 : 1
and each occurrence of -1
with inverse ? 1 : -1
. Which is exactly what is done in the resulting code.
UPDATE: Added doRowSpan
in the code because it should not adapt the index if we are in the <tr>
that contains the rowspan-td
.
本文标签: javascriptjQuery sortColumns plugin How to sort correctly with rowspanStack Overflow
版权声明:本文标题:javascript - jQuery sortColumns plugin: How to sort correctly with rowspan - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745599825a2158390.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论