jQuery Tablesorter Static Rows - javascript

I've been struggling to find an answer to this question. That is, how would I have a static row that doesn't sort or move up and down? The reason for this is to have repeated headers in a very large table. The multiple headers Would anyone be able to help?
http://tablesorter.com/docs/
$("#dataTable").tablesorter({
sortList: [[0, 0], [1, 0]],
widgets: ['zebra', 'rowHover'],
widgetZebra: { css: ["even", "odd"] },
widgetRowHover: { css: 'rowhover' }
});
..
<table>
<tr>
<td>
Row 1
</td>
</tr>
<tr>
<td>
Row 2
</td>
</tr>
<tr>
<td>
Static Row
</td>
</tr>
<tr>
<td>
Row 3
</td>
</tr>
</table>

I was asked by #patmortech to add my comment above as an answer. So here is my comment verbatim.
I realise that this is ~4 months old now, but I ran into a similar problem and created a widget for Tablesorter that allows you to mark any rows as static. Take a look if you're still interested: http://asciisoup.wordpress.com/2011/02/20/static-rows-widget-for-jquery-tablesorter/

It sounds like you might want to break this table into 2 tables and adjust the columns widths if possible. Especially if you are not grouping rows.

Related

DataTables: TypeError: i is undefined

I have a table like the following
the table as rowspans because for some users I need to have 2 lines (Like you see at column 'D')
I am trying to use datatables:
<table class="table table-bordered table-hover table-striped" id="myTable">
(...)
</table>
And I call this at the begining of the code:
<script>
$( document ).ready(function() {
$('#myTable').DataTable();
});
</script>
But I have this error:
TypeError: i is undefined
And the table is not like a datatable type!
Maybe it doesn't work with rowspans?
Any idea??
FWIW you can also get this error if you don't have the same number of <td></td> elements in every row. Make sure you aren't adding any rows with nav buttons or links or anything like that that may not be formatted the same way as the other rows.
jQuery DataTables plug-in doesn't support ROWSPAN attribute by default. However there is a RowsGroup plugin for jQuery DataTables that groups cells together to make them look like as if ROWSPAN attribute is used.
See this example for code and demonstration.
See jQuery DataTables – ROWSPAN in table body TBODY for more details.
For future referer.
It is because you are using Rowspan or colspan which is not supportable.
If you want to use colspan you can use it outside </tbody>.
Thanks.
This problem happens if your table is not well formed, for example you should have
<table>
<thead>
<th>
<tbody>
<tr>
<td>
And then the id of the table should not overlap with id of any thing else on the same page. Other wise you will get errors like i is udefined or c is undefined.
I'd say your table is not a data table because you have undefined data and the 'i' referred to is the internal iterator of the DataTable loop, the use of rowspans is the problem - I would redesign your table to have an entire row for each piece of data (in your example 250 would require an entire row with duplicate values for all other columns except D) - it is wholly possible to use css to hide values that are duplicated for the same visual effect, this would allow datatable filtering to still work on those rows (although you may need some hooks to reveal hidden data when these 'extra' rows are filtered).
I was facing the same issue. The main reason for the error is due to using the colspan & rowspan. Because the jQuery DataTables plug-in does not support them and hence causing the error.
TypeError: i is undefined
So, If you are using any colspan or rowspan within any <tr></tr> inside the <tbody></tbody> then make sure that each <tr></tr> having the same no of <td></td> for each row. If not, then repeat the <td style='display:none'></td> to match the same no e.g
<table border='1' cellspacing='2'>
<thead>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td rowspan="2">name</td>
<td>200</td>
<td style='display:none'></td>
<td style='display:none'></td>
</tr>
<tr>
<td >300</td>
<td style='display:none'></td>
<td style='display:none'></td>
</tr>
</tbody>
</table>
I think by following the above suggestion will help you sure.

How to create a partially expanding/collapsing html table? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am trying to improve on an old school "Top Screens" page that we currently have. It shows the top 30 in a plain old html table. I want to be able to generate the table with the top 100, but only show the top 20 on page load and then have an expand/collapse button. I have found plenty of examples of fully expanding and collapsing tables and subtables, but I have yet to find an example of partially doing one like I need.
It is currently a very simple 2 column table with headers and minimal CSS styling and JS. I would like to keep it to plain JS if possible, but I do have the JQuery library available to me, I am just not very familiar with it.
Any help would be appreciated.
Thanks in advance!
EDIT
I apologize for what ended up being a relatively easy solution with JQuery, but I am very new to it. After reading through the API docs some more I found the :gt() selector that when combined with toggle() lead to an elegant solution which I am adding for anyone who may be interested.
I added the "collapse" class to my <tbody> so the <thead> would not be affected or counted.
// Hide extra rows on load.
$(document).ready(function() {
$(".collapse").find('tr:gt(19)').hide();
});
// Toggle extra rows on click.
$(".collapse").click(function(){
$(this).find('tr:gt(19)').toggle();
});
The simplelest way to do this would be with jQuery, as you could use the .toggle() method.
In my example I've chosen to only show the first 3 results, so that the code isn't too long.
See my comments in the code to understand what's going on.
$(document).ready(function() {
$("button#sh").click(function() {
$("tr.row:nth-child(n+5)").toggle();
});
});
//Here jQuery listens for a click on the button with id "sh", and when clicked,
//either shows or hides the rows selected by the CSS selector, which is the same as
//the one that hid the rows in the CSS section.
tr.row:nth-child(n+5) {
display: none
}
/* Here all rows after the 4th one will be hidden on load. So you have 1 row for the
header, then 3 rows of data, 3+1=4, so row 5 and on will be hidden. */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Here jQuery is included -->
<button id="sh">Show/Hide</button>
<!-- Here the button that will show and hide the rows is set. -->
<table border="1">
<tr class="row">
<td>Name</td>
<td>Number</td>
</tr>
<tr class="row">
<td>Name 1</td>
<td>1</td>
</tr>
<tr class="row">
<td>Name 2</td>
<td>2</td>
</tr>
<tr class="row">
<td>Name 3</td>
<td>3</td>
</tr>
<tr class="row">
<td>Name 4</td>
<td>4</td>
</tr>
<tr class="row">
<td>Name 5</td>
<td>5</td>
</tr>
<tr class="row">
<td>Name 6</td>
<td>6</td>
</tr>
</table>

how to make two table rows be constantly attached

So I have a table that can sort its columns.
It is formated with multiple rows like this:
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
I want to be able to sort by the Data rows and have the metadata rows just follow the data rows that they have information about. However, since my sorting code can't tell the difference between the rows, I end up getting something like:
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
<tr><td> MetaData </td></tr>
How do I force the MetaData and the Data rows to be "tied" together?
Ok, first things first, when you have a table cell spanning two columns like that you're supposed to use the colspan attribute, e.g.
<tr><td colspan="2">MetaData</td></tr>
Now, in order to tie them together, I think you're going about it the wrong way. The meta data itself doesn't logically sit in a table row all of it's own, it should live in the same row as the actual data. You could do something like this with HTML5 data attributes :
<tr>
<td data-meta="MetaData">Data</td>
<td data-meta="MetaData">Data</td>
</tr>
You can group your rows using the <tbody>tag, which can appear more then once within <table> - maybe it's not so common to have multiple tbodies but it's actually possible.
<tbody>
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
</tbody>
<tbody>
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
</tbody>
You still have to tune your code others mentioned to sort the tbodies by their rows instead of sorting just the rows so it probably won't work out of the box, but this structure might help you then solving the problem.
do that using javascript
function sortNum(a, b) {
return 1 * $(a).find('.YOUR_DATA_TO_SORT').text() < 1 * $(b).find('.YOUR_DATA_TO_SORT').text() ? 0 : 1;
}
function sortTheTable(){
$(function() {
var elems = $.makeArray($('tr:has(.YOUR_DATA_TO_SORT)').remove())
elems.sort(sortNum)
$('table#TABLE_ID').append($(elems));
});
}
here's the fiddle: http://jsfiddle.net/E56j8/
[Source]
If you arrange your data as below, your data and it's associated meta-data will sort/move together.
<tr>
<td>
<table>
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
</table>
</td>
<tr>
<tr>
<td>
<table>
<tr><td>Data</td><td>Data</td></tr>
<tr><td> MetaData </td></tr>
</table>
</td>
<tr>
This answer out of context is very bad practice! The only reason I have proposed it is because you haven't provided the actual js code that is doing the sorting

Remove table row that contains a table

I have html that displays a table similar to:
<table>
<tr>
<th>col1</th>
<th>col2</ht>
</tr>
<tr>
<td>0001</td>
<td>Test</td>
</tr>
<tr>
<td colspan="2" id="detailsTable">
<table>
<tr>
<th>one</th>
<th>two</th>
</tr>
<tr>
<td>xxxxxx</td>
<td>xxxxxxx</td>
</tr>
</table>
</td>
</tr>
There is a column of expand and contract buttons on the outer table so that the nested table is only shown when the user clicks to expand.
The expansion works and the table gets displayed. However when when I try and remove the row from the outer table that contains the child table it doesn't work.
I had code like:
var rowIndex = $(this).parent().parent().prevAll().length;
$("table[id$=gvParentAccounts] tr").eq(rowIndex + 1).remove();
If the row only contains text it works as I'd like and removes the row, however if like in this case the row contains a table it is unable to remove the row as required.
I'm using ASP.Net and jQuery for this.
Thanks
Alan.
How about:
$(this).parent().parent().remove();
I'm not sure if this is exactly what you have, but here's a JSFiddle demonstrating that it works:
http://jsfiddle.net/9TQG9/1/
EDIT: Actually this:
$(this).parents("tr").eq(0).remove();
would be much nicer and more reliable. See here:
http://jsfiddle.net/9TQG9/2/

dynamically close and open table rows

I have a table on my site that contains the options for different products. I didn't put it there, the ecommerce platform did. It lists the options in a row in the table. The table looks like this:
<div class="attributes">
<table>
<tbody>
<tr>
<td>Size:</td>
<td> </td>
<td><select><option>Sizes here</option></select></td>
</tr>
</tbody>
</table>
</div>
Then if there were another option it would be in an additional row with the same markup.
This renders with the label (size in this case) out in front of the <select> box. I want the label above the <select> box and I figured the easiest way to accomplish this would be to close the <tr> and open a new one. Any ideas on how to do this?
EDIT: I should mention that the ecommerce platform generates the html and I do not have access to the source code
Assuming that it follows that exact structure, try this:
$(".attributes select").each(function(){
$label = $(this).parent().prev().prev();
$label.parent().before("<tr></tr>");
$label.parent().prev().append($label.clone());
$label.remove();
$(this).parent().prev().remove();
});
Here's an example: Demo
Like so?
<div class="attributes">
<table>
<tbody>
<tr>
<td>Size:</td>
</tr>
<tr>
<td><select><option>Sizes here</option></select></td>
</tr>
</tbody>
</table>
</div>
I think you have to do it in two steps:
remove the elements:
$('.attributes').find('tr:first-child').remove();
$('.attributes').find('tr:first-child').remove();
2.append them back in the same place
$('.attributes').find('tr:first-child').before('<tr><td>Sizes here</td></tr>');

Categories