Modify the text of table cells using js - javascript

I have a table in html and I want to alter the text inside different cells using js. My table looks like this:
<tr><td colspan="7" style="text-align:center;">Calendar evenimente tds</td></tr>
<tr>
<th>Data1</th>
<th>Data2</th>
<th>Data3</th>
<th>Data4</th>
<th>Data5</th>
<th>Data6</th>
<th>Data7</th>
</tr>
<tr>
<td id="col1row1">null</td>
<td id="col2row1">null</td>
<td id="col3row1">null</td>
<td id="col4row1">null</td>
<td id="col5row1">null</td>
<td id="col6row1">null</td>
<td id="col7row1">null</td>
</tr>
</table>
and my js script looks like this:
var j=0;
for(j=0;j<=7;j++)
document.getElementById("col"+j+"row1").innerHTML=j;
but I get this error:
Uncaught TypeError: Cannot set property 'innerHTML' of null
My question is whats the propper way of modifying the text inside a HTML table cell and what am I doing wrong?

The first iteration of your loop fails because there is no col0. Rather than iterate over IDs like this, you can simply loop over the elements by tag:
Array.from(document.getElementsByTagName('td')).forEach((td, index) => {
td.innerHTML = index
})
If you want the count to start at 1, use td.innerHTML = index + 1 instead.

loop are calling an ID that does not exist.make for loop starts with 1 instead of zero as there is no col0row1 in your html
var j;
for(j=1;j<=7;j++){
document.getElementById("col"+j+"row1").innerHTML=j;
}

As at j = 0 there is no element with id "col0row1" hence the uncaught error.
var j = 1
for(j=1;j<=7;j++){
document.getElementById("col" + j + "row1").innerHTML = j;
}

Related

My assign on a table row not reflecting on the front end

I have finally filtered and retrieved the rows I want in my table and assigned it a value, it outputs to the console properly but not rendered on the web page itself.
I have retrieved my rows into a variable row and assigned it another variable
var rows = [...$(".table td")].map(e => $(e).text().trim()).filter(e => e);
console.log(rows);
for (i = 0; i < rows.length; i++) {
//I have assigned it in the line below
rows[i].text = dateArr[i];
console.log(rows[i]);
}
as you can see in your console.log(rows);
you only get a new array of string with all TD values, not a pointer on each TD with a useless complicated code
const newVals = [111,222,333];
document.querySelectorAll('#myTable td').forEach( (elmTD, idx)=>{
elmTD.textContent=newVals[idx].toString()
})
td { border:1px solid grey }
<table id="myTable">
<tr>
<td> aaa </td>
<td> bbb </td>
<td> ccc </td>
</tr>
</table>
All I can say is "forget jQuery and use javascript ES6" only because you already use arrow functions

Protractor - How to get all cells from one column and sum them when the Grid has id="0-0" for rows-Columns

I am validating a drill down process in the portal i am testing, for this my script is doing:
Read the value from the first row of a table and click at this value (there is a link for certain cells that perform the drill down to the detail page)
To click at this particular cell I am using it's ID:
<table id="transHistTable" class="table table-hover table-bordered table-striped dataTable no-footer" style="width: 100%" role="grid" aria-describedby="transHistTable_info">
<thead>
<tbody>
<tr role="row" class="odd">
<td id="0-0" class="ng-scope">31 Jul 2018</td>
<td id="0-1" class="ng-scope">RandomText0</td>
<td id="0-2" class="ng-scope">RandomText1</td>
<td id="0-3" class="ng-scope">EmptyValue</td>
<td id="0-4" class="ng-scope">Value I Click And Save it</td>
So for this table I am clicking directly to the row 0 column 4 since my data and my filters will always bring only one row, but then, comes my problem....
When the drill down is performed I never know how many rows I will have since it depends of user operations.
I need to perform a validation to compare the sum of all the values from the table displayed after the drill down with the value captured from table "transHistTable" row 0 column 4
This is the values I get after performing the Drill Down:
<table id="transHistDetailTable" class="table table-hover table-bordered table-striped dataTable no-footer" style="width: 100%" role="grid" aria-describedby="transHistDetailTable_info">
<thead>
</thead>
<tbody><tr role="row" class="odd">
<td id="0-0" class="ng-scope">Site</td>
<td id="0-1" class="ng-scope">Date</td>
<td id="0-2" class="ng-scope">Time</td>
<td id="0-3" class="ng-scope">I</td>
<td id="0-4" class="ng-scope">value 1</td>
<td id="0-5" class="ng-scope">value 2</td>
<td id="0-6" class="ng-scope">value 3</td>
<td id="0-7" class="ng-scope">12</td>
</tr></tbody>
</table>
So what I would like to do is reading all the rows (could be 0,1,2,3,4,5...) saving the value that is stored in Column 7 then after this is done, perform a sum and then comparing with the value I have saved from the first table.
My code is this one:
var rowstransHistDetail = element(by.id('transHistDetailTable')).all(by.tagName("tr"));
rowstransHistDetail.count().then(function(rcount){
//In case only 1 row is displayed
if (rcount < 3)
{
element(by.id('0-7')).getText().then(function(valueQty){
expect(valueQty).toEqual(600)
})
}
else
{
var tempValue
for (i=0; i < rcount; i++)
{
element(by.id(i+'-7')).getText().then(function(valueQty){
tempValue = Number(tempValue) + Number(valueQty)
})
}
expect(tempValue).toEqual(600);
}
});
But when I execute this, gives me a undefined value
Any ideas how to solve this please?
Thank you!!!!
It seems that you are incrementing a value in a loop before execution.
See here: https://stackoverflow.com/a/6867907/6331748
Should bee i++ instead of ++i in a loop.
Drop me a line if I'm wrong.
===========================
Edited:
Here's some code from my side:
var expectedCells = element.all(by.css('#transHistDetailTable tr td:nth-of-type(5)'));
var currentSum = 0;
expectedCells.each((eachCell) => {
eachCell.getText().then((cellText) => {
currentSum += Number(cellText);
});
}).then(() => {
expect(currentSum).toEqual(600);
});
Sorry, but wasn't able to test it. I only want to share a main idea and elaborate it.
expectedCells are all id=n-4 cells. We go through all elements and get text from them, change to the number type and add to current value. Aftermath we do an assertion.
It also looks that if statement is not necessarily.
Let me know how it works.
Two options for your issue:
1) using element.all().reduce()
let total = element
.all(by.css('#transHistDetailTable > tbody > tr > td:nth-child(8)'))
.reduce(function(acc, item){
return item.getText().then(function(txt) {
return acc + txt.trim() * 1;
});
}, 0);
expect(total).toEqual(600);
2) using element.all().getText() and Array.reduce
let total = element
.all(by.css('#transHistDetailTable > tbody > tr > td:nth-child(8)'))
.getText(function(txts){ //txts is a string Array
return txts.reduce(function(acc, cur){
return acc + cur * 1;
}, 0);
});
expect(total).toEqual(600);

extract xml data and put into a html timetable

I have the following XML data which represents one course, now i have many course elements in my xml and i need to loop horugh them all and display times and course code in correct places in the html table.
<course code="Philo">
<dayofWeek> Monday
<hoursofClass>
<hour>0800</hour>
<hour>0900</hour>
</hoursofClass>
<roomNumber>B2029</roomNumber>
</dayofWeek>
<dayofWeek> Wednesday
<hourofClass>
<hour>1000</hour>
<hour>1100</hour>
</hourofClass>
<roomNumber>M3045</roomNumber>
</dayofWeek>
</course>
I need to insert into time into correct timetable stots. My HTML table is. Im new to programming and would like some advice. Does My xml need to be reformatted?
<table id="myTable">
<!--DATE HEADING-->
<tr>
<td></td>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
<td>Thursday</td>
<td>Friday</td>
</tr>
<tr>
<td>800</td>
<td id = "m800"></td>
<td id ="t800"></td>
<td id = "w800"></td>
<td id="th800"></td>
<td id ="f800"></td>
</tr>
<tr>
<td>900</td>
<td id = "m900"></td>
<td id ="t900"></td>
<td id = "w900"></td>
<td id="th900"></td>
<td id ="f900"></td>
</tr>
<tr>
<td>1000</td>
<td id = "m1000"></td>
<td id ="t1000"></td>
<td id = "w1000"></td>
<td id="th1000"></td>
<td id ="f1000"></td>
</tr>
As we want you to learn by yourself how to code this, I'll (hopefully) give you all the relevant parts you need to get you started.
Steps:
Modify your XML so that you can find the day prefix more easily; otherwise you will have to use switch case in your JavaScript code to translate the day name into the prefix.
Load the XML data on your page containing the class table. To make life easier, I would recommend to not use XMLHttpRequest but use a library like JQuery, loading your data is then as easy as:
$.ajax('PATHTOXML.xml', {
success: function(data) {
// your XML code will be available inside the "data" variable
}
});
Loop over your loaded data in a loop. The following functions may be handy when you access your XML object:
data.children[0].getAttributeNode("code").value will return "Philo".
data.children[0].hasAttribute("code") will return TRUE for the same entry.
data.children.length can be used to check for the number of elements (or the length of a contained value in case of strings or numbers), it will return 1 for the base element.
data.getElementsByTagName("course")[0].getElementsByTagName("dayofWeek") will access the first element (JS uses 0 as base for counting) with the XML tag name "course" and will then return the values for the tag name "dayofWeek"
More examples can be found in this SO Q&A and in this blog post
add the data to your table. I will use a static code example (without any error handling, should be different in your code) to show how this could be done:
var courseName= data.children[0].getAttributeNode("code").value;
var dayName= data.getElementsByTagName("course")[0].getElementsByTagName("dayofWeek")[0].childNodes[0].textContent;
var start= data.getElementsByTagName("course")[0].getElementsByTagName("dayofWeek")[0].getElementsByTagName("hoursofClass")[0].getElementsByTagName("hour")[0].textContent;
var end= data.getElementsByTagName("course")[0].getElementsByTagName("dayofWeek")[0].getElementsByTagName("hoursofClass")[0].getElementsByTagName("hour")[1].textContent;
var room= data.getElementsByTagName("course")[0].getElementsByTagName("dayofWeek")[0].getElementsByTagName("roomNumber")[0].textContent;
document.getElementById(dayName+start).innerHTML += courseName + ' in ' + room + '<br />' + start + ' - ' + end + '<br />';
If you want to loop over a structure, you can use code similar to the following:
// accesses the first element matching the tag "course"
var courseData= data.getElementsByTagName("course")[0];
// retrieves the node attribute value of attribute "code"
var courseName= courseData.getAttributeNode("code").value;
var courseDaysData= courseData.getElementsByTagName("dayofWeek");
// loop over all course days below one course
for (var icd=0; icd<courseDaysData.length; icd++) {
// loop over your days
}
General hints:
When running your page in your browser of your choice, open the "Developer Tools" (shortcut should be F12) that will show errors in your code, allow you to position breakpoints to stop your code exactly on the relevant points and much more. It's the most handy tool for JS code debugging that you'll find.
To see the values of variables, you can add debug output statements in your code. To do so, use console.log(VARIABLE);, i.e. console.log(dayName);. You will find the output in said Developer Tools.
Regarding your XML:
As mentioned before, the day name (or prefix) in your HTML and XML should match, otherwise you need a "switch case". Besides that, your current XML code just allows you to have different times for one class in one room, I don't know if that is what you wanted to have.
Let me know if you need any more explanation. Good learning!
Hope This Answers your Question Just Copy & Paste into an HTML file for testing.
var XML = ''
+'<course id="Philo">'
+' <dayofWeek>Monday'
+' <hoursofClass>'
+' <hour>8</hour>'
+' <hour>9</hour>'
+' </hoursofClass>'
+' <roomNumber>B2029</roomNumber>'
+' </dayofWeek>'
+''
+' <dayofWeek>Wednesday'
+' <hoursofClass>'
+' <hour>10</hour>'
+' <hour>11</hour>'
+' </hoursofClass>'
+' <roomNumber>M3045</roomNumber>'
+' </dayofWeek>'
+'</course>';
XML = (new DOMParser()).parseFromString(XML, "text/xml");
console.log(XML);
console.log(XML.getElementsByTagName("course"));
XML.getElementsByTagName("course");
for(N_01=0; N_01<XML.getElementsByTagName("course").length; N_01++){
console.log(XML.getElementsByTagName("course")[N_01]);
DAY_OF_WEEK = XML.getElementsByTagName("course")[N_01].getElementsByTagName('dayofWeek');
///
///
///
for(N_02=0; N_02<DAY_OF_WEEK.length; N_02++){
CLASS_HOUR = DAY_OF_WEEK[N_02].getElementsByTagName('hoursofClass');
CLASS = DAY_OF_WEEK[N_02].getElementsByTagName('roomNumber');
///
///
//
for(N_03=0; N_03<CLASS_HOUR.length; N_03++){
///
///
///
HOURS = CLASS_HOUR[N_03].getElementsByTagName('hour');
for(N_04=0; N_04<HOURS.length; N_04++){
var ROW = document.getElementById('TIME_'+HOURS[N_04].innerHTML);
var CELL= '';
if(DAY_OF_WEEK[N_02].innerHTML.search('Monday')!=-1){ CELL=1; }
if(DAY_OF_WEEK[N_02].innerHTML.search('Tuesday')!=-1){ CELL=2; }
if(DAY_OF_WEEK[N_02].innerHTML.search('Wednesday')!=-1){CELL=3; }
if(DAY_OF_WEEK[N_02].innerHTML.search('Thursday')!=-1){ CELL=4; }
if(DAY_OF_WEEK[N_02].innerHTML.search('Friday')!=-1){ CELL=5; }
ROW.cells[CELL].innerHTML = CLASS[N_03].innerHTML;
}//
///
///
}//
///
///
}//
///
///
}
#myTable TD{text-align:center; padding:5px;}
#myTable .td_1{text-align:right; padding:5px; padding-left:15px;}
<table id="myTable" cellspacing=1 cellpadding=1 border=1>
<!--DATE HEADING-->
<tr><td></td>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
<td>Thursday</td>
<td>Friday</td>
<tr ID=TIME_8><td class=td_1>8</td>
<td id = "m800"></td>
<td id ="t800"></td>
<td id = "w800"></td>
<td id="th800"></td>
<td id ="f800"></td>
<tr ID=TIME_9><td class=td_1>9</td>
<td id = "m800"></td>
<td id ="t800"></td>
<td id = "w800"></td>
<td id="th800"></td>
<td id ="f800"></td>
<tr ID=TIME_10><td class=td_1>10</td>
<td id = "m800"></td>
<td id ="t800"></td>
<td id = "w800"></td>
<td id="th800"></td>
<td id ="f800"></td>
<tr ID=TIME_11><td class=td_1>11</td>
<td id = "m800"></td>
<td id ="t800"></td>
<td id = "w800"></td>
<td id="th800"></td>
<td id ="f800"></td>
</TABLE>

How to get index of current cell

I have a table and a function.
I can take cell's parameters.
I'm new in JS. Please help to find index of current cell. Thank you
function changePosition(currentCell) {
let top = currentCell.offsetTop
//need to find index of cell
}
<table class="square-table">
<tr>
<td onmouseover =
"changePosition(this)"></td>
<td onmouseover =
"changePosition(this)"></td>
<td onmouseover =
"changePosition(this)"></td>
<td onmouseover = function() {
"changePosition(this)"></td>
</tr>
</table>
I found the solution here
link
function changePosition(currentCell) {
let top = currentCell.offsetTop
currentCell.cellIndex
//need to find index of cell
}
My problem is resolved. Sorry

javascript - get custom attribute based on an id

How can I find the seq number given the id in this example?
<table>
<tr class="row_header thin_border">
</tr><tr id="id33192010101533333" seq="2">
<td>20101015</td>
<td>600</td>
<td>730</td>
<td>Click</td>
<td><a href="#" onclick='selectEditActivity("id3319201010153333");'>Click</a></td>
</tr>
<tr id="id3319201010151111" seq="3">
<td>20101015</td>
<td>600</td>
<td>730</td>
<td> <img src="/bbhtml/img/deleteAction.png"></td>
<td></td>
</tr>
<table>
<script>
function selectEditActivity(pass_id){
alert("seq# =:" + ???)
}
</script>
try this
var id = document.getElementById("divId").getAttribute("attributeId");
How to get an attribute based on an id
With jQuery :
var seq = $('#id33192010101533333').attr("seq");
Without jQuery :
vvar seq = document.getElementById("id3319201010151111").getAttribute("seq");
You can try both of them at this Fiddle.
Both options should work in any browser!
What you really want
First of all, it's better to name your custom attribute data-seq instead of seq. The HTML5 standard allows custom elements but only considers them valid when their name starts with data-.
Also, it's not a good idea to put your click handlers directly in your CSS. It's better to use the class property or some custom data-action property with a value like edit or delete and then attach an event handler when you finish loading your page. Then, look at the first ancestor that has a data-seq property and get that property.
As one demo says more than a thousand words, here's a demo :
var list = document.querySelectorAll('[data-action="delete"]');
for (var i = 0; i < list.length; ++i) {
list[i].addEventListener("click", function(e){
alert('delete ' + e.target.closest('[data-seq]').getAttribute('data-seq'));
});
}
var list = document.querySelectorAll('[data-action="edit"]');
for (var i = 0; i < list.length; ++i) {
list[i].addEventListener("click", function(e){
alert('edit ' + e.target.closest('[data-seq]').getAttribute('data-seq'));
});
}
table, td {
border : 1px solid #333;
}
td {
padding : 10px;
}
<table>
<tr class="row_header thin_border"></tr>
<tr id="id33192010101533333" data-seq="2">
<td>20101015</td>
<td>600</td>
<td>730</td>
<td>Click</td>
<td><a href="#" data-action='edit'>Click</a></td>
</tr>
<tr id="id3319201010151111" data-seq="3">
<td>20101015</td>
<td>600</td>
<td>730</td>
<td> <img src="https://i.stack.imgur.com/mRsBv.png?s=64&g=1"></td>
<td></td>
</tr>
<table>
Or, if you prefer the jQuery way, you can replace the JavaScript code with the following (much simpler) code :
$('[data-action="delete"]').click(function(e){
alert('delete ' + $(this).closest('[data-seq]').data('seq'));
});
$('[data-action="edit"]').click(function(e){
alert('edit ' + $(this).closest('[data-seq]').data('seq'));
});
See also this Fiddle and this Fiddle for the same demo on JSFiddle, respectively without and with jQuery.
Retrieve the DOM element and then get the seq attribute:
document.getElementById(id).getAttribute('seq'); // note: this will return a string, and getElementById might return null in case there is no element with the given id.
You want to use objRef.getAttribute('seq') or plan old dot notation objRef.seq

Categories

Resources