I have this table, and I can't seem to find out how to unselect marked field, if it's clicked again? So a double-click on id 2 would select->unselect.
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
I thought about making some kind of count on the rowID, so if it's clicked more than once after each other, then it would toggle between select/unselect?
You can solve it by doing something similar to this, this will first check the selected row for the selected class and remove it if it is found, otherwise, it'll add it to the row you clicked. After that is done, this function will loop through all other rows, check if they aren't the clicked row and remove the selected state accordingly.
So now once you click, your code will look for selected on the row you clicked, if it is found, it'll remove that class to reset the styling, if it isn't found, it'll add the selected class. After this, the code will check all rows to see if they're not the selected row and style them accordingly.
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function() {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
if(row !== rowId) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
if (rowSelected.classList.contains('selected')) {
rowSelected.style.backgroundColor = "";
rowSelected.classList.remove('selected');
} else {
rowSelected.style.backgroundColor = "yellow";
rowSelected.classList.add("selected");
}
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
Hope this helps!
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
if(row!==rowId){
rowsNotSelected[row].style.backgroundColor = "white";
rowsNotSelected[row].classList.remove('selected');
}
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
if(rowSelected.classList.contains("selected")) {
rowSelected.style.backgroundColor = "";
rowSelected.classList.remove("selected");
}
else{
rowSelected.style.backgroundColor = "yellow";
rowSelected.classList.add("selected");
}
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
I'd do it like this
var selected;
(function () {
var rows = document.querySelectorAll('#testresultsTable > tbody > tr');
rows.forEach(tr => tr.addEventListener('click', () => {
if(selected === tr){
selected.classList.remove('selected');
selected = undefined;
}
else {
if(selected) selected.classList.remove('selected');
selected = tr;
tr.classList.add('selected');
}
}));
})();
tbody > tr {
cursor: pointer;
user-select: none;
}
tr.selected {
background-color: yellow;
}
<table id="testresultsTable">
<thead><th>ID</th><th>Tests</th></thead>
<tbody>
<tr><td>1</td><td>TESTRUN1</td></tr>
<tr><td>2</td><td>TESTRUN2</td></tr>
<tr><td>3</td><td>TESTRUN3</td></tr>
</tbody>
</table>
Related
Supposed that I have a table like this on a webpage with the id ='table':
Name Age Money(USD) DATE
A 19 4 2019-03-11 16:15:35
B 20 0 2019-03-11 16:16:37
C 27 3 2019-03-13 04:15:43
D 34 0 2019-03-13 04:16:57
Could you help me find the FIRST SMALLEST VALUE IN THE MONEY COLUMN, which is 0 for B in the Column1 and HIGHLIGHT the whole table row for B, using javascript without using any library and any button onClicking?
Note: I have searched around and just been unlucky enough to find the correct answer to my problem.
Thanks.
UPDATE:I just got a piece of javacript like this to get the first smallest value and print it out, but not be able to highlight the whole row with it
var table = document.getElementById("table"), minVal;
for(var i = 1; i < table.rows.length; i++)
{
// if its the first row get the value
if(i === 1){minVal = table.rows[i].cells[2].innerHTML; }
// test with the other values
else if(minVal > table.rows[i].cells[2].innerHTML){
minVal = table.rows[i].cells[2].innerHTML;
}
}
document.getElementById("val").innerHTML = " Minimum Value = "+minVal;
console.log(maxVal);
var table = document.getElementById("table"), minVal, minI;
for(var i = 1; i < table.rows.length; i++){
if(i === 1){
minVal = table.rows[i].cells[2].innerHTML;
}
else if(minVal > table.rows[i].cells[2].innerHTML){
minVal = table.rows[i].cells[2].innerHTML;
minI = i;
}
}
table.rows[i].cells[2].innerHTML = '<span style="background:red">' + table.rows[minI].cells[2].innerHTML + '</span>';
Something like that.
var table = document.getElementById("table");
var minVal = undefined;
for(var i = 1; i < table.rows.length; i++)
{
if(i === 1){
minVal = table.rows[i].cells[2];
}
else if(minVal.innerHTML > table.rows[i].cells[2].innerHTML){
minVal = table.rows[i].cells[2];
}
}
minVal.parentElement.style.background="yellow";
There are two things you need to do:
Convert innerHTML to a number using +
Keep track of the row number while looping.
This is the code
var table = document.getElementById("table"), minVal;
let minRow = 1;
for(var i = 1; i < table.rows.length; i++)
{
// if its the first row get the value
if(i === 1){
minVal = +table.rows[i].cells[2].innerHTML;
}
// test with the other values
else if(minVal > table.rows[i].cells[2].innerHTML){
minVal = table.rows[i].cells[2].innerHTML;
minRow = i;
}
}
let row = table.rows[minRow];
row.style.backgroundColor = 'red';
This simply keeps track of the minimum row, and lets you hang your formatting off of that:
const highlightLowest = () => {
var rows = table.rows;
var minRow = rows[0]
for (var i = 1; i < rows.length; i++){
rows[i].classList.remove('highlight')
if (Number(rows[i].cells[2].innerHTML) < Number(minRow.cells[2].innerHTML)) {
minRow = rows[i]
}
}
minRow.classList.add('highlight')
}
tr.highlight td {background-color: yellow}
<table id="table">
<tr><td>A</td><td>19</td><td>4</td><td>2019-03-11 16:15:35</td></tr>
<tr><td>B</td><td>20</td><td>0</td><td>2019-03-11 16:16:37</td></tr>
<tr><td>C</td><td>27</td><td>3</td><td>2019-03-13 04:15:43</td></tr>
<tr><td>D</td><td>34</td><td>0</td><td>2019-03-13 04:16:57</td></tr>
</table>
<hr />
<button onClick="highlightLowest()">Highlight</button>
Here you go. The function 'highlight' takes the column that you want to base your highlighting upon as an argument.
// Get your table's headers
headers = document.querySelectorAll('#table tbody tr th')
// Get your table's headers
rows = document.querySelectorAll('#table tbody tr')
// Declaring function that takes wanted column as argument
highlight = (colName) =>{
let min = 0;
for(i=0;i<headers.length;i++){
if(headers[i].innerText == colName){
for(j=1;j<rows.length;j++){
value = parseInt(rows[j].children[i].innerHTML);
if(j == 1){
min = value;
}
if(value < min){
rows[j].style.backgroundColor = "yellow"
break;
}
}
}
}
}
<table id="table">
<tbody><tr>
<th>Test 1</th>
<th>Test 2</th>
<th>Test 3</th>
</tr>
<tr>
<td>7</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>3</td>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>12</td>
<td>1</td>
<td>5</td>
</tr>
<tr>
<td>15</td>
<td>89</td>
<td>4</td>
</tr>
<tr>
<td>3</td>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
</tbody></table>
<input type='text' id='col'>
<button onclick=highlight(document.getElementById('col').value)>Highlight based on input column</button>
I'm trying to add rows and columns to a table using user input values to determine the number of rows and columns dynamically using jQuery. Below is my code which actually adds rows and columns but not according to the user's inputs
function makeGrid() {
let numOfRow = 0; let numOfCol = 0;
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
for (var i = 1; i <= numOfRow; i++) {
let row = $('.grid-canvas').append('<tr>');
for (col = 1; col <= numOfCol; col++) {
$('tr').append('<td></td>');
}
}
});
}
makeGrid();
Assuming a user inputs numOfRow = 2 and numOfCol = 2, I should have a table like this
<tbody class="grid-canvas">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
Problem is my code seems to be adding extra but I haven't been able to figure it out. This is the result of my code
<tbody class="grid-canvas">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
How do I fix my code?
try changing your code from:
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
for (var i = 1; i <= numOfRow; i++) {
let row = $('.grid-canvas').append('<tr>');
for (col = 1; col <= numOfCol; col++) {
$('tr').append('<td></td>');
}
}
});
into this
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
var body = $('.grid-canvas');
for (var i = 1; i <= numOfRow; i++) {
let row = $('<tr></tr>');
for (col = 1; col <= numOfCol; col++) {
row.append('<td></td>');
}
body.append(row);
}
});
what i have done in the above code is created a separate object for the table's body and then once my rows are created with the columns, I append them back to the table object.
Pure javascript code is here
function f(x, y) {
var rows = x,
rowButtonNumber = y;
var table = document.getElementById("myTable");
table.innerHTML = "";
for (var i = 0; i < rows; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < rowButtonNumber; j++) {
var td = document.createElement("td");
var btn = document.createElement("button");
btn.innerHTML = "btn " + (i + 1);
btn.id = "btn-" + i;
btn.onclick = function() {
alert(this.innerHTML);
};
td.appendChild(btn);
tr.appendChild(td);
}
}
}
function go() {
var row = document.getElementById("row").value;
var col = document.getElementById("col").value;
f(row, col);
}
<html>
<head>
<style>
td {
width: 200px;
height: 200px;
}
button {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
Rows
<input id="row" type="number" placeholder="Rows" />
<br> Columns
<input id="col" type="number" placeholder="Columns" />
<button onclick="go()">Go</button>
<table id="myTable" cellspacing="50">
</table>
</body>
It does not seem you are using the row variable. I would suggest appending newly created td to row instead of $('tr').
I need to move the row/s that is matched with the inputted string.
on the code below you need to click first the row before you can move that particular row to the top.
Instead of clicking the row, I just wanted to input a string or char then onclick, if there's a match on the html table, the row that matched or like on the string inputted will be moved on the top of the table grid.
var index;
function getSelectedRow() {
var table = document.getElementById("table");
for (var i = 1; i < table.rows.length; i++) {
table.rows[i].onclick = function() {
if (typeof index !== "undefined") {
table.rows[index].classList.toggle("selected");
}
index = this.rowIndex;
this.classList.toggle("selected");
};
}
}
getSelectedRow();
function upNdown(direction) {
var rows = document.getElementById("table").rows,
parent = rows[index].parentNode;
if (direction === "up") {
if (index < rows.length) {
parent.insertBefore(rows[index], rows[index - index + 1]);
index--;
}
}
}
<table id="table" border="1">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<tr>
<td>A1</td>
<td>B1</td>
<td>C1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
<td>C2</td>
</tr>
<tr>
<td>A3</td>
<td>B3</td>
<td>C3</td>
</tr>
</table>
<input type="text" id="txt">
<button onclick="upNdown('up');">↑</button>
what I need to do is upon click of the button, find the matching data and move the row to the top.
If I correctly understand you problem, Think this is your answer. This code find the first match of input and move that to first row. If the input be empty, it will do nothing.
var index = 0;
function findMatchRow(rows, str) {
if (!str.length) {
return null;
}
for (var i = 1; i < rows.length; i++) {
for (var j = 0; j < rows[i].children.length; j++) {
if (rows[i].children[j].textContent.match(str)) {
return i;
}
}
}
return 0;
}
function getSelectedRow() {
var table = document.getElementById("table");
for (var i = 1; i < table.rows.length; i++) {
table.rows[i].onclick = function() {
if (typeof index !== "undefined") {
table.rows[index].classList.toggle("selected");
}
index = this.rowIndex;
this.classList.toggle("selected");
};
}
}
getSelectedRow();
function upNdown(direction) {
var rows = document.getElementById("table").rows,
parent = rows[index && index > -1 ? index : 0].parentNode,
inpt = document.getElementById("txt").value;
var matchedRow = findMatchRow(rows, inpt);
if (matchedRow) {
if (direction === "up") {
index = matchedRow;
parent.insertBefore(rows[index], rows[index - index + 1]);
index--;
if (index < 0) {
index = rows.length - 1;
}
}
}
}
<table id="table" border="1">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<tr>
<td>A1</td>
<td>B1</td>
<td>C1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
<td>C2</td>
</tr>
<tr>
<td>A3</td>
<td>B3</td>
<td>C3</td>
</tr>
</table>
<input type="text" id="txt">
<button onclick="upNdown('up');">↑</button>
I have a DataTable that stores names only. I want to have a button that will add all the names in the DataTable to an text input field.
<div id="myTabDiv">
<table name="mytab" id="mytab1">
<thead>
<tr>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>chris</td>
</tr>
<tr>
<td>mike</td>
</tr>
</tbody>
</table>
<button id="add" >ADD</button>
<input type="text" id="text">
</div>
After click the "add" button, I want the names to appear in the text field separated by a comma.
And if possible, If the button is clicked again, remove the names?
I created the whole solution on codepen. This is the function used:
var clicks = 0;
function csv() {
var box = document.getElementsByName('text')[0];
if(clicks === 0){
var newcsv = "";
var tds = document.getElementsByTagName("TD");
for(var i = 0; i < tds.length; i++)
{
newcsv += tds[i].innerHTML;
if(i != tds.length-1) newcsv += ",";
}
box.value = newcsv;
clicks++;
}
else{
clicks = 0;
box.value = "";
}
}
This is bound to onclick event of a button.
Assign id to input
<input type=text id="textbox"/>
Just loop though table
var table = document.getElementById("mytab1");
var textbox=document.getElementById("textbox")
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
if(textbox.value=="")
{
textbox.value=row.cells[j].innerText;
}
else
{
textbox.value+= textbox.value+','+row.cells[j].innerText;
}
}
}
I want to cut table after tr to insert a div and re-open the table :
Before :
<table>
<tr onClick="cutAfter(this);">
<td>bla</td><td> 123 </td><td>Yes </td>
</tr>
<tr onClick="cutAfter(this);">
<td>bli</td><td> 456 </td><td>no</td>
</tr>
<tr onClick="cutAfter(this);">
<td>blu</td><td> 789 </td><td>hum</td>
</tr>
</table>
After :
<table>
<tr onClick="cutAfter(this);">
<td>bla</td><td> 123 </td><td>Yes </td>
</tr>
<tr onClick="cutAfter(this);">
<td>bli</td><td> 456 </td><td>no</td>
</tr>
</table>
<div onClick="fuse(this)">It works</div>
<table>
<tr onClick="cutAfter(this);">
<td>blu</td><td> 789 </td><td>hum</td>
</tr>
</table>
And return to first state on click.
Any idea (no jQuery).
A simple whay to do it is to use combination of DOM manipulation methods like insertAdjacentHTML to create new table and appendChild to move rows into new table:
function cutAfter(row) {
var table = row.parentNode.parentNode;
if (row.nextElementSibling) {
table.insertAdjacentHTML('afterend', '<table><tbody></tbody></table>');
var newTable = table.nextElementSibling.tBodies[0];
while (row.nextElementSibling) {
newTable.appendChild(row.nextElementSibling);
}
}
}
table {
margin-bottom: 10px;
}
table td {
border: 1px #AAA solid;
}
<table>
<tr onClick="cutAfter(this);">
<td>bla</td><td> 123 </td><td>Yes </td>
</tr>
<tr onClick="cutAfter(this);">
<td>bli</td><td> 456 </td><td>no</td>
</tr>
<tr onClick="cutAfter(this);">
<td>blu</td><td> 789 </td><td>hum</td>
</tr>
</table>
Here's a simple example, made of an HTML file (the structure) and a Javascript file (the behavior). The script uses node manipulation, so as to preserve existing handlers (e.g. added by other scripts). It also attaches event handlers directly, using element.onxxx, to keep things simple, but you should replace that by your favorite event manager.
var makeSplittable = function(table, joinText) {
init();
function init() {
var tBodies = table.tBodies;
for (var ii = 0; ii < tBodies.length; ii++) {
var rows = tBodies[ii].rows;
for (var j = 0; j < rows.length; j++) {
rows[j].onclick = split; // Replace with your favorite event manager
}
}
}
function split(evt) {
var rowIndex = this.rowIndex;
var tbody = findParent(this, "tbody");
var numRows = tbody.rows.length;
if (rowIndex < numRows - 1) {
var rows = [];
for (var ii = rowIndex + 1; ii < numRows; ii++) {
rows.push(tbody.rows[ii]);
}
var existingTable = findParent(this, "table");
var newTable = createTable(rows);
var joiner = createJoiner();
existingTable.parentNode.insertBefore(newTable, existingTable.nextSibling);
existingTable.parentNode.insertBefore(joiner, existingTable.nextSibling);
}
}
function createTable(rows) {
var table = document.createElement("table");
var tbody = document.createElement("tbody");
for (var ii = 0; ii < rows.length; ii++) {
tbody.appendChild(rows[ii]);
}
table.appendChild(tbody);
return table;
}
function createJoiner() {
var div = document.createElement("div");
var content = document.createTextNode(joinText);
div.appendChild(content);
div.onclick = join; // same
return div;
}
function join(evt) {
var previousTable = this.previousSibling;
var nextTable = this.nextSibling;
var tbody = previousTable.tBodies[previousTable.tBodies.length - 1];
var rows = nextTable.rows;
while (rows.length) {
tbody.appendChild(rows[0]);
}
nextTable.parentNode.removeChild(nextTable);
this.parentNode.removeChild(this);
}
function findParent(element, type) {
if (!element || !type) {
return null;
}
if (element.nodeName.toLowerCase() == type.toLowerCase()) {
return element;
}
return findParent(element.parentNode, type);
}
};
makeSplittable(document.getElementById("target"), "Merge adjacent tables");
table,
div {
margin: 5px 0;
}
tr:hover td {
background-color: orange;
}
td {
background-color: yellow;
cursor: pointer;
padding: 10px;
}
div {
color: #0c0;
cursor: pointer;
}
<table id="target">
<tr>
<td>bla</td>
<td>123</td>
<td>Yes</td>
</tr>
<tr>
<td>bli</td>
<td>456</td>
<td>no</td>
</tr>
<tr>
<td>blu</td>
<td>789</td>
<td>hum</td>
</tr>
</table>
A possibility, assuming that a DIV should not be inserted after the last TR if there has not been a cut, but it would have been nice to see your effort. Also assuming no <thead> or <tfoot>.
function isTagName(element, tagName) {
return element.tagName.toUpperCase() === tagName.toUpperCase();
}
function getClosest(element, tagName) {
var closest = null;
while (element !== document && !isTagName(element, tagName)) {
element = element.parentNode;
}
if (element !== document && isTagName(element, tagName)) {
closest = element;
}
return closest;
}
function insertAfter(newNode, referenceNode) {
return referenceNode.parentNode
.insertBefore(newNode, referenceNode.nextSibling);
}
function moveAppend(list, dest, from) {
var index = list.length - 1,
last;
for (last = from || 0; index >= last; index -= 1) {
dest.appendChild(list[index]);
}
return dest;
}
document.body.addEventListener('click', function(e) {
var target = e.target,
tr = getClosest(target, 'tr'),
newDiv,
newTable,
newBody,
next,
parent;
if (tr) {
if (tr.rowIndex < tr.parentNode.rows.length - 1) {
newDiv = document.createElement('div');
newDiv.appendChild(document.createTextNode('It works!'));
insertAfter(newDiv, getClosest(tr, 'table'));
newTable = document.createElement('table');
newBody = document.createElement('tbody');
moveAppend(tr.parentNode.rows, newBody, tr.rowIndex + 1);
newTable.appendChild(newBody);
insertAfter(newTable, newDiv);
}
} else if (isTagName(target, 'div') &&
isTagName(target.previousElementSibling, 'table') &&
isTagName(target.nextElementSibling, 'table')) {
next = target.nextElementSibling;
moveAppend(next.tBodies[0].rows, target.previousElementSibling.tBodies[0]);
parent = target.parentNode;
parent.removeChild(next);
parent.removeChild(target);
}
}, false);
table,
td {
border-style: solid;
border-width: 1px;
}
div {
background-color: yellow;
}
<table>
<tr>
<td>bla</td>
<td>123</td>
<td>Yes</td>
</tr>
<tr>
<td>bli</td>
<td>456</td>
<td>no</td>
</tr>
<tr>
<td>blu</td>
<td>789</td>
<td>hum</td>
</tr>
</table>