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.
Related
I am trying to update a table once a button is clicked. I have created the table and the button with the following HTML code
<button type="button" onclick="calculateMatrixFact()">Calculate MF!</button>
<table id = "matrix_factorization">
<tr>
<th>User</th>
<th>Movie One</th>
<th>Movie Two</th>
</tr>
</table>
While the function that I am calling on the onclick event, is the following:
function calculateMatrixFact(){
var cache = CacheValues();
// split the array in two single arrays one per each user and movie
var user_matrix = createGroups(cache.mu, 2);
var score_matrix = createGroups(cache.ms, 2);
// remove the string user_name and movie_name
for (let i = 0; i < user_matrix.length && i < score_matrix.length; i++) {
user_matrix[i].shift();
score_matrix[i].shift();
}
var dot_matrix = [];
// perform the dot product
for (let j = 0; j < user_matrix.length; j++) {
for (let k = 0; k < score_matrix.length; k++) {
//console.log(user_matrix[j])
//console.log(score_matrix[k])
var dot_product = math.multiply(user_matrix[j], score_matrix[k]);
dot_matrix.push(dot_product);
}
}
// create the matrix and push back the string (first column of the table)
var dot_prod_matrix = createGroups(dot_matrix, 2);
dot_prod_matrix[0].unshift("Anna");
dot_prod_matrix[1].unshift("Jonny");
// from array to HTML table
fetch = document.getElementById('matrix_factorization');
for (var i = 0; i < dot_prod_matrix.length; i++) {
var newRow = fetch.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
}
I think the problem is that I do not reset the table each time the button is clicked, is that right? How can I delete the old info and insert the new ones?
Here you can see the full code: https://jsfiddle.net/932ebu0v/7/
Because of this block in very last of your function:
fetch = document.getElementById('matrix_factorization');
for (var i = 0; i < dot_prod_matrix.length; i++) {
var newRow = fetch.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
The fetch will get the existing table that having rows and you just inserting new rows into it.
Then, you can just clear whole table, re-add the header and insert the row (the clear and re-instantiation of the header would be done in one line of code !!):
fetch = document.getElementById('matrix_factorization');
// Just use this line to clear whole table and put back the header row
fetch.innerHTML = `<tr>
<th>User</th>
<th>Movie One</th>
<th>Movie Two</th>
</tr>`; // Put your whole <th> here.
// as for the rest, just let it be
for (var i = 0; i < dot_prod_matrix.length; i++) {
var newRow = fetch.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
A simple solution would be to keep the 1st row in the <thead> element, given that it functions as the table's header. The rest of the rows go inside the <tbody> element. Only the table body is reset each time the button is clicked.
// access tbody (thead remains unimpacted)
var mfTableBody = document.querySelector('#matrix_factorization tbody');
mfTableBody.innerHTML = ''; // clear tbody
for (var i = 0; i < dot_prod_matrix.length; i++) {
// insert tr inside tbody
var newRow = mfTableBody.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
<table id="matrix_factorization">
<thead>
<tr>
<th>User</th>
<th>Movie One</th>
<th>Movie Two</th>
</tr>
</thead>
<tbody></tbody>
</table>
This JavaScript code makes tables responsive:
/* Credits:
https://gist.github.com/jpen365/f34bbff7d9db99f912e1e75193071718 */
var headertext = [];
var headers = document.querySelectorAll("thead");
var tablebody = document.querySelectorAll("tbody");
for (var i = 0; i < headers.length; i++) {
headertext[i]=[];
for (var j = 0, headrow; headrow = headers[i].rows[0].cells[j]; j++) {
var current = headrow;
headertext[i].push(current.textContent);
}
}
for (var h = 0, tbody; tbody = tablebody[h]; h++) {
for (var i = 0, row; row = tbody.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
col.setAttribute("data-th", headertext[h][j]);
}
}
}
My question is how to exclude tables using class all tables with this class is-style-stripes for example this table:
<table class="wp-block-table aligncenter is-style-stripes">
<tbody>
<tr>
<th>Company</th><td>Amazon</td>
</tr>
<tr>
<th>Company</th><td>Google</td>
</tr>
</tbody>
</table>
If you want to get all tables without class you can use
document.querySelectorAll("table:not(.is-style-stripes)")
You will get all tables without that class
If you want tables with this class just use
document.querySelectorAll("table.is-style-stripes")
Then you can search for it's tbody or thead like
table.querySelectorAll("tbody")
I have a problem. I need insert cell in a row. The content of cell is an element of an array. But is duplicate... Here my code:
function addFila() {
var iframe = document.getElementById('myFrame');
var table = iframe.contentDocument.getElementsByClassName("head_to_head h2h_home")[0];
var row = table.insertRow(1);
var fila = ["fecha", "liga", "equipolocal", "equipovisitante", "goleslocal", "golesvisitante"];
for (let i = 0; i < 6; i++) {
row.insertCell(i);
for (let x = 0; x <= fila.length; x++) {
row.insertCell(i).innerHTML = fila[i];
}
}
}
What is wrong?
row.insertCell() return new cell. If you want to create cell and use it you should save created cell in variable. You get duplicate because you call insertCell twice. I hope code below can help you
var table = document.querySelector(".table");
var row = table.insertRow(-1);
var fila = ["fecha", "liga", "equipolocal", "equipovisitante", "goleslocal", "golesvisitante"];
for (let i = 0; i < fila.length; i++) {
const insertedCell = row.insertCell(i);
insertedCell.textContent = fila[i];
}
table td {
border: 1px solid lime;
}
<table class="table">
<tbody>
<tr>
<td>cell_1_1</td>
<td>cell_1_2</td>
</tr>
<tr>
<td>cell_2_1</td>
<td>cell_2_2</td>
</tr>
</tbody>
</table>
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>
I am trying on following code;
Why doesn't deleteRow() alert "hi" when we click on delete button for first time (nor it delete row)?
Surprisingly it will work perfectly second time.
HTML
<div style="height: 190px;overflow: auto;left:220px;width:710px;" id="filterTable">
<table id="filterTableBody" style="border-collapse: collapse; border: 1px solid black;width:690px;" border="1">
<tbody><tr bgcolor="#FF6600">
<td><strong>
and/or
</strong></td>
<td><strong>
Column Name
</strong></td>
<td><strong>
operator
</strong></td>
<td><strong>
Filter
</strong></td>
<td><strong>
Delete
</strong></td>
</tr>
<tr><td> </td><td>WORKGROUP_NAME</td><td>!=</td><td>ABDEL HAMEID</td><td><img src="/images/delete.gif"></td></tr></tbody></table>
</div>
Javascript
function deleteRow(){
var table = document.getElementById('filterTableBody');
var rows1 = table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
for (var i = 0; i < rows1.length; i++) {
rows1[i].onclick = (function() {
alert("hi");
table.deleteRow(this.rowIndex);
var oTable = document.getElementById('filterTableBody');
//gets rows of table
var rowLength = oTable.rows.length;
for (i = 1; i < rowLength; i++){
var oCells = oTable.rows.item(i).cells;
//gets cells of current row
var cellLength = oCells.length-1;
for(var j = 0; j < cellLength; j++){
oCells.item(j).innerHTML = "";
break;
}
break;
}
});
}
}
Why doesn't the code run in first click and why it runs in the second?
The reason is because the onclick event handler for the rows are getting attached only when the Delete button is clicked for the first time.
They have to be attached onload itself. You can do it like below:
window.onload = deleteRow;
Demo Fiddle
This code works for me. Thank you #harry for pin pointing the problem.
function deleteRowUI(btndel) {
var table=document.getElementById('filterTableBody');
if (typeof(btndel) == "object") {
p=btndel.parentNode.parentNode;
p.parentNode.removeChild(p);
var oTable = document.getElementById('filterTableBody');
//gets rows of table
var rowLength = oTable.rows.length;
for (var i = 1; i < rowLength; i++){
var oCells = oTable.rows.item(i).cells;
//gets cells of current row
var cellLength = oCells.length-1;
for(var j = 0; j < cellLength; j++){
oCells.item(j).innerHTML = "";
break;
}
break;
}
} else {
return false;
}
}