Cannot read property 'rowIndex' of undefined for my javascript code - javascript

<script>
var cell = document.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
cell[i].onclick = function(){alert("Hello world");};
var col = this.cellIndex;
var row = this.parentNode.rowIndex;
}
</script>
So I have a table, a HTML table. And I am trying to get the column and row of the part of the table that was clicked on, and I am using cell index, and row index. However this is not working and is pulling up the error " cannot read property rowindex of undefined" i couldnt find this error anywhere online..

As referenced in comments, this will reference the window inside of a for loop, additionally, you're creating your function for alert within the for loop, not something you want to do as this may create weird behaviors. I think what you're trying to achieve will work better with the code below. Tip, unless you need the index you should take advantage of the much simpler "for of" loop.
function createAlert(td) {
alert("Hello world")
var col = this.cellIndex;
var row = this.parentNode.rowIndex;
console.log('the col and row:::::', col, row)
}
var cell = document.getElementsByTagName("td");
for (let td of cell) {
td.onclick = createAlert
}
<table>
<td>hello</td>
<td>hello2</td>
<td>hell3</td>
<td>hello4</td>
<td>5 hello</td>
<td>hello6</td>
</table>

Related

Countng number of rows of table and getting every cell value

My question is that I have found the code to traverse every row and cell but I am not able to understand how do i fetch every cell value with this code ? Can anyone help me with this code. I want to use this code only in my project.
Here is my js code
var table = document.getElementById('tblOne');
var rowCount = $('.table tr').length - 1;
for(var i=0; i<rowCount; i+=1){
var row = table.rows[i];
//your code goes here, looping over every row.
//cells are accessed as easy
var cellLength = row.cells.length;
for(var y=0; y<cellLength; y+=1){
var cell = row.cells[y];
console.log(cell);
//do something with every cell here
}
}
Following will help
var cell = row.cells[y];
console.log($(cell).text());

Inserting Drop-Down List in Table with Javascript

I have created a function to make a table from arrays of data which will resize according to the amount of data.
I would like to add a drop-down list to each row, but am having a problem getting it to appear. I know it is something simple, but I cannot find out what is happening.
The section in question is:
for (var i = 1; i < chosenArray.length + 1; i++) {
var thisRow = table.rows[i];
var cell = thisRow.insertCell(columnCount - 1);
cell.innerHTML = mySelectBox;
}
I get the error: "ReferenceError: mySelectBox is not defined"
Full code here: https://jsfiddle.net/qamzen2k/12/
Any help would be welcomed!

Create an array from JSON in Javascript

I've researched quite a bit on here and I can't seem to find something that will work for me. What I have is an application that I'm trying to have go out and return the next four bus arrival times for a bus stop. I am reaching out to an API that returns this data in a JSON file. The problem I am having is I can see my request go out via fiddler but I can't seem to get the data into an array. Below is the code that I'm dealing with right now. I'm trying to get the returned data into a table format which you can see I'm failing at.
Eventually I want to get a popup to appear when the user clicks on the Show me the next 4 bus arrival times but this was for testing purposes. I would love to have the users click on my button which calls this function and then something like a like table open with these values. If you can help with that within this code I would appreciate it as well.
JSON Data:
[{"ARRIVAL":"01:23P","ROUTE":"208","DIR":"E"},
{"ARRIVAL":"01:53P","ROUTE":"208","DIR":"E"},
{"ARRIVAL":"02:23P","ROUTE":"208","DIR":"E"},
{"ARRIVAL":"02:53P","ROUTE":"208","DIR":"E"}]
Code:
<script>
function getTimes(stopNumber) {
var busArrivalAPI = "http://blahblahblah/rtcTimes/" + stopNumber ";
$.getJSON(busArrivalAPI, function(busArrivals) {
var a = [];
for (var i = 0; i < busArrivals.length; i++) {
a[i] = [busArrivals[i].ROUTE, busArrivals[i].ARRIVAL, busArrivals[i].DIR];
document.getElementById("results").createElement("TR");
for (var b = 0; b < 3; b++) {
var x = document.createElement("TH");
var z = a[i][b];
var t = document.createTextNode(z);
x.appendChild(t);
document.getElementById('results').appendChild(x);
};
};
});
</script>
My DIV:
<div style="overflow-x:scroll; overflow-y:scroll;" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title:'Bus Arrival Times', selected:true">
<table id = 'results'>
<tr>
<th>Route</th>
<th>Arrival Time</th>
<th>Direction</th>
</tr>
</table>
</div>
UPDATE: Ok, I've use the makeTable idea provide below and it works when I program as seen below hard coding the json data. However, when trying to use the $.getJSON I'm having some cross domain issues now and don't know how I can get my $.getJSON request working. Any input on how to get the data from my getJSON request work be great.
function getTimes(stopNumber) {
// This is the API address I need to hit. Trying to figure out how to incorporate that and remove the function getJSON where I have the data hard coded.
//var busArrivalAPI = "http://-----/rtcTimes/"+ stopNumber + "?jsoncallback=?";
function makeTable(busArrivals) {
// This will remove old values so table will only load current Times
var results = document.getElementById("results");
var rowCount = results.rows.length;
for (var x=rowCount-1; x>0; x--) {
results.deleteRow(x);
}
// This will populate the result table with the correct bus routes/times/direction
busArrivals.forEach(function(busArrival) {
var tr = document.createElement('tr');
var route = document.createElement('td');
route.appendChild(document.createTextNode(busArrival.ROUTE));
var arrival = document.createElement('td');
arrival.appendChild(document.createTextNode(busArrival.ARRIVAL));
var direction = document.createElement('td');
direction.appendChild(document.createTextNode(busArrival.DIR));
tr.appendChild(route);
tr.appendChild(arrival);
tr.appendChild(direction);
document.getElementById('results').appendChild(tr);
});
}
function getJSON(callback) {
var data = [{"ARRIVAL":"05:23P","ROUTE":"201","DIR":"E"},
{"ARRIVAL":"05:54P","ROUTE":"202","DIR":"E"},
{"ARRIVAL":"06:33P","ROUTE":"203","DIR":"E"},
{"ARRIVAL":"07:11P","ROUTE":"204","DIR":"E"}];
callback(data);
}
getJSON(makeTable);
};
I think you could write a separate function to build the table, like this:
function makeTable(busArrivals) {
busArrivals.forEach(function(busArrival) {
var tr = document.createElement('tr');
var route = document.createElement('td');
route.appendChild(document.createTextNode(busArrival.ROUTE));
var arrival = document.createElement('td');
arrival.appendChild(document.createTextNode(busArrival.ARRIVAL));
var direction = document.createElement('td');
direction.appendChild(document.createTextNode(busArrival.DIR));
tr.appendChild(route);
tr.appendChild(arrival);
tr.appendChild(direction);
document.getElementById('results').appendChild(tr);
});
}
var busArrivalAPI = 'http://blahblahblah/rtcTimes/'+ stopNumber;
$.getJSON(busArrivalAPI, makeTable);
In each iteration of the forEach loop, you construct a tr element, insert the tds and finally put the whole thing inside the DOM.
You're creating a TR element, but never appending it to the table. Instead, you're appending the TH elements directly to the table, which is invalid.
function getTimes(stopNumber) {
var busArrivalAPI = "http://blahblahblah/rtcTimes/" + stopNumber;
$.getJSON(busArrivalAPI, function(busArrivals) {
var table = document.getElementById('results');
for (var i = 0; i < busArrivals.length; i++) {
var a = [busArrivals[i].ROUTE, busArrivals[i].ARRIVAL, busArrivals[i].DIR];
var row = document.createElement("TR");
for (var b = 0; b < 3; b++) {
var x = document.createElement("TH");
var z = a[b];
var t = document.createTextNode(z);
x.appendChild(t);
row.appendChild(x);
};
table.appendChild(row);
};
});
}
I'm not sure why you need the a array. If you just want to change get the object properties into an array so you can iterate over it, you can do that with a 1-dimensional array, you don't need to save all the other rows in a 2-dimensional array. I've changed a to a single array.

Javascript table creation

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.

Looping through siblings of a specific row/setting up function

Trying to work through my javascript book I am referencing to learn the language and got stuck on looping through siblings of a specific row. W3schools and W3 didnt have what i was looking for. Below is a function walk-through...
It reads: Create the countRecords() function. The purpose of this function is to count the number of visible rows in the data table after the table headings. The total is then displayed in the table cell with the id "records". Add the follow commands to the function:
a. Create a object named headRow that points to the table row with the id "titleRow". Create a variable named rowCount, setting its initial value to 0.
b. Create a for loop that uses familial references starting with the first sibling of headRow and moving to the next sibling until there are no siblings left. Within the for loop. test whether the node name of the currentnext sibling until there are no sibilings left. Within the for loop test whether the node name of the current node is equal to "TR". If it is, test wheter the value of its display style is equal to an empty text string. If it is (indicating that it is visible in the document) increate the value of the rowCount variable by 1.
c. Change the text of the "records" table cell to the value of the rowCount variable. Don't use innerHTML. Create a text node that contains the value of the rowCount variable and assign it to a variable called txt. Create a variable called record to store the reference to the element "records" table cell.
d. Insert an if condition that test whether the "records" cell has any child nodes. If it does, replace the replace the text node of the "record" table cell with the created text node (txt). If it doesn't append the text node to the cell.
var headRow; // part a
var rowCount = 0;
//part b this is where I get lost. I know I need to access the id titleRow but unsure how to set my loop up specifically for this
headRow = document.getElementById("titleRow");
for(var i=0; i<headrow.length; i++)
{
if (something is not equal == "TH")
{
make code happen here
}
if (is "TR" == ""){
rowCount = +1;
}
//part c
var txt = document.createTextNode(rowCount);
var record = document.getElementsById("records")
//part d holding off on this part until I get a,b,c figured out.
The HTML supporting snippet:
<table id="filters">
<tr><th colspan="2">Filter Product List</th></tr>
<tr>
<td>Records: </td>
<td id="records"></td>
</tr>
<table id="prodTable">
<tr><th colspan="8">Digital Cameras</th></tr>
<tr id="titleRow">
<th>Model</th>
<th>Manufacturer</th>
<th>Resolution</th>
<th>Zoom</th>
<th>Media</th>
<th>Video</th>
<th>Microphone</th>
</tr>
Thanks for the help!
You should check out the nextSibling property. I'm not sure how strictly you want to follow your book but a while loop seems more appropriate than a for:
var headRow = document.getElementById("headRow");
var rowCount = 0;
var cRow = headRow; // used as a reference to the current row
while (cRow = cRow.nextSibling) // While there is a next sibling, loop
{
if (cRow.tagName == "TR" && cRow.style.display === "")
rowCount++; // increment rowCount by 1
}
If you're insistent on using a for loop, I suppose you could do something like this:
var headRow = document.getElementById("headRow");
var rowCount = 0;
for (var cRow = headRow.nextSibling; cRow = cRow.nextSibling;)
{
if (cRow.tagName == "TR" && cRow.style.display === "")
rowCount++; // increment rowCount by 1
}
/**
* Schedules a command to retrieve the count of WebElements
* this function can be called from your Helper Control to your page object
* method
*/
console.log('Driver: ' + this.driver);
let test = await this.driver.findElements({css: this.cssLocator})
console.log('--test: ' + test);
console.log('--test length: ' + test.length);
return test.length;

Categories

Resources