Javascript wrong target.ids' return - javascript

I won't post all my code because it's quite big. But i have a problem in a part of it. I cannot get tds' id (i mean cells' id in table). What's wrong with it? Thanks.
function controllerDrawTable() //creating table
{
var table = document.getElementById("tablefield");
for (var i = 0; i < model.fieldSquare; i++)
{
var row = table.insertRow(i);
for (var j = 0; j < model.fieldSquare; j++)
{
var cell = row.insertCell(j);
var atr = letter[i] + number[j]; //it's just a values for creating IDs like A3, B5, etc.
cell.setAttribute("id", atr);
cell.onclick = controller.fire; //here i handle clicks on the table.
}
}
}
And here is my function which handle clicks on the table:
function controllerFire(event)
{
var cell = document.getElementById(event.target.id);
console.log(cell); //i get <td id="C0"> instead of "C0"
}

You read the element from the id itself.
You should get expected value in in event.target.id it self. Check its value.
console.log(event.target.id);

Related

Modify a function to ignore any clicks made in the last cell of each row of a table

I'm using this JavaScript function that works as follows. When you click on any row in the table, it opens a new page at link specified on line 6. (The ID# from column 0 is added to the end of the link) It works perfectly, but now I need it to ignore clicks made in the last cell of each row. I'm trying to put another link in that last cell and as long as this function is active it opens the link on line 6 and ignores the link in the last cell of the row. i starts at 2 because of the table header. How can I modify the function, such that, it does not respond to clicks in the last cell of each row?
function addRowHandlers(){
var rows = document.getElementById("mytable").rows;
for (i = 2; i < rows.length; i++) {
rows[i].onclick = function(){ return function(){
var id = this.cells[0].innerHTML;
window.open("https://site url/"+id+";", "Details", "top=150, left=500,height=757, width=900");
};}(rows[i]); }}
window.onload = addRowHandlers();```
sorry i misreaded your question, i would bind onclick event on cells instead of rows then like this:
function addRowHandlers(){
var rows = document.getElementById("mytable").rows;
for (i = 2; i < rows.length; i++) {
//edit: let instead of var
let id = rows[i].cells[0].innerHTML;
for (j = 0; j < rows[i].cells.length - 1/* last one is not included */; j++) {
rows[i].cells[j].onclick = function(){
window.open("https://site url/"+id+";", "Details", "top=150, left=500,height=757, width=900");
};
}
}
}
window.onload = addRowHandlers();
You can add a common class name to all the last cells of each row.so that based on the class name you can identify the last cells and avoid the window.open function for the cells that have an class name mentioned by you.
please refer the below the modified code.
for (i = 2; i < rows.length; i++) {
rows[i].onclick = function(){ return function(){
for(var j = 0 ; j<=this.cells.length; j++) {
if(!this.cells[j].classList.contains('your className of last cell for each row') {
var id = this.cells[0].innerHTML;
window.open("https://site url/"+id+";", "Details", "top=150,
left=500,height=757, width=900");
}
}
window.onload = addRowHandlers();`

How do I check if a cell has a select element in a Javascript loop?

I have a dynamically created table which is generated through a JS addRow function. I would like to loop through this table and check if the cell has a select element in it. If it does then I would like to push the value of the selected option to a dictionary called ingredient_dict.
This is what I have so far:
var table = document.getElementById('selected_ingredients');
var rowCount = table.rows.length;
//table width by counting headers minus the last cell which has a delete button
var cellsCount = table.rows[0].cells.length -1 ;
//loop through all rows (r) in table
for (var r = 1; r < rowCount; r++) {
//initiate dictionary for this ingredient
var ingredient_dict = {};
//loop through each cell (c) in row
for (var c = 0; c < cellsCount; c++) {
var $cell = table.rows[r].cells[c];
if (**CHECK IF CELL HAS A SELECT ELEMENT**) {
$ingredient_dict["UOM"] = $cell.options[$cell.selectedIndex].value
} else if (**CHECK IF CELL HAS INPUT ELEMENT**) {
$ingredient_dict["qty"] = $cell.value
} else {
$ingredient_dict["name"] = $cell.value
}
}
}
I'm not sure if it matters but this is the code in my addRow function to dynamically create the select element:
// ingredient unit of measurement drop down
var cell3= row.insertCell(2);
var unit_of_measure = document.createElement("select");
unit_of_measure.name = "unit_of_measure_select";
cell3.appendChild(unit_of_measure);
I'm pretty new to javascript so I apologize if my code is messy or if this is an obvious question!
var doesCellHaveElement = (cell,element) => {
return cell.innerHTML.toLowercase().indexOf(`<${element}`) >= 0;
};
element would be some name of tag in lowercase. For example:
doesCellHaveElement(cell, "select");
doesCellHaveElement(cell, "input");

How to add nested table to datatable?

I need to add a nested table to each row of a jquery datatable(using legacy datatables). So, I tried using example from datatables.net for child rows and modifying it to my needs as I need for the child rows to show at all times, rather than on clicking the parent row.Here is the code I am using both to build my inner table and then display it..
function buildInnerTable(){
var keys = Object.keys(reportApp.gridData),
len = keys.length,
j = 0,
prop,
value;
while (j < len) {
prop = keys[j];
value = reportApp.gridData[prop];
detLen = value.detail.length;
var rowVals = [];
for(var i = 0; i < detLen; i++){
tmpRow = "<tr><td>"+value.detail[i].invtid+"</td>"+
"<td>"+value.detail[i].bf+"</td>"+
"<td>"+value.detail[i].qtyship+"</td>"+
"<td>"+value.detail[i].ordqty+"</td>"+
"<td>"+value.detail[i].bf+"</td>"+
"<td>"+value.detail[i].exttreating+"</td>"+
"<td>"+value.detail[i].extpriceinvc+"</td>"+
"<td>"+value.detail[i].misc+"</td>"+
"<td>"+value.detail[i].extother+"</td>"+
"<td>"+value.detail[i].calcext+"</td></tr>";
rowVals.push(tmpRow);
}
setTableRow(rowVals , j);
j += 1;
}
function setTableRow(rowVals , ndx){
$("#gridTbl > tbody > tr:eq("+ ndx+ ")").after("<table><tr><th>InvtID</th>"+
"<th>Clss</th><th>Pieces</th><th>BilQty</th><th>BF</th><th>Treating</th>"+
"<th>Wood</th><th>NEED NAME</th><th>Other</th><th>Misc</th><th>Total</th></tr>"+
rowVals);
But, I am not getting what I need to get. What it looks like is that the datatables adds a new row and then sets the new table inside the first cell on new row. However, when I view source, that isn't what is happening at all. It closes the previous row and then inserts new table...
I am attaching a screenshot. What I need is for the details to show below the main item rows and to be aligned in same way. Any help in where I am wrong will be greatly appreciated.
Ok... Finally figured this out.
In order to make the view show normally, I had to add a new row to the datatable and then, in side that row, add my new table. However, this caused an indexing issue with the table. So, I had to check the index each time before I added new row. I am posting working code in the hope that it will help someone else.
function buildInnerTable(){
var keys = Object.keys(reportApp.gridData),
len = keys.length,
j = 0,
prop,
value;
while (j < len) {
prop = keys[j];
value = reportApp.gridData[prop];
detLen = value.detail.length;
var rowVals = [];
//THIS NEXT LINE IS WHERE I GET MY INDEX...
var ndx = ($("tr:contains("+value.invcnbr+ ")").index());
for(var i = 0; i < detLen; i++){
tmpRow = "<tr><td>"+value.detail[i].invtid+"</td>"+
"<td>"+value.detail[i].bf+"</td>"+
"<td>"+value.detail[i].qtyship+"</td>"+
"<td>"+value.detail[i].ordqty+"</td>"+
"<td>"+value.detail[i].bf+"</td>"+
"<td>"+value.detail[i].exttreating+"</td>"+
"<td>"+value.detail[i].extpriceinvc+"</td>"+
"<td>"+value.detail[i].misc+"</td>"+
"<td>"+value.detail[i].extother+"</td>"+
"<td>"+value.detail[i].calcext+"</td></tr>";
rowVals.push(tmpRow);
}
setTableRow(rowVals,ndx);
}
j += 1;
}
}
function setTableRow(rowVals,ndx){
var outerTbl = $('#gridTbl').DataTable();
var tr = $("#gridTbl > tbody > tr:eq("+ ndx+ ")");
//NOTE HOW I ADD A ROW AND THEN ADD NEW TABLE TO CELL IN THE ROW.
var innerTbl = "<tr><td colspan = 10><table style = 'background- color:#FFFFFF; width:100%; border:1px solid;'><tr><td>InvtID</td>"+
"<td>Clss</td><td>Pieces</td><td>BilQty</td><td>BF</td><td>Treating</td>"+
"<td>Wood</td><td>NEED NAME</td><td>Other</td><td>Misc</td><td>Total</td></tr>"+
rowVals + "</td></tr>";
tr.after(innerTbl).show();
}

How do I change an html cell's color on click, if the table is generated dynamically?

function drawTable() {
var table = document.getElementById("myTable");
var input = prompt("Insert height (in number of cells)");
var a = +input;
var input2 = prompt("Insert width (in number of cells)");
var b = +input2;
for (var i = 0; i < a; i++) {
var row = table.insertRow(i);
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
};
};
};
I can't for the life of me figure out how to add a onClick event that would change the color of a cell. Do I create a new function in JavaScript and add an onClick event to the table element? That's what I did, but it doesn't seem to work.
function changeColor() {
var td = document.getElementsById("myTable").getElementsByTagName("td");
td.style.backgroundColor = "red";
}
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
cell.addEventListener("click", changeColor.bind(cell), false);
};
function changeColor(e) {
this.style.backgroundColor = "red";
}
Should do the trick. Every cell gets an onclick handler set in the for loop. Bind passes the reference of the cell to the changeColor function. The function can address the cell by using this.
For some situations, the answer suggested by Mouser work well. But if consider a situation taking your example of table creation based on number of rows and columns, then adding eventlistener to each cell doesn't sound a good approach. Suppose at initial user requested for 10X10 table. At that moment,
eventlistener is added to each cell.
But what if at some later point of time, more rows/columns are added dynamically. In that situation, only thing you will left with is to add event listeners.
Better approach is to understand the term
Event Delegation
In this approach, you add event listener to parent and just listen to event bubbled up(default behavior) by the child elements.In that case you dont have to be worry about dynamically created cells and adding event listeners to those.
You can take a look on working sample with Event Delegation approach on your code at below link:
http://jsfiddle.net/zL690Ljb/1/
function drawTable() {
var table = document.getElementById("myTable");
table.addEventListener("click", changeColor);
var input = prompt("Insert height (in number of cells)");
var a = +input;
var input2 = prompt("Insert width (in number of cells)");
var b = +input2;
for (var i = 0; i < a; i++) {
var row = table.insertRow(i);
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
//cell.addEventListener("click", changeColor.bind(cell), false);
};
};
};
function changeColor(event) {
if (event.target && event.target.tagName && (!event.target.tagName.match(/table|th|tr|tbody|thead/i)) )
{
var element = event.target;
while (element && element.parentElement)
{
if(element.tagName=='TD'){
element.style.backgroundColor = "red";
break;
}
else
{
element = element.parentElement;
}
}
}
}
drawTable();
I hope Mouser will agree on this. Thanks!
Inside the for you can add the onclick event for each cell:
for (var i = 0; i < a; i++) {
var row = table.insertRow(i);
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
cell.onclick = function(){
changeColor(this);
}
};
};
Then the changeColor will be as following:
function changeColor(cell) {
cell.style.backgroundColor = "red";
}

Javascript table row <tr> onclick function not executing

I'm trying to have each table row clicked to be highlighted in a color and I'm handling this with a class name but the onclick function is not executing, I tried print statement inside the onclick function to check if it is entering but it's just not.
Here is the JS code related to that part:
var rows = document.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++)
{
rows[i].onclick = function() {
this.className = "highlighted";
}
}
Anyone know why this function isn't getting entered?
EDIT: I realized the mistake in the rows variable and I corrected it but the function is still not getting entered and I have no errors on my JS console
var table = document.getElementById("tableId");
var rows = table.getElementsByTagName("tr");
for (i = 0; i < rows.length; i++) {
var currentRow = table.rows[i];
var createClickHandler = function(row) {
return function() {
row.className = "highlighted";
};
};
currentRow.onclick = createClickHandler(currentRow);
}
Use this it will works....
Use this code. Your table rows must have an attribute name with the value "tr" to make this work :
var rows = document.getElementsByName("tr");
for (var i = 0; i < rows.length; i++)
{
rows[i].onclick = function() {
this.className = "highlighted";
}
}
use getElementsByTagName instead of getElementsById.
Try this
var rows = document.getElementsByTagName("tr");
Add semicolon
rows[i].onclick = function() {
this.className = "highlighted";
}; // here
It works for me .. Check here : JS Fiddle

Categories