HTML Table onClick function to get table row key and value
I wanted to create a HTML table with onclick function to get the key and value of a row, so far the onclick function is working but it displaying and empty array for me, how can I fix this problem. Thanks. I wanted it to be display in console log in this format when you click on the first row:
var table = document.getElementById("tableID"); if (table != null) < for (var i = 0; i < table.rows.length; i++) < table.rows[i].onclick = function() < tableText(this); >; > > function tableText(tableRow)
name age Clark 29 Bruce 30
You are passing a DOM element (i.e. a host object) to JSON.stringify, are you sure that should work? See How to serialize DOM node to JSON even if there are circular references?.
Hi @RobG thanks your reply, I guess I went to a wrong direction. My goal is to get the entire row object onClick so i can pass it later to edit a REST API Framework later. for now i just want to get the object in JSON format. can you help me with that. thanks
The stringified (serialised) version of a TR would be its outerHTML, which can be passed as a string then parsed back to a DOM object using an HTML parser. I think JSON is the wrong tool in this case.
Per the first comment, you can manually serialise the element but that seems a bit extreme. So either serialise just the bits you want, or use outerHTML. Perhaps you should explain what you mean by «key and value of a row«, e.g. what should clicking on a row produce (sample output)?
4 Answers 4
I edited my answer to return the data as an object. Run the script and have a look.
var table = document.getElementById("tableID"); if (table) < for (var i = 0; i < table.rows.length; i++) < table.rows[i].onclick = function() < tableText(this); >; > > function tableText(tableRow) < var name = tableRow.childNodes[1].innerHTML; var age = tableRow.childNodes[3].innerHTML; var obj = ; console.log(obj); >
name age Clark 29 Bruce 30
@JosanIracheta Thanks alot this works! if you dont mind me asking, if I have a much bigger table. how can make it more dynamic by not having to declare the tableRow.childNodes[i].innerHTML; 1 by 1
@M.Izzat Since you wanted an object, you’re going to have to declare what you want specifically so the value is paired with the correct key.
I think you can use tr.innerTest to get the value in the tags
I think you mean innerText. It seems to me that the OP wants to serialise the entire TR structure, not just get the textContent.
If you are using jQuery you can add an eventlistener to the table like this
$('#tableID').on('click', 'tr', function(e)< tableText($(this).html()); >); function tableText(tableRow)
Text MoreText Lorem Ipsum Text MoreText Lorem Ipsum Text MoreText Lorem Ipsum Text MoreText Lorem Ipsum
There are many ways to do what you’re after, however a robust and extensible way would be to get the property names from the table header row, then get the values from the row that was clicked on.
I don’t know why you have hidden cells in the header, it just complicates things. If you’re using it for data, that would be much better in an associated object or data-* property of the table or row.
function getRowDetails(event) < row = this; var table = row.parentNode.parentNode; var header = table.rows[0]; // Get property names from header cells var props = [].reduce.call(header.cells, function(acc, cell ) < if (!cell.hasAttribute('hidden')) < acc.push(cell.textContent); >return acc; >, []); // Get value for each prop from data cell clicked on var result = props.reduce(function(acc, prop, i) < acc[prop] = row.cells[i].textContent; return acc; >, <>); // Do something with result console.log(result); return result; > // Add listener to body rows, could also put single listener on table // and use event.target to find row window.onload = function() < [].forEach.call(document.getElementsByTagName('tr'), function(row, i) < if (i) row.addEventListener('click', getRowDetails, false); >); >
How would I be able to target a specific table to manipulate it?
Html page Browser view of html page: CSS page I’m trying to target a specific table when I click the buttons. But the function I have set up effects all of them, even the table in the middle. I figured table.children[0].childElementCount > 10 would only effect the first and the third table since there the one that have more then 10 rows. Would any one know how I can target an individual table that has a more then 10 rows? Please let me know if my question makes sense and if I need to provide additional information. Javascript
/* ========================================================================== ShowDebug constructor ========================================================================== */ var ShowDebug = function () < this.tables = document.querySelectorAll('.tbl_List'); this.counters = < min: 1, max: 5 >this.rule = document.styleSheets[0].rules[0] this.appendElements(); > /* ========================================================================== ShowDebug Inherited methods ========================================================================== */ ShowDebug.prototype = < // Create button to collopase table items createLessBtn() < var lessBtn = document.createElement("button"); lessBtn.className = "btn"; lessBtn.textContent = "Less"; lessBtn.setAttribute("onclick", "showDebug.showLess();"); return lessBtn >, // Create button to expand table items createMoreBtn() < var moreBtn = document.createElement("button"); moreBtn.className = "btn"; moreBtn.textContent = "More"; moreBtn.setAttribute("onclick", "showDebug.showMore();"); return moreBtn >, // Append elements to the tables appendElements() < console.log(document.styleSheets[0].rules[0]) this.tables.forEach(function (table) < if (table.children[0].childElementCount >10) < let itemCounter = document.createElement('span') itemCounter.className = "item-counter" itemCounter.innerHTML = ` 1 - 10 of $items` table.children[0].appendChild(itemCounter); table.children[0].appendChild(this.createLessBtn()); table.children[0].appendChild(this.createMoreBtn()); > >, this) >, // Collaspe table items showLess() < this.tables.forEach(function (table, index) < if (table.children[0].childElementCount >10) < if (index === 0) < console.log("less"); showDebug.counters.max = showDebug.counters.max - 5; showDebug.rule.selectorText = "table tr:nth-of-type(" + showDebug.counters.min + "n+" + showDebug.counters.max + ")"; >> >) >, // Expand table items showMore() < this.tables.forEach(function (table, index) < if (table.children[0].childElementCount >10) < if (index === 0) < console.log("more"); showDebug.counters.max = showDebug.counters.max + 5; showDebug.rule.selectorText = "table tr:nth-of-type(" + showDebug.counters.min + "n+" + showDebug.counters.max + ")"; >> >) > > var showDebug = new ShowDebug();
table tr:nth-of-type(1n+5) < display: none; >table < width: 100%; >/* .hide:nth-of-type(1n+1) < display: none; background: red; >*/
How to know element clicked within a table?
I’m trying get the element clicked within a TR in a HTML table. If I click on the Select input inside a TR, CurrentTarget field returns «TR», and OriginalTarget returns «SELECT». This is my HTML:
Descripción Registro Fecha 1651 Name
//trb is each TR element of the line $(trb).click(function(elem) < if (elem.currentTarget && elem.currentTarget.tagName.toLowerCase() === "tr" && !isInput(elem.originalTarget))< if (editableRow)< var rowTrigger = editableRow.find("button").get(); $.editRow(rowTrigger,$.tableEditor.vault.getTableID($("#" + id))); >>);
This code is working fine on my web browser, but it doesn’t on mobile devices, because OriginalTarget returns undefined . Is there any way to get the original target on a mobile web browser?
Why are you mixing jquery with javascript. Give your elements some ids and/or classes are bind on them
2 Answers 2
You haven’t actually said what trb is but it sounds like it might be a set of the tr elements in your table.
What you’re looking for is elem.target . That’s the topmost element that was clicked, the one that initiated the event. (FWIW, I wouldn’t call the argument passed to the event handler elem , it’s an event, not an element.)
. and you click the text «click me,» you’ll see
Side note: It’s handy to use closest with that if you want to know what cell or row was clicked, e.g.:
@Cherniv: No, currentTarget is the same as this (usually). It refers to the element the handler was bound to.
@T.J.Crowder these two names are very confusing , more intuitive to think that currentTarget is a «topmost element» , isn’t it?
To properly understand you need to know the basics of javascript.
most of the browser especially modern ones like mobile use standard javascript like:
element.addEventListener //to add Event Handlers //those eventListeners return always the event as first parameter //and this event contains the target which can be called with event.target
but older browsers or internet explorer uses different ways to achieve this
attachEvent //to add eventListener // the event needs to be called with window.event // and the target is called event.srcElement
knowing that you can write a function like this:
//addEvent checks if addEventListener exists else it uses attachEvnet //as you can see attachEvent also has only 2 parameters and needs a 'on' //before the event name function addEvent(a,e,f)/Element,Event,Function(the> //handler handles in this case the click event //it checks if the first parameter is event else it uses the window.event //it checks if inside the event exists a event.target else event.srcElement //then it loops through the parentNode until it finds(this case) the TR Element //and just to test it alerts the content of it //if you want to get the TD element replace e.target.parentNode with e.target //and TR with TD // so you get the proper row or column clicked. function handler(e) < e=e||window.event; e.target=e.target||e.srcElement; var x=e.target.parentNode; while(x.nodeName!='TR')/or>alert(x.innerHTML); > //when the page loads it it searches for the first table (note the [0]) //and adds a eventListener to the whole table. //this allows you to have one eventListener on the full table but //control every single row or column. window.onload=function()
thats why jQuery exists. to avoid all this double checks.
anyway . after some tests and as mobile browsers support the modern standard ways. i prefer to leave out jQuery from mobile webapps as it just slows down everything.
So for mobile devices i use:
function handler(e) < var x=e.target; while(x.nodeName!='TR')< x=x.parentNode; >console.log(x.innerHTML); > window.onload=function()
how to make a cell of table hyperlink
@vaichidrewar you can vote to close a question as a duplicate of another question now that you have over 3000 reputation.
11 Answers 11
yes, it’s the best way but you forgot the vertical align problem! using this way we can’t put the link exactly at the center of the td element. test it yourself. with style=»display:block;» and without style=»display:block;» i think maybe the JavaScript way is better because today JavaScript is necessary for every one. look at my answer.
yes, it’s the best way but you forgot the vertical align problem! using this way we can’t put the link exactly at the center of the td element. test it yourself. with style=»display:block;» and without style=»display:block;» i think maybe the javascript way is better because today javascript is necessary for every one.
Easy with onclick-function and a javascript link:
When using the other answers, the link does not necessarily take up all the space in the
This also does not create a true hyperlink, so for example, the link destination does not appear a the bottom of the view in Chrome, and you cannot Ctrl-click to open the destination in a new tab, etc.
This is a really ugly solution, as it prevents opening the link in a new tab in any way (as far as I know). I’ve encountered this behaviour somewhere, and it’s really annoying. It’s even more annoying if you have an actual link in the cell, suggesting it works as usual, and then when you Ctrl-click for a new tab, it opens the link in both the same tab and a new one.
Like this you can still benefit from some table cell properties like vertical-align .(Tested on Chrome)
This sort-of works, but as I move my cursor over the cell it alternates between a pointer and a hand.
(User: Kamal) It’s a good way, but you forgot the vertical align problem! using this way, we can’t put the link exactly at the center of the TD element! even with vertical-align:middle;
(User: Christ) Your answer is the best answer, because there is no any align problem and also today JavaScript is necessary for every one. it’s in every where even in an old smart phone. and it’s enable by default.
My Suggestion to complete answer of (User: Christ):
a.LN1 < font-style:normal; font-weight:bold; font-size:1.0em; >a.LN2:link < color:#A4DCF5; text-decoration:none; >a.LN3:visited < color:#A4DCF5; text-decoration:none; >a.LN4:hover < color:#A4DCF5; text-decoration:none; >a.LN5:active