We have a large HTML table (maybe 100x100 cells). Selecting rows is pretty fast as we can simply select all TDs in a specific TR. But selecting columns with the help of jQuery and nth-child is much slower. Are there any faster alternatives for column selection? How about pseudo classes for every column (like class="column-1", and so on)? What is your experience with this?
Are there any faster alternatives for column selection?
I would recommend using the much-ignored COLGROUP/COL tags, as per the original W3C HTML spec. Copy-and-paste this code into a dummy HTML page and see for yourself the magic of COLGROUPs!
<table id="mytable">
<caption>Legend</caption>
<colgroup>
<col style="background-color: #f00;"/>
<col/>
<col/>
</colgroup>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tfoot>
<tr>
<td>cell 1,1</td>
<td>cell 1,2</td>
<td>cell 1,3</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>footer 1,1</td>
<td>footer 1,2</td>
<td>footer 1,3</td>
</tr>
</tbody>
</table>
TFOOT tags go before TBODY tags. COLGROUPs have COLs for each column.
The advantage of this is that styling to a COL inside a COLGROUP will cascade to all of the columns in a table. Background colors, for instance. It never ceases to amaze me how many people have absolutely no idea of this trick, even though the HTML spec is out there for anybody to read and digest.
I personally would use a class for each column. My usual standard is as such:
<tr class="row row-1">
<td class="col col-1"></td>
<td class="col col-2"></td>
<td class="col col-3"></td>
</tr>
Have you tried just using the DOM directly?
var column = new Array();
var cells;
for (row = 0; row < table.rows.length; row++) {
tr = table.rows[row];
column.push(tr.cells[1]);
};
It works pretty fast for me at http://www.jsfiddle.net/gaby/GWqtB/4/ (for 100cols x 300rows)
Can you provide an example, so we can see the speed of your implementation ?
Could it be that the delay is at some other part of the code ? like styling while selecting..
Related
In my WordPress options page, for creating fields I am using Fluent Framework. It is similar to Meta Box. So both of them use do_settings_fields function and the function generates the code like this:
<table class="form-table">
<tr>
<th scope="row">Header 1</th>
<td>Element 1</td>
</tr>
<tr>
<th scope="row">Header 2</th>
<td>Element 2</td>
</tr>
<tr>
<th scope="row">Header 3</th>
<td>Element 3</td>
</tr>
<tr>
<th scope="row">Header 4</th>
<td>Element 4</td>
</tr>
</table>
It looks like this:
In this table, I want to use firs row as a one row like this:
I creted a javascript file to fields/custom_html directory and hide scope with jQuery and enqueue the javascript file like this:
jQuery(document).ready(function()
{
jQuery('th[scope="row"]').first().hide();
});
But this doesn't completely solve my problem. Because I don't mind if I only use one row, but it's very problematic for multi-rows. Maybe I need to close the table tag and open a new table tag again, but I haven't been able to do this with my limited jQuery knowledge.
Merging two columns you have to use "colspan" attributes which can helpful, Here I am sharing the code for jquery.
$(document).ready(function(){
var $table_head = jQuery('tr').first();
var value = $table_head.text();
$table_head.html('<th colspan="2">'+value+'</th>');
});
I have a table (table1) which contains only th tags and a table (table2) which contains only td tags. (I know this set up seems really wrong, but it's set up this way due to a few different issues with the application, so try not to worry about why it's set up this way).
Each TH in table1 acts as a sorting button corresponding the TD in table2.
The full width of each table is the same, however the width of the TH's and the TD's are different making them not line up correctly.
I need to find a way to link the width of each individual TH to the width of the TD below it. The difficult part is that the TH sorting buttons are dynamic and the user has the ability to add or remove TH's to their liking, so the widths need to be able to dynamically change. I can't figure out how to link the two together seamlessly. Any ideas?
IE:
<table id="table1">
<thead>
<th>Sorts 1</th>
<th>Sorts 2</th>
<th>Sorts 3</th>
<th>Sorts 4</th>
</thead>
</table>
<table id="table2">
<thead>
<td>Sort 1</td>
<td>Sort 2</td>
<td>Sort 3</td>
<td>Sort 4</td>
</thead>
</table>
I have created a basic Fiddle that shows what mean. The last few td's get squished into the Sorts7 column. I want the TH and the corresponding TD to always equal the same width, even if we add or remove columns.
Link to Fiddle
Thank you in advance.
Edit: The two tables do have to remain separate. It's unfortunate I know. :(
Well I don't like this answer, but it works so...
What you could do is use jQuery to get the widths of the bottom columns and apply it on the top columns - like this:
$('#top1').css({"width":$("#bottom1").width()});
$('#top2').css({"width":$("#bottom2").width()});
$('#top3').css({"width":$("#bottom3").width()});
$('#top4').css({"width":$("#bottom4").width()});
table, th, td {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table1">
<thead>
<th id="top1">Sorts 1</th>
<th id="top2">Sorts 2</th>
<th id="top3">Sorts 3</th>
<th id="top4">Sorts 4</th>
</thead>
</table>
<br> <!-- To demonstrate that they are separate -->
<table id="table2">
<tr>
<td id="bottom1">Sort 1</td>
<td id="bottom2">Sort 2 With Longer Content</td>
<td id="bottom3">Sort 3</td>
<td id="bottom4">Sort 4</td>
</tr>
<tr>
<td id="bottom1">Sort 1</td>
<td id="bottom2">Sort 2</td>
<td id="bottom3">Sort 3 With Longer Content</td>
<td id="bottom4">Sort 4</td>
</tr>
</table>
I just hope you don't have a lot of columns!
You can use a same class for both th & td.
Will something like this work for you?
I've used jQuery because of simplicity:
$( "#table2 tr td" ).each(function( index ) {
$('#table1 th').eq(index).css('width',$(this).width()+'px');
});
Demo: https://jsfiddle.net/6u1dyL55/10/
So, idea is to get td widths, and attach it to corresponding TH's in first table (via indexes - because they are same).
This is the table structure that I have:
<table>
<thead >
<tr>
<th >Header 1</th>
<th >Header 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
I have multiple tbody tags to support a nested ng-repeat structure with spanned rows hence it is inevitable to have the tbody tags.
However, I am now unable to put these tbody tags in a valid container and set the overflow-y as auto inorder to bring in the scroll bar just for the table data and not including the thead (headers)
Help will be appreciated!
first thing to consider of multiple tbody. you can do your task without using of multiple tbody as it is not a good approach.
Aside you can use Table FloadHead plug in. probably it will help in making headers fixed.
applying datatable on each table using id but it only triggers for one table and give error in console.
"Uncaught TypeError: Cannot set property 'nTf' of undefined" while i need to display it on every table .
Using class cannot be applied because each table has different td's count .
for instance i have two tables with id's table1 & table2 and calling datatable as
$('#table1').DataTable();
$('#table2').DataTable();
Please advise any help would be appreciated
my first table is
<table id="table1">
<thead>
<tr>
<th>No.s</th>
<th>Title</th>
<th>project</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>test</td>
<td>test project</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="3"></th>
</tr>
</tfoot>
</table>
My second table is
<table id="table2">
<thead>
<tr>
<th>No.s</th>
<th>Title</th>
<th>Task</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>test</td>
<td>test task</td>
<td>Edit</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="4"></th>
</tr>
</tfoot>
</table>
Using class cannot be applied because each table has different td's count
There is nothing to do when we use datatable for mutiple tables it works only for the tables which have same count of td's and can be applied using the both table's same class
Live Demo
i just had this problem and it turned out to be one too many tds in the tfoot. Check your rows and columns for extras, unclosed tags etc.
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/