Using jQuery to select table group columns - javascript

This is a part of my table columns I want to select. Here's the code:
<tr>
<th colspan="2">
</th>
</tr>
<tr>
<td></td><td></td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
Now i want to be able to select the whole big column. Tried many methods but none work so far. Any help would be appreciated.

well it will be
$('th[colspan="2"],td[colspan="2"]')

well if you know which column it is , ie 3rd column then it will be like
$("table td:nth-child(3),table th:nth-child(3)")
another answer could be
in case you can change the markup
<tr>
<th colspan="2" class="bigcol">
</th>
</tr>
<tr>
<td class="bigcol"></td><td></td>
</tr>
<tr>
<td colspan="2" class="bigcol"></td>
</tr>
$(".bigcol").hide()

This bit more complex jquery code does the trick. It is looking for a th and all the td with a specific colspan (so it's not perfect, because you can't have 2 big tds ina a row). It also hides the required amount of tds with 1 colspan. http://jsfiddle.net/balintbako/xz6W4/
var colw = 2;
var position = $("th[colspan=" + colw + "]").prevAll().length;
$("th[colspan=" + colw + "]").hide();
$("tr").each(function () {
if ($(this).find("th").length !== 0) {
return;
}
if ($(this).find("td[colspan=" + colw + "]").length !== 0) {
$(this).find("td[colspan=" + colw + "]").hide();
return;
}
for (var i = 1; i <= colw; i++) {
$(this).find("td:nth-child(" + (position + i) + ")").hide();
}
});

Related

Select 2 columns of an HTML table based on the first column selected

I have an HTML table with like 7 columns. When I select a column I want all the other columns to be hidden except the column next to the selected one. To be clear, only 2 columns need to be visible at a time - and those are the one selected and the one next to it. If there is a column to the right of the selected column, this one should be shown along with the selected column, if not (last column selected) the column to the left shall be shown along with the selected one.
I tried using loops but the problem is the user can select any column from the table.
My code:
var I = document.getElementsByTagName("th").length;
if(s=== I-1) { // s - index of selected column- check if its the last column
for (var D = 0; D < I-2; D++) {
var o = datatable.column(D);
o.visible(!o.visible());
}
} else {
for (var D = 0; D < s; D++) {
var o = datatable.column(D);
o.visible(!o.visible());
}
for (var D = s+1; D < I; D++) {
var o = datatable.column(D);
o.visible(!o.visible());
}
}
My HTML:
<table id="DataTables_Table_0" >
<thead>
<tr role="row" style="height: 0px;">
<th>
<div>Pro</div>
</th>
<th>
<div>Pri</div>
</th>
<th>
<div>State</div>
</th>
<th>
<div>phyId</div>
</th>
<th>
<div>Title</div>
</th>
<th>
<div>Origin</div>
</th>
<th>
<div>type</div>
</th>
</tr>
</thead>
<tbody style="">
<tr role="row" class="odd">
<td class="0 sorting_1">Private</td>
<td class="1">High</td>
<td class="2">Create</td>
<td class="3">E210DC29509F</td>
<td class="4">5</td>
<td class="5">8/9/2019, 8:24:00 AM</td>
<td class="6">Issue</td>
</tr>
<tr role="row" class="even">
<td class="0 sorting_1">Public</td>
<td class="1">Low</td>
<td class="2">Assign</td>
<td class="3">E210DC29509F</td>
<td class="4">5</td>
<td class="5">8/9/2019, 9:11:11 AM</td>
<td class="6">Issue</td>
</tr>
<tr role="row" class="odd">
<td class="0 sorting_1">Private</td>
<td class="1">Medium</td>
<td class="2">Assign</td>
<td class="3">E210DC29509F</td>
<td class="4">5</td>
<td class="5">8/9/2019, 9:17:26 AM</td>
<td class="6">Issue</td>
</tr>
<tr role="row" class="even">
<td class="0 sorting_1">Public</td>
<td class="1">Urgent</td>
<td class="2">Active</td>
<td class="3">E210DC29509F</td>
<td class="4">5</td>
<td class="5">8/8/2019, 4:14:59 PM</td>
<td class="6">Issue</td>
</tr>
</tbody>
</table>
An update to the question: I can select the 1st column always alonwith the column selected by the user. So that means I dont have to manually select the adjacent column from the table. I just modified the code:
for (var D = 1; D < I/2 ; D++) {
if (D !== s ) {
var o = f.datatable.column(D);
o.visible(!o.visible());
}
}
Now it works as expected. Actually this was for generating a line chart for the table data. Now i get a line chart, but i am just confused as to if the line chart does look as expected. I mean I have attached a screenshot of my line chart, but it looks like ther is something more to do. Sorry for not mentioning about the line chart as i thought it would make the question more complicated and confusing.linechart tabledata for the line chart
How exactly should a line chart look with my table.
I would make those td class names more explicit, so they're clearly labeling columns (like col-0), and then query the DOM based on those.
On selection change:
Hide all the columns.
Get the index being selected.
Calculate the two column class names to show.
Query for those class names and show those DOM nodes.
Here's some (untested) example js:
$('th, td').hide();
// for the OP: make sure colIndex isn't the rightmost col
const selectedCol = 'col-' + colIndex;
const nextCol = 'col-' + (colIndex + 1);
$('.' + selectedCol).show();
$('.' + nextCol).show();
Get the count of all columns.
then hide all the columns.
and then only show the selected and next or previous column
var I = document.getElementsByTagName("th").length;
function hideCol(s){
datatable.columns( 'th' ).visible( false );
if(s == I-1){
datatable.column(s).visible(true);
datatable.column(s-1).visible(true);
}else if(s < I){
datatable.column(s).visible(true);
datatable.column(s+1).visible(true);
}
}
hideCol(2);

Showing and Hiding Table Rows Based Off Alphabet Buttons

I have a table with a lot of rows in it, and I want to give users the ability to click an 'A' button and all the results that start with 'A' are displayed. They could do the same for every letter. This is what I've come up with so far:
HTML
<input type="button" id="aSort" value="A" onclick="alphaSort(this.value);">
<table>
<thead>
<tr>
<td>Title</td>
<td>Description</td>
<td>Active</td>
</tr>
</thead>
<tbody>
<tr>
<td name="title">Apple</td>
<td>It's a fruit</td>
<td>Active</td>
</tr>
<tr>
<td name="title">Pear</td>
<td>It's also fruit</td>
<td>No</td>
</tr>
</tbody>
</table>
JS
function alphaSort(val) {
//pseudocode
var $rows = $('td[name=title]');
$rows.forEach(function(e) {
if(e.innerText == val + '%') {
e.closest('tr').show();
} else {
e.closest('tr').hide();
}
}
}
So with what I have here, the idea is if the user clicked the button only the Apple row would show. Ideally the function would be case insensitive. Could someone help me with how to properly iterate through all the table rows efficiently and compare the value stored in the title row?
you can use startsWith function : https://www.w3schools.com/jsref/jsref_startswith.asp
like this :
$("#aSort").click(function(){
var $rows = $('td[name=title]');
var val = $(this).val()
$rows.each(function() {
if($(this).text().startsWith(val)) {
$(this).closest('tr').show();
} else {
$(this).closest('tr').hide();
}
})
})
https://jsfiddle.net/xpvt214o/899140/

Collapsing and expanding multiple nested rows in jQuery

I need a little help with collapsing and expanding nested rows. Currently my code below expands and collapses as desired at the first level but the subsequent levels also show.
$(document).ready(function(e) {
$('.collapseTitle').click(function() {
$(this).parent()
.parent()
.next('tbody')
.toggleClass('collapsed');
});
});
.collapsed {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td class="collapseTitle">Title</td>
</tr>
</thead>
<tbody class="collapsed">
<tr>
<td>Level 1</td>
</tr>
<tr>
<td>Level 2</td>
</tr>
</tbody>
</table>
I am trying to achieve that Level 1 expands when "collapseTitle" is clicked and that only when "collapseAccount" is clicked, does Level 2 expand. Now I know that my code should look something like the below, but I am struggling...
<table>
<thead>
<tr>
<td class="collapseTitle">Title</td>
</tr>
</thead>
<tbody>
<tr class="collapsed account">
<td class="collapseAccount">Level 1</td>
</tr>
<tr class="collapsed level">
<td>Level 2</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(e) {
$('.collapseTitle').click(function() {
$(this).parent().parent().next('tbody tr').toggleClass('account');
});
});
$(document).ready(function(e) {
$('.collapseAccount').click(function() {
$(this).next('tr').toggleClass('level');
});
});
</script>
Any help would be greatly appreciated.
The following code should do it. I hope it helps with what you want to achieve:
collapses/expands columns when clicking on the header/title of the column and
collapses/expands all rows following the account row when clicking on it (until the next account row)
The only thing you need to do is add the class account to the higher level rows. You can do this pretty easily when you're displaying these with a loop.
.collapsed {
/* using visibility, since display causes layout issues */
/* due to empty rows rows/columns collapsing */
visibility: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Title1</td>
<td>Title2</td>
</tr>
</thead>
<tbody>
<tr class="account">
<td class="collapsed">Account Summary - Account A</td>
<td class="collapsed">Account Summary - Account A</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part I - Account A</td>
<td class="collapsed">Account Details Part I - Account A</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part II - Account A</td>
<td class="collapsed">Account Details Part II - Account A</td>
</tr>
<tr class="account">
<td class="collapsed">Account Summary - Account B</td>
<td class="collapsed">Account Summary - Account B</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part I - Account B</td>
<td class="collapsed">Account Details Part I - Account B</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(() => {
/* the following handlers expand/collapse the columns */
$('thead > tr > td').each((i, el) => {
$(el).click(() => {
const colIndex = $(el).index() + 1;
const nRows = $('tbody > tr').length;
for (let j = 0; j < nRows; j += 1) {
let cellSelector = `tbody > tr:nth-child(${j+1})`
cellSelector += `> td:nth-child(${colIndex})`;
$(cellSelector).toggleClass('collapsed');
}
})
})
/* the following handlers expand/collapse the account-details rows */
$('tbody > tr.account').each((i, el) => {
$(el).click(() => {
$(el).nextUntil('.account').each((j, ele) => {
$(ele).toggleClass('collapsed');
})
})
})
});
</script>
Your jQuery selectors are just a bit off for the toggleClass. You can use the class names of the row to toggle. Also you should create a class to be toggled that displays the row/hides it. For example:
edit:
I now created the titles and rows dynamically to give you a better idea of how this can be done using data- attributes.
You will have a title td and a row td that match on a data- attribute, so when you click a title and corresponding tr will be shown. So for example if you click title 1 (with a data-index=1) then the tr with the attribute data-rowindex=1 will be shown.
$(document).ready(function(e) {
createTable();
$('.collapseTitle').click(function() {
// grab the data-index value from the clicked title
let index = $(this).attr("data-index");
// find a tr that has the attribute data-rowindex and it matches index
$("tr[data-rowindex='" + index + "']").toggleClass("collapsed");
});
});
function createTable(){
// create the titles and the level rows
for(let i = 0; i < 3; i++){
// create the title row
let $trTitle = $('<tr>');
let $tdTitle = $('<td>', {class: "collapseTitle", text: "Title " + i});
$tdTitle.attr("data-index", i);
let $finalTitleRow = $trTitle.append( $tdTitle );
// create the level row
let $trLevel = $('<tr>', {class: "collapsed account"} );
$trLevel.attr("data-rowindex", i);
let $tdLevel = $('<td>', {text: "Level " + i});
let $finalLevelRow = $trLevel.append( $tdLevel );
// add the title and level row pairs to the head and body
$("#myTableHead").append($finalTitleRow[0]);
$("#myTableBody").append($finalLevelRow[0]);
}
}
.collapsed {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead id="myTableHead">
</thead>
<tbody id="myTableBody">
</tbody>
</table>
I managed to find the answer I was looking for... Thank you to "stackoverfloweth",
Answer To My Question
The snippet of code which has helped me thus far is below,
$('.parent-row').click(function(){
var $element = $(this).next();
while(!$element.hasClass('parent-row')){
$element.toggle();
if($element.next().length >0){
$element = $element.next();
}
else{
return;
}
} });
$('.child-row.has-children').click(function(){
var $element = $(this).next();
while($element.hasClass('child-child-row')){
$element.toggle();
if($element.next().length >0){
$element = $element.next();
}
else{
return;
}
} });

How to find the corresponding th to a given td?

Basically the same question as How can I get the corresponding table header (th) from a table cell (td)? but not jQuery specific.
From a given <td> is there an easy way to find the corresponding <th>?
<table width="100%" id="stock">
<tr>
<th>Name</th>
<th>Type</th>
<th>Quantity</th>
<th>Options</th>
</tr>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td>-1</td>
<td>...</td>
</tr>
I'd like something doing this:
document.getElementById('target').correspondingTH // would return HTMLObject <th>Type</th>
An ideal answer might contain both a jQuery way to do it and a vanilla one but I'm personally looking for a vanilla one.
Pure JavaScript's answer.
var index = Array.prototype.indexOf.call(your_td.parentNode.children, your_td)
var corresponding_th = document.querySelector('#your_table_id th:nth-child(' + (index+1) + ')')
As posted here in the more jQuery specifc question: https://stackoverflow.com/a/37312707/1524913
HTML table model gives easier solution. jquery in this case is more sophisticated. I tested following table:
<table style="width:100%" id="stock">
<tbody>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td>-1</td>
<td>...</td>
</tr>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td>-1</td>
<td>...</td>
</tr>
</tbody>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td colspan="2">-1</td>
<!--<td>...</td>-->
</tr>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Quantity</th>
<th>Options</th>
</tr>
</thead>
</table>
Script without jquery is simple and straightforward.
window.onload = function () {
var tbl = document.getElementById('stock');
var tds = document.getElementsByTagName('td');
for (var i = 0, td; td = tds[i]; ++i) {
td.onclick = function () {
var tr = this.parentNode;
console.log(tbl.rows[0].cells[this.cellIndex].innerHTML);
}
}
}
jquery also is useful.
$(document).ready(function () {
$('#stock td').click(function () {
console.log($(this).parents('table').find('tr:first-child').children('th:nth-child(' + (this.cellIndex + 1) + ')').html());
});
});
<thead> can be placed at the top, at the bottom, and between rows. thead inside tbody is obvious error but browser fixes it. Scripts work in any case.
I think you need to step through the TH colSpans to exactly match the TD
Try
function getHeadCell(td) {
var index = Array.prototype.indexOf.call(td.parentNode.children, td);
var table = td;
while (table && table.tagName != 'TABLE') table = table.parentNode;
var cx = 0;
for (var c = 0; cx <= index; c++) cx += table.rows[0].cells[c].colSpan;
return table.rows[0].cells[c - 1];
}
See https://jsfiddle.net/Abeeee/upt75s2x/34/ for a working example

Good code for structure manipulation of table's cells/rows with JQuery

I'm writing wysiwyg editor (iframe in designmode), and I can't find good right code to operate with table. Not simple table where any cells have rowspan or colspan is 1! I mean about hard table variant, like this:
<table border=1>
<tr>
<td rowspan=2 colspan=2 width=60px height=60px> </td>
<td height=30px width=30px> </td>
</tr>
<tr>
<td rowspan=2 width=30px height=60px> </td>
</tr>
<tr>
<td height=30px width=30px> </td>
<td height=30px width=30px> </td>
</tr>
</table>
Any code I was found is only for simple tables. For example, this is code for insert rows and it do that wrong:
var cell = select.current;
var row = cell.closest('tr');
var table = row.closest('table');
row.after('<tr></tr>');
var row_new = row.next();
row.children().each(function()
{
var cs = $(this).prop('colSpan');
if ( cs == 1 )
{
row_new.append('<td> </td>');
}
else
{
row_new.append('<td colspan=' + cs + '> </td>');
}
});
I think the right code maybe will analyze all table rows and change rowspan values and etc.

Categories

Resources