I would like to convert these for loops into jQuery but I am unsure how to do this. I am also unsure of how to convert document.querySelector. I tried to convert it like this:
$('.table1 tbody')
but it does not work when you call
tablebody.row[]
This is my code:
var headertext = [],
headers = $(".table1 th"),
tablebody = document.querySelector(".table1 tbody");
for(var i = 0; i < headers.length; i++) {
var current = headers[i];
headertext.push(current.textContent.replace(/\r?\n|\r/,""));
}
for (var i = 0, row; row = tablebody.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
col.setAttribute("data-th", headertext[j]);
}
}
Thanks
You can use map() to create an array from the attributes of the specified th elements. You can then loop through that array and set the data attribute on the required td elements.
That being said, you can change the logic entirely to do this in a single each() loop. Try this:
var $headers = $('.table1 th');
$('tr > td').each(function(i) {
$(this).data('th', $headers.eq($(this).index()).text().replace(/\r?\n|\r/, ""));
});
Working example
Note that jQuery keeps data attributes in an internal cache, so you won't see any changes to the DOM with the above code (which is why in the jsFiddle example I set the text() too). This is absolutely fine, you just need to remember to use jQuery's getter signature of data() to retrieve the attribute.
For your reference, your attempt to convert querySelector to $('.table1 tbody') didn't work because the jQuery version returns a jQuery object, not a DOMElement, and jQuery object's don't have rows property.
You can use each function in jquery to iterate over elements.
$('.table1 th').each(function(index){
var text=$(this).text();
});
And
$('.table1 tbody td').each(function(index){
var tdObject=$(this);
// loop for iterating over all the TDs of table.
// You can use tdObject to get text, class and other values.
// e.g. var id = tdObject.attr('id');
var text=tdObject.text();
});
Related
I need a way to get values and edit the values of an array returned by .find() example:
$container = $('#survey-types');
$slider = $container.find('#slide-container');
$slides = $slider.find('.slide');
for(let i = 0; i < $slides.length; i++){
console.log($slides[i].width());
}
But this gives me .width() is not a function
$slides[i] is an HTMLElement, not jQuery wrapper, and HTMLElement does not have a width() method. Try replacing $slides[i] with $slides.eq(i):
for(let i = 0; i < $slides.length; i++){
console.log($slides.eq(i).width());
}
You can also use the jQuery each() method, rather than writing your own for loop.
$slides.each(function(index, slide){
console.log($(slide).width());
//or you could still use eq
console.log($slides.eq(index).width());
});
I'm testing Datatables plugin and need some advice. My problem is that I can't delete a specific row in my table after ordering. For removing rows I use .index() method. Here is my fiddle
At first I find closest row:
var row = $(this).closest('tr');
then using this code to set index number:
var index = $("#example tbody").children().index(row);
And of course after ordering this index number changes.
Can you suggest something more efficient?
Considering name as unique entry:
var name = $(row).find('td:first').text();
for (var i = 0; i < dataSort.length; i++) {
if (dataSort[i][0] == name) {
break;
}
}
dataSort.splice(i, 1);
Fiddle here
this may be the code u needed...
var row = $(this).closest('tr');
var nRow = row[0];
dataTable.dataTable().fnDeleteRow(nRow);
I'm trying to make a JavaScript that alternates the color of each row in multiple tables. The catch is that some tables aren't going to be altered at all. So, I'm trying to use this code to get the rows of the table:
function alternateRows(myTable)
var rows = document.getElementsByTagName("table").getElementsByClassName(myTable).getElementsByTagName("tr");
And, in the HTML:
<body onload="alternateRows('myTable')";>
<table class="myTable">
I can get it to work just fine if I use the id attribute and change the JavaScript to:
var rows = document.getElementById(myTable).getElementsByTagName("tr");
Any suggestions would be great. Thanks!
getElementsByTagName returns a NodeList, thats why it called getElements not getElement. a NodeList does not have the "getElementsByClassName" method defined, that's the error you should see.
You'll need to use loops. Also know that you can use CSS selectors for this, all modern browsers support this except IE 8 and lower.
CSS for modern browsers (or IE8- with e.g. a helper library, like ie9.js)
table.mytable tr:nth-child(odd) {
background-color: black;
}
table.mytable tr:nth-child(even) {
background-color: white;
}
There are two kinds of DOM methods:
Methods which return a reference to a single node. For example getElementById and querySelector.
Methods which return a list of nodes. For example, getElementsByTagName, getElementsByClassName, querySelectorAll.
Those methods which return a list of nodes usually return a NodeList [MDN] object, which has a very limited interface. All you can do with it is access the single elements in the list, just like an array, it does not have the same interface as a DOM node (or element).
If you want to call further DOM methods or DOM properties on the elements in the list, you can either access a specific node directly with its index, or iterate over the list and do so for each element:
var elements = document.getElementsByTagName('div');
for(var i = 0, l = elements.length; i < l; i++) {
// do something with elements[i]
}
Note that NodeLists are usually live, which means any changes to the DOM (e.g. removing a div element) will update the list automatically.
In your particular situation, you have to options:
Use querySelectorAll to select all rows:
var rows = document.querySelectorAll('table.' + myTable + ' tr');
or iterate over the selected elements:
var rows = [];
var tables = document.getElementsByTagName("table");
for (var i = 0, l = tables.length; i < l; i++) {
// check whether it is a table with class in the variable `myTable`
if ((' ' + tables[i].className + ' ').indexOf(' ' + myTable + ' ') > -1) {
rows = rows.concat(tables[i].getElementsByTagName('tr'));
}
}
Instead of selecting the elements by tag name and then test their class, you could directly use getElementsByClassName instead, but it is not as widely supported as querySelectorAll.
If all of your tables must be modified in same way, you can use following code:
var tables = document.getElementByTagName("table");
for (var i in tables)
{
var rows = tables[i].getElementByTagName("tr");
//Alternating code here
}
Try this:
You can use only by getElementsByTagName or by getElementsByClassName
Like:
var rows = document.getElementsByTagName("table")[0].getElementsByTagName("tr");
or
var rows = document.getElementsByClassName('myTable')[0].getElementsByTagName("tr");
or use querySelectorAll
Syntax:
var matches = document.querySelectorAll("div.note, div.alert");
In your example:
var rows = document.querySelectorAll("table."+myTable).getElementsByTagName("tr");
getElementsByTagName gives array so you should use it with zero index
Same for getElementsByClassName
Read https://developer.mozilla.org/en-US/docs/DOM/element.getElementsByTagName
And
https://developer.mozilla.org/en-US/docs/DOM/document.getElementsByClassName
I am trying to access table cells in javascript using the getElementsByTagName method as shown below. Ultimately I want to compare each cell in the array to another value, and be able to change the background color of that cell according to the comparison.
var cells = document.getElementById("myTable").getElementsByTagName("tr");
for (i = 0; i < cells.length; i++)
{
cells[i] = cells[i].getElementsByTagName("td");
}
However, if I try to access cells[0][0], it returns undefined. I feel like I don't fully understand getElementsByTagName is doing... is there any hope for this method? Is there a more efficient one?
use jquery it will be simple :
var contentArray = new Array();
$('tr').each(function(indexParent) {
contentArray['row'+indexParent] = new Array();
$(this).children().each(function(indexChild) {
contentArray['row'+indexParent]['col'+indexChild] = $(this).html();
});
});
You can access any cell directly using the table element's .rows property, and the tr element's .cells property:
var myCell = myTable.rows[y].cells[x];
No need to build your own array.
So don't use .getElementsByTagName(), which returns a one-dimensional array. (Well, actually a NodeList, but you can use it like an array as long as you remember that it is live.)
If you did want to loop through all cells to compare them to some other value here's how, left to right, top to bottom using .rows and .cells:
var rows = document.getElementById("myTable").rows;
for (var y=0; y < rows.length; y++) {
for (var x=0; x < rows[y].length; x++) {
var cellAtXY = rows[y].cells[x];
cellAtXY.someProperty = something; // your code here
}
}
You need to do something like this for each row.
var row = table.getElementsByTagName('tr')[rowIndex];
var cells = row.getElementsByTagName('td');
then build your array from the contents of these variables.
Use this to get the table cells as 2D array
var tableRows = (document.getElementById("myTable")).getElementsByTagName("tr");
var cells = [];
for(var i = 0; i < tableRows.length; i++) {
cells.push(tableRows[i].getElementsByTagName("td"));
}
And now you can get any cell on your table using
cells[0][0]
Trying to create a table using the following code but not working. Please point out where I'm going wrong.
var i,j;
function cell(ih){
var tcell =document.createElement('td');
tcell.innerHTML=ih;
return tcell;
}
mutable=document.createElement('table');
for (i=0;i<10;i++){
row1=document.createElement('tr');
for(j=0;j<10;j++){
row1.appendChild(cell(j));
}
mutable.appendChild(row1);
document.write(mutable);
}
You have several problems, the first two are the big ones, the second two are a matter of style and risk of clashes with other code:
You are trying to document.write HTMLElementNodes. document.write only deals with strings. Grab a container element (e.g. with document.getElementById) and append to it
You are trying to document.write the entire table every time you add a row to it. Append the table once the table is complete, not every time you go through the loop.
You are using globals all over the place, learn to love the var keyword
row1 is a poor variable name for the row you are operating on which usually isn't the first
Use document.body.appendChild(...) instead of document.write(...).
You can do it by changing your script to use document.body.appendChild(mutable) after your nested for loop:
var i,j;
function cell(ih){
var tcell =document.createElement('td');
tcell.innerHTML=ih;
return tcell;
}
mutable=document.createElement('table');
for (i=0;i<10;i++){
row1=document.createElement('tr');
for(j=0;j<10;j++){
row1.appendChild(cell(j));
}
mutable.appendChild(row1);
}
document.body.appendChild(mutable);
This appends the entire mutable table object you've created to the <body> element of your page. You can see it working here.
Also note that most times in markup, you don't see the <tbody> element, but it is good practice to append this as a child element of the <table> and as a parent element for all of your rows. So, your script should look more like this:
function cell(ih){
var tcell = document.createElement('td');
tcell.innerHTML = ih; // I would suggest you use document.createTextNode(ih) instead
return tcell;
}
function appendTable() { // you now have to call this function some time
mutable = document.createElement("table");
var tBody = mutable.appendChild( document.createElement("tbody") ); // technique using "fluid interfaces"
for (var i = 0; i < 10; i++) {
var row1 = tBody.appendChild( document.createElement('tr') ); // fluid interface call again
for(var j = 0; j < 10; j++) {
row1.appendChild(cell(j));
}
}
document.body.appendChild(mutable);
}
I made some style changes to your script, and I would suggest making even more, but as far as correctness, it should work.