How can I use jQuery to access the cell (td) immediately below a given cell in a traditional grid-layout html table (i.e., one in which all cells span exactly one row and column)?
I know that the following will set nextCell to the cell to the immediate right of the clicked cell because they are immediate siblings, but I am trying to retrieve the cell immediately below the clicked cell:
$('td').click(function () {
var nextCell = $(this).next('td');
});
Preferably I would like to do it without any use of classes or ids.
Try this:
$("td").click(function(){
// cache $(this);
var $this = $(this);
// First, get the index of the td.
var cellIndex = $this.index();
// next, get the cell in the next row that has
// the same index.
$this.closest('tr').next().children().eq(cellIndex).doSomething();
});
$('td').click(function () {
var index = $(this).prevAll().length
var cellBelow = $(this).parent().next('tr').children('td:nth-child(' + (index + 1) + ')')
});
index is the 0-based index of the cell in the current row (prevAll finds all the cells before this one).
Then in the next row, we find the nth-child td at index + 1 (nth-child starts at 1, hence the + 1).
How about:
$('td').click(function () {
var nextCell = $(this).parent().next().find("td:nth-child(whatever)");
});
If you want to do it without using selectors, you can do:
function getNextCellVertically(htmlCell){
//find position of this cell..
var $row = $(htmlCell).parent();
var cellIndex = $.inArray(htmlCell, $row[0].cells);
var table = $row.parent()[0];
var rowIndex = $.inArray($row[0], table.rows);
//get the next cell vertically..
return (rowIndex < table.rows.length-1) ?
table.rows[rowIndex+1].cells[cellIndex] : undefined;
}
$('td').click(function () {
var nextCell = getNextCellVertically(htmlCell);
//...
});
Not that efficiency is important here but it works out much faster to do it like this - in tests over 100,000 iterations it was 2-5 times faster than the selector based approaches.
Are there an equal number of cells in each table row? If so, you could get the "count" of the cell in question, then select the corresponding cell in the next('tr').
Related
I have a table with this columns in HTML page. Razor is used for output. The values are generated dynamically from the database.
ID
Name
Week_1
Week_2
...
Week_52
1
Test1
3
1
2
Test2
2
3
3
3
Test3
5
1
And for example I want to hide column Week_52 because column has no values in all rows.
The column (table -> thead -> tr -> th) has no children, so I don't understand how they can be associated with values in (table -> tbody -> tr -> td).
How can I do this in vanilla javascript? Or maybe there is another solution?
Edited. 0 -> empty
I solved the problem. I added id="myAnchor" to the table with attribute data-currentweek. (I get currentweek value from database using Razor)
function hideWeekColumns(){
const myAnchor = document.getElementById("myAnchor");
currentweek = myAnchor.dataset.currentweek-1;
let weeks = document.getElementsByClassName('column week');
let weeks_array = Array.from( weeks );
weeks_array.splice(0, currentweek); // from position 0, remove 1 element
weeks_array.forEach(element => {
element.style.display = 'none';
});
};
hideWeekColumns();
A slightly different take on the last answer with comments, still in jquery though.
hideemptycols()
function hideemptycols() {
var hide = {} //set an object to track the qty of cells within each column that HAVE zero data
//to hide a column including header, all cells within need to be empty
$('table tbody tr').each(function () { // iterate through all rows
$(this).find('td').each(function (i, v) { // with each of the rows cells
if (!hide[i]) { hide[i] = 0 } //check if the object contains the column index, if not add it and give it a zero value
if ($.trim($(v).text()).length == 0) { //check the length of data if zero
$(v).hide()// hide the cell
}
else {
hide[i] += 1//add 1 against the column for every cell found with data
}
})
})
$.each(hide,function (index, EmptyQty) { //loop the object
if (EmptyQty == 0) { //with each column if the qty of cells with dataequals zero then hide the column
$('table tr th:nth-child(' + index + ')').hide()//get the column by index and hide
}
})
}
By Using jquery you can achieve this
The first step includes a jquery file and then
at bottom add
<script>
let hide = {}
for(let i = 1; i <= 52; i++){
hide[i] = true
}
$('table tbody tr').each(function(){
let cn = -1
$(this).find('td').each(function(){
if($.trim($(this).text()) != '0' && hide[cn]){
hide[cn] = false
}
cn++
})
})
console.log(hide)
for (var key of Object.keys(hide)) {
if(hide[key]){
$('table tr td:nth-child('+key+')').hide()
}
}
</script>
I am generating a table row which has two columns dynamically in html containing values from the database.
I want every td of the first column to have an unique id which i have done but i cant set the id to the td of last row in the table.
Here's the code to set id
<script>
var i=0;
var id=1;
while(i<100)
{
document.getElementsByTagName("td")[i].setAttribute("id", id);
i=i+2;
id=id+1;
}
</script>
Any help will be appreciated
but i cant set the id to the td of last row in the table.
You need to get to the last row in the table first.
var allRows = document.getElementsByTagName("tr");
var lastRow = allRows[allRows.length - 1];
now set Id to the first td of last row
lastRow.getElementsByTagName("td")[0].setAttribute("id" , allRows.length + 1 );
DOM Selectors are provided for a reason. :)
var tds = $('tr td:first-child');
var i=0;
$.each(tds, function(){
$(this).attr('id',i++);
});
OR
Using pure javascript
var tds = document.querySelectorAll('tr td:first-child');
var i = 0;
for(var td in tds){
tds[td].setAttribute('id',i++);
// or
//tds[td].id=(i++).toString();
};
You can use querySelectorAll to get all first td's withing given table using :first-child;
It will return NodeList which need to be convert into in an Array.
var arrTD = document.querySelectorAll("#list-notification tr td:first-child");
arrTD = Array.prototype.slice.call(arrTD);
var i =0;
arrTD.forEach(function(val,key){
val.setAttribute('id',i);
++i
})
I have a table with 2 columns. One column with a checkbox and another one with plain text. I would like to generate an object array with the the check state and the text. I can go tr after tr with this:
$('#divInfCambios .frozen-bdiv tr').each(function(i)
{ ... }
How can access to td[1], check the state, and recover the text of td[2]?
I got the check state with:
$(this).find('input[type="checkbox"]').prop('checked')
I need now how to access node 2 (td[1]) and grab the text.
//run through each row
$('#divInfCambios .frozen-bdiv tr').each(function (i, row) {
var getInputByName = $(this).find('input[name="selection"]');
if (getInputByName.is(':checked') ){
}
// assuming you layout of the elements
var tds = $(this).find('td');
var getTdText = tds.eq(1).text();
});
I have the following table: http://jsfiddle.net/UfhVc/1/
I am trying to:
Get the same style on all rows who have the same ID
Highlight the differences in each on the rows with the same ID.
But right now I can't seem to figure out the logic needed for step 1). It's ok to use jQuery, I just found it easier to use plain js.
Also, I get a warning in this part of the code:
table.rows[i+1].cells[0].innerHTML
Like this?
var newColor = "#F1D0F2";
var diffColor = "#CECECE";
$('#tbl tr:gt(0)').each(function () { //Loop through the trs leaving out the header
var txt = $(this).find('td:eq(0)').text(); //get the text of the id column
var $this = $(this);
var matchingRows = $('#tbl tr').not(this).filter(function () { //get the matching rows whose id colum value is same
return $(this).find('td:eq(0)').text() == txt;
}).css('background-color', newColor); //apply css for match
matchingRows.find('td').css('background-color', function (i) { //apply background color
if ($this.find('td:eq(' + i + ')').text() != this.innerHTML) return diffColor; // to the tds of matching rows but column valud differ.
});
});
Fiddle
References:
:gt()
filter()
css()
:eq()
Edit
Based on your comment here is the update:
var allColors = ["#333333","#990099", "#1295A6", "#FFFF99"]; //Set up the colors in to an array
var diffColor = "#CECECE";
$('#tbl tr:gt(0)').each(function () {
var txt = $(this).find('td:eq(0)').text();
var $this = $(this);
if($this.is('.transformed')) //check for class transformed is present if so this has already been processed skip it.
return;
//Get the matching rows whose id column value is same
var matchingRows = $('#tbl tr').filter(function () {
return $(this).find('td:eq(0)').text() == txt;
}).css('background-color', allColors.shift()).addClass('transformed'); //Set the color and add a class to avoid latter processing
matchingRows.find('td').css('background-color', function (i) { //apply background color
var $parTd = $this.find('td:eq(' + $(this).index() + ')');
if ($.trim($parTd.text()) != $.trim(this.innerHTML)) // to the tds of matching rows but column value differ.
{
$parTd.css('background-color', diffColor);
return diffColor;
}
});
});
Fiddle
For step one:
There are a few ways you can do it, I would probably attach a class to all table cells which are of a certain type, so you can easily select them all at once for editing.
<table>
<tr>
<td class="id-cell"></td>
</tr>
</table>
Then you could simply query it with CSS like:
.id-cell {
background-color:red;
}
But you can also just use more jQuery / JavaScript to find those table cells you're looking for anyways. This fiddle uses jQuery to find all the cells which are in the "id" column, and paint the background red.
http://jsfiddle.net/8QL22/
Another way of doing it:
$("table tr:not(:first-child) td:first-child").each(function(index) {
var thisId = $(this);
$("table tr:not(:first-child) td:first-child").each(function(_index) {
if (index != _index && thisId.text() == $(this).text())
{
thisId.parent("tr").css("backgroundColor", "red");
$(this).css("backgroundColor", "red");
$(this).siblings("td").each(function(sindex) {
var other = $(thisId.siblings()[sindex]);
if (other.text() != $(this).text())
other.css("backgroundColor", "yellow");
});
}
});
});
http://jsfiddle.net/w4mvp/
I have the following code:
$(document).ready(function() {
var id = 'cbx';
var idPrefix = 'Arrow';
var html = '<img .../>';
// query parent row
var rowq = $('#' + id);
if (rowq.length < 1) {
rowq = $('.' + id);
VersionHeader = true;
}
if (rowq[0]) {
rowq.addClass('ArrowHeader');
// set to 0 for header
var index = 0;
var row = rowq.parents('.g')[0].insertRow(index);
// assign id for new row
row.id = idPrefix + id;
// assign classes for style and tree
row.className = 'srcrow' + id;
// insert new cell
var cell = row.insertCell(0);
// assign html result
cell.innerHTML = html;
// set colspan
cell.colSpan = 1;
Now my problem is it adds the cell but it adds it under the first column. Is there a way to move through the columns? Granted I'm not an html expert at all. Just a beginner trying to get some stuff to work and would appreciate some help since I'm totally lost. I didn't include the html just ... through it.
Thanks
I'm not sure I'm understanding your question entirely correctly (I gather you are attempting to insert a cell into a new row, and you want to select into which column it is inserted?). Assuming that's what you meant:
row.insertCell(0)
This is your problem. The insertCell method takes as an argument the index of the column into which the cell should be inserted. Index 0 is the first column, index 1 is the second column, and so on. So try replacing the 0 with the appropriate index.