JavaScript - Get Table Column from Index - javascript

I need a way to grab a column based on its index. The index number is from looking up a <td> and returning its cellIndex. The reason I want to do this is so I can grab the <col>'s class and apply it to all its <td>s. Each <td> needs the class applied since I'm using a library (List.js) and I won't be able to do any of the sorting/filtering/searching if the individual <td>s are not appropriately labeled (unfortunately, it won't work if only the <col>s have them). Also, the <col>s do not have any other attributes added like ids, names, etc.
function addClassesToCells(table) {
var col = ; // hoping to identify col using index here
var classname = col.className;
// rest of function
}
function getIndex() { // test function to find index
document.addEventListener("click", function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
var td = "TD";
if (target.tagName == td) {
console.log(target.cellIndex);
}
}, false);
}
The goal is getting all <td>s under a particular to apply classes, so if there are other/better ways to do this, then I welcome any. Thank you.

To get the list of cols and tds, use queries and match the indexes.
var table = document.querySelector('table');
var cols = table.querySelectorAll('col');
var trs = table.querySelectorAll('tr');
var tds = [].map.call(trs, tr => tr.querySelectorAll('td'));
for (var i = 0; i < trs.length; i++) {
for (var j = 0; j < tds[i].length; j++) {
tds[i][j].className = cols[j].className;
}
}
.a {
color: red;
}
.b {
color: blue;
}
.c {
color: green;
}
<table>
<colgroup>
<col class="a" />
<col class="b" />
<col class="c" />
</colgroup>
<tr>
<td>Lime</td>
<td>Lemon</td>
<td>Orange</td>
</tr>
<tr>
<td>Green</td>
<td>Yellow</td>
<td>Orange</td>
</tr>
</table>

Related

Javascript set first column style

I'm using javascript to modify a page's styling and it's working great. The next step however is to change the styling of the first column of a table. How can I identify and set the styling of the first column only? My other changes so far are based on ID or based on a number of items having a class. In this example I just know they are TH or TD elements, and I want to change the ones in the first column.
In case anyone asks, this is my code so far... this is working and doesn't include anything to do with setting the style of the first column
function rotate_headers() {
const collection = document.getElementsByTagName("th");
for (let i = 0; i < collection.length; i++)
{
collection[i].innerHTML =
'<div style="padding-left: 100%;"><div style="transform: translate(7px, 3px) rotate(315deg); width: 30px;"><span style="border-bottom: 1px solid #ccc; padding: 5px 10px; color:grey;"' + collection[i].innerHTML + '</span> </div></div>';
// collection[i].style.background = "#6877c3"; //
//collection[i].style.height = "100px"; //
}
const collection2 = document.getElementsByClassName("table-bordered");
for (let i = 0; i < collection2.length; i++)
{ collection2[i].style.border = "0px";
collection2[i].style.marginTop = "95px";
}
const collection3 = document.getElementsByClassName("highlight");
for (let i = 0; i < collection3.length; i++)
{ collection3[i].classList.remove("highlight"); }
const collection4 = document.getElementsByClassName("table-content");
for (let i = 0; i < collection4.length; i++)
{ collection4[i].style.padding = "1rem 1rem"; }
const collection5 = document.getElementsByClassName("table-content");
for (let i = 0; i < collection5.length; i++)
{ collection5[i].style.width = "100px";
collection5[i].style.position = "relative";
collection5[i].style.whiteSpace = "nowrap";
collection5[i].style.overflowX = "scroll";
collection5[i].style.overflowY = "hidden";
}
}
The below code does what I want, but only if my table has an ID... which mine typically do not.
var table = document.getElementById('test');
for (var i = 1; i < table.rows.length; i++) {
var firstCol = table.rows[i].cells[0]; //first column
firstCol.style.background = 'red'; // or anything you want to do with first col
}
The code below does not work... which is my problem
var table = document.getElementsByTagName("table");
for (var i = 1; i < table.rows.length; i++) {
var firstCol = table.rows[i].cells[0]; //first column
firstCol.style.background = 'red'; // or anything you want to do with first col
}
You can just use document.querySelectorAll('tr th:first-child, tr td:first-child') then iterate the result setting the styles you want.
let firstCol = document.querySelectorAll('tr th:first-child, tr td:first-child')
for (let i = 0; i < firstCol.length; i++) {
firstCol[i].style.color = 'red'
}
<table>
<tr>
<th>one</th>
<th>two</th>
<th>three</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
I think you will find answer in next article:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Tables/Basics
Styling without
There is one last feature we'll tell you about in this article before we move on. HTML has a method of defining styling information for an entire column of data all in one place — the and elements. These exist because it can be a bit annoying and inefficient having to specify styling on columns — you generally have to specify your styling information on every or in the column, or use a complex selector such as :nth-child.

searching text within Html table

I just googling to find a script that I can use to find a text within HTML table.
Like I create a table of student names which have many columns and rows. I have a good script too that display whatever I try to search but it display full row...
function searchSname() {
var input, filter, found, table, tr, td, i, j;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td");
for (j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
}
}
if (found) {
tr[i].style.display = "";
found = false;
} else {
tr[i].style.display = "none";
}
}
}
<input id='myInput' onkeyup='searchSname()' type='text'>
<table id='myTable'>
<tr>
<td>AB</td>
<td>BC</td>
</tr>
<tr>
<td>CD</td>
<td>DE</td>
</tr>
<tr>
<td>EF</td>
<td>GH</td>
</tr>
</table>
But know I am looking for making some changes to display exact text whatever I searched instead of full row like it will display text that I type to search and hide other unmatched fully....
Kindly let me know is it possible to display text only that I type to search within a table? Like if I try to find student name "AB" then it should display AB only instead of "AB BC".
This is much simpler than you are making it.
var cells = document.querySelectorAll("#myTable td");
var search = document.getElementById("myInput");
search.addEventListener("keyup", function(){
for(var i = 0; i < cells.length; ++i){
// This line checks for an exact match in a cell against what the
// user entered in the search box
//if(cells[i].textContent.toLowerCase() === search.value.toLowerCase()){
// This checks for cells that start with what the user has entered
if(cells[i].textContent.toLowerCase().indexOf(search.value.toLowerCase()) === 0){
cells.forEach(function(element){
element.style.display = "none";
});
cells[i].style.background = "yellow";
cells[i].style.display = "table-cell";
break;
} else {
cells[i].style.background = "white";
cells.forEach(function(element){
if(cells[i] !== element){
element.style.display = "table-cell";
}
});
}
}
});
table, td { border:1px solid black; border-collapse: collapse;}
<input id='myInput'>
<table id='myTable'>
<tr>
<td>AB</td>
<td>BC</td>
</tr>
<tr>
<td>CD</td>
<td>DE</td>
</tr>
<tr>
<td>EF</td>
<td>GH</td>
</tr>
</table>

Why can I filter by int but not string?

Right now I have code that can filter by int:
<input name='tablefilter' type='checkbox' value='1' id='tablefilter1' checked/>
<label for='tablefilter1'>1</label>
<input name='tablefilter' type='checkbox' value='2' id='tablefilter2' checked/>
<label for='tablefilter2'>2</label>
<input name='tablefilter' type='checkbox' value='3' id='tablefilter3' checked/>
<label for='tablefilter3'>3</label>
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody id='tablebody'>
<tr>
<td>1</td>
<td>One</td>
<td>First</td>
</tr>
<tr>
<td>2</td>
<td>Two</td>
<td>Second</td>
</tr>
<tr>
<td>3</td>
<td>Three</td>
<td>Third</td>
</tr>
</tbody>
</table>
js
/* Demo filtering table using checkboxes. Filters against first td value */
/* Set 'ready' handler' */
document.addEventListener('DOMContentLoaded', initFunc);
/* When document ready, set click handlers for the filter boxes */
function initFunc(event) {
var filters = document.getElementsByName('tablefilter');
for (var i = 0; i < filters.length; i++) {
filters[i].addEventListener('click', buildAndExecFilter);
}
}
/*
This function gets called when clicking on table filter checkboxes.
It builds a list of selected values and then filters the table based on that
*/
function buildAndExecFilter() {
var show = [];
var filters = document.getElementsByName('tablefilter');
for (var i = 0; i < filters.length; i++) {
if (filters[i].checked) {
show.push(filters[i].value);
}
}
execFilter(show); // Filter based on selected values
}
function execFilter(show) {
/* For all rows of table, see if td 0 contains a selected value to filter */
var rows = document.getElementById('tablebody').getElementsByTagName('tr');
for (var i = 0; i < rows.length; i++) {
var display = ""; // Default to display
// If it is not found in the selected filter values, don't show it
if (show.indexOf(rows[i].children[0].textContent) === -1) {
display = "none";
}
// Update the display accordingly
rows[i].style.display = display;
}
}
http://jsfiddle.net/2Lm7pytt/3/
However that filter can't filter by a string. If I for example want to use "one" instead of 1, it wouldn't work.
Does anyone know why and what the solution would be?
Thank you
These lines of your execFilter() method,
if (show.indexOf(rows[i].children[0].textContent) === -1) {
display = "none";
}
is only comparing the index 0 which is the numeric value not other columns.
Unless you compare the values with all the columns (all the indexes of rows[i].children) it won't give you the result you want.
So, you might wan't to run a for loop to iterate through all the children of rows[i].children and compare their text.
var foundResult = false;
for ( var counter = 0; counter < rows[i].children.length; counter++ )
{
if (show.indexOf(rows[i].children[0].textContent) != -1)
{
foundResult= true;
break;
}
}
if ( !foundResult )
{
display = 'none';
}
You mean something like this
var flt = ["zero","one","two","three"];
...
var showIt = show.indexOf(rows[i].children[0].textContent) !=-1;
for (var j=0;j<show.length;j++) {
if (flt[show[j]] == rows[i].children[1].textContent) {
showIt=true;
break;
}
}
rows[i].style.display = showIt?"":"none";

Detecting click on multiple tables with Javascript

I have developed code which detects when a user clicks on a cell in a table, and then uses the bgColor that has been set for that cell.
I have most of what I am trying to achieve working, I am stuck on how do get it to detect a click in multiple tables, instead of just one. I need to have this working with multiple tables, however I cannot have it working with all tables, just the colorchartX tables. So other tables on this page, should do nothing when their cell is clicked.
So in the code below, I have colorchart1 working as I want, how do I also get colorchart2 to detect when one of its cells is clicked and then provide the bgColor for that cell?
function getVal(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
var colorSelected = targ.attributes.bgcolor.value;
alert(colorSelected);
}
onload = function() {
var t = document.getElementById("colorchart1").getElementsByTagName("td");
for ( var i = 0; i < t.length; i++ )
t[i].onclick = getVal;
}
<table id="colorchart1">
<tr>
<td bgColor="#F8E0E0"></td><td bgColor="#F8ECE0"></td><td bgColor="#F7F8E0"></td><td bgColor="#ECF8E0"></td>
<td bgColor="#E0F8E0"></td><td bgColor="#E0F8EC"></td><td bgColor="#E0F8F7"></td><td bgColor="#E0ECF8"></td><td bgColor="#E0E0F8"></td>
</tr><tr>
<td bgColor="#F5A9A9"></td><td bgColor="#F5D0A9"></td><td bgColor="#F2F5A9"></td><td bgColor="#D0F5A9"></td>
<td bgColor="#A9F5A9"></td><td bgColor="#A9F5D0"></td><td bgColor="#A9F5F2"></td><td bgColor="#A9D0F5"></td><td bgColor="#A9A9F5"></td>
</tr>
<table>
<table id="colorchart2">
<tr>
<td bgColor="#F8E0E0"></td><td bgColor="#F8ECE0"></td><td bgColor="#F7F8E0"></td><td bgColor="#ECF8E0"></td>
<td bgColor="#E0F8E0"></td><td bgColor="#E0F8EC"></td><td bgColor="#E0F8F7"></td><td bgColor="#E0ECF8"></td><td bgColor="#E0E0F8"></td>
</tr><tr>
<td bgColor="#F5A9A9"></td><td bgColor="#F5D0A9"></td><td bgColor="#F2F5A9"></td><td bgColor="#D0F5A9"></td>
<td bgColor="#A9F5A9"></td><td bgColor="#A9F5D0"></td><td bgColor="#A9F5F2"></td><td bgColor="#A9D0F5"></td><td bgColor="#A9A9F5"></td>
</tr>
<table>
var ids = ['colorchart1', 'colorchart2'];
for(var j = 0; j < ids.length; j++) {
var t = document.getElementById(ids[j]).getElementsByTagName("td");
for ( var i = 0; i < t.length; i++ )
t[i].onclick = getVal;
}
Or - use jQuery and give all your tables a "colorchart" class then use the $('.colorchart') selector.

How to check current tag element in javascript?

I've a GridView with three rows like this
<tr>
<th>SlNo</th>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
I've the following code to traverse through the rows
var GridViewRow=GridView.getElementsByTagName('tr')
Here the row length is 3.
I travese through the GridViewRow using for loop .Here how will i get the tag name of the current element ie (th or td).
If the tagname is "TH" it should return and if it is "TD" it should take the value of TD.
How about this
var table = document.getElementById("mytab1");
for (var i = 0, cell; cell = table.cells[i]; i++) {
//iterate through cells
//cells would be accessed using the "cell" variable assigned in the for loop
}
you can also try out
var tbl = document.getElementById('yourTableId');
var rows = tbl.getElementsByTagName('tr');
for (var i = 0; i < rows.length; i++)
{
if(rows[i].getElementsByTagName('td').length > 0)
{
//code to execute
}
else
{
continue;
}
}
var GridViewRow = GridView.getElementsByTagName('tr');
$(GridViewRow).each(function() {
var $this = $(this), td = $this.find('td');
if (td.length === 1) {
console.log(td.text());
}
});
this works for <tr> in which you have exactly one <td> if you use jquery, otherwise in plain javascript try this:
var GridViewRow = GridView.getElementsByTagName('tr'),
len = GridViewRow.length,
td;
while (--len) {
td = GridViewRow[len].getElementsByTagName('td');
if (td.length === 1) {
console.log(td[0].innerHTML);
}
}
});
You can check the tag name with jQuery :
$(this).attr("tag");
Later edit:
For raw javascript, use tagName:
element.tagName

Categories