This is proving surprisingly tricky. Attached is a screen of what I want from the DOM:
I want the innerHTML (Or at least I thought I did) of the td with class product-price.
Here's another screen of all the stuff I've tried and the output:
How do I get the console to return $59.99? Important it comes from the first element not the second where 59.99 also exists
Following a comment, here is the broader html:
<table cellspacing="1" class="store_location_list">
<tr>
<th class="item-type">Item<br />Type</th>
<th class="item-desc">Item<br />Description</th>
<th class="total-qty">Total<br />Quantity</th>
<th class="product-price">Product<br/>Price</th>
<th class="total-price">Total<br/>Price</th>
<th class="removeItemLink"> </th>
</tr>
<tr>
<td class="item-type">Metal Wall Art</td>
<td class="product-description-long">Metal Wall Art</td>
<td class="total-qty">1</td>
<!-- ************************************** -->
<td class="product-price">$59.99</td>
<td class="total-price">$59.99</td>
<td class="removeItemLink">Remove</td>
</tr>
</table>
document.querySelector('td.product-price').innerHTML
Use:
document.querySelectorAll('.product-price')[1].innerHTML
jsFiddle example
querySelector only returns the first match, while querySelectorAll returns all of them (hence the [1]) notation to get the second element. You can also use textContent
in place of innerHTML as it works a little faster, but you won't notice much of a difference in your case.
document.querySelectorAll('.product-price')
will return an array of elements with the given class.
document.querySelectorAll('.product-price')[n]
will give you (n+1)th element with the class
.innerHTML : will give you html content inside it, i.e. even the tags.
.textContent : will give you only text, no html tags.
What you want are the properties: innerText and innerHTML.
But you are selecting the correct item. You select all elements that have the product-price class, and the title of the table has that class.
I recommend you first to ensure you select the correct item.
Related
I am trying to select an element on a table which is on a webpage. The inner text which is on the table is a name of a professor. I am using this line of code to grab the elements.
var tableElementNode = document.querySelectorAll(".section-detail-grid.table-bordered-wrap>tbody>tr>td>div");
And yes it works with the tables on the main webpage and grabs the elements I need. However when i try going on a different course page to grab the elements of another table it does not work even though all the tables have the same format. Its as if the tables are invisible to the code and only grabs the ones on the main webpage.
However every so know and then it grabs all the elements I need on a different course page but on very rare occasions.
The last line on the code below is the element I am trying to grab.
<table class="section-detail-grid table-bordered-wrap">
<thead>
</thead>
<tbody>
<tr data-id="80886" data-index="0" class="section-item section
first linked-section">
<td class="persist row-label">
COP
</td>
<td class=" row-label">
3514
</td>
<td class="persist row-label">
001
</td>
<td class="persist row-label">
Class Lecture
</td>
<td class=" row-label">
<div>Wang, Jing</div>
Someone mentioned that it may be an ajax driven site and thats why its not grabbing all the elements all the time. Ive even tried getting the xpath of that element but it is still not being found. Why is this element invisible to my code?
My html code is-
<tr class="selected">
<td id="participantID">XXXXX1234</td>
<input type="hidden" value="000001234" id="taxID">
<td id="fullName">Y, X</td>
</tr>
Here, I want to get hidden field value. I can not use ID of hidden field to get its value because there are multiple rows which can contain hidden field with same ID as "taxID". I want to get this value using <tr> class name.
i.e. selected.
I am using below code to get its value but it is giving me 'undefined' value.
var x = document.getElementsByClassName("selected")[0];
var y = x.getElementsByTagName("input")[0];
alert(y.value);
Alert statement shows undefined value. Am I missing something over here?
First, you cannot have multiple elements in a document with identical id values. That will have to be altered and that alone may solve your problem.
Second, your HTML is invalid. The input must be inside of a td.
Next, there is no reason to use getElementsByClassName() or getElementsByTagName() when you are looking for just one element - it's wasteful because you wind up searching the entire document when you are only interested in one item.
Also, both of those methods return "live" node lists which require re-scanning the entire document every time their results are referenced. The use cases for that are limited.
Instead use .querySelector() when you want to find just one item based on any valid CSS selector and .querySelectorAll() when you want to find a set of matching elements.
Assuming these things are corrected, you can do this:
var x = document.querySelector(".selected td input[type=hidden]");
alert(x.value);
<table>
<tr class="selected">
<td id="participantID">XXXXX1234
<input type="hidden" value="000001234" id="taxID">
</td>
<td id="fullName">Y, X</td>
</tr>
</table>
You need to have a table be the parent of a tr, then the DOM lookup will properly work. Also as noted by #Rory McCrossan you will want to wrap td tag around your input element:
var x = document.getElementsByClassName("selected")[0];
var y = x.getElementsByTagName("input")[0];
alert(y.value);
<table>
<tr class="selected">
<td id="participantID">XXXXX1234</td>
<td><input type="hidden" value="000001234" id="taxID" /></td>
<td id="fullName">Y, X</td>
</tr>
</table>
(Posted solution on behalf of the OP).
After removing ID of hidden field, it is working fine. Edited code is:
<tr class="selected">
<td id="participantID">XXXXX1234</td>
<input type="hidden" value="000001234" id="taxID">
<td id="fullName">Y, X</td>
</tr>
I am working on visualforce pages. below is given the part of HTML file code that has been generated after executing the apex code.
<table class="detailList" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr></tr>
<tr>
<td class="labelCol"></td>
<td class="dataCol col02"> userName </td>
<td class="labelCol"></td> <td class="dataCol"></td>
</tr>
<tr>
<td class="labelCol"></td>
<td class="dataCol col02"></td>
<td class="labelCol"></td>
<td class="dataCol"></td>
</tr>
</table>
I want to remove the userName anchor tag from this page which is coded in line# 6 whose class Name is "dataCol col02", and there is another anchor tag with the same class name "dataCol col02" at line# 11. keep it in mind that this html is generated by executing an APEX code. Kindly guide me how could i remove the anchor tag at line#6 only..
You can use find, first and remove methods.
$('.dataCol.col02').first().find('a').remove();
In case that you want to remove the userName textNode:
$('.dataCol.col02').first().contents().filter(function () {
return this.nodeType === 3;
}).remove();
Removing all the contents:
$('.dataCol.col02').first().empty();
Use this
$(function(){
$(".dataCol.col02:first a").remove();
});
Demo
You could do something like:
var anchor = document.getElementsByClassName("col02")[0] //select first matching 'col02'
.getElementsByTagName("a")[0] //select first matching <a>
anchor.parentNode.remove(anchor)
You can see it running here: jsfiddle
This assumes of course you only ever want to remove from the first instance of something with class='col02', so is not hugely robust. I imagine the fact it's generated means you can't put in more helpful class/id attributes?
On the flipside unlike the other answers it doesn't depend on jquery : )
Try this -
$('td.dataCol.col02').eq(0).find('a').remove();
or if you would like to empty that td -
$('td.dataCol.col02').eq(0).empty();
$("table .dataCol.col02:first a").remove();
Try this:
$("tr:eq(1) > td:eq(1)").remove()
Do this >>
$(".col02:first > a").remove();
Example Fiddle
I want to change the "Yes! Pick me" into "Picked" with Jquery in the following HTML structure, I used $('#myDiv>table>tr>td>table>tr').eq(1).text("Picked"); But it was not working. Could someone shed some light on this please? Thanks!
FYI, the first td of the the first table itself contains another table...
<div id="myDiv">
<table>
<tr>
<td>
<table>
<tr>
<td>Yes! Pick me!</td>
<td>Not me..</td>
</tr>
<tr>
<td>Not me..</td>
</tr>
</table>
</td>
<td>Not me..</td>
</tr>
<tr>
<td>Not me..</td>
</tr>
</table>
</div>
The section $('#myDiv>table>tr>td>table>tr>td').eq(1).text("Picked"); does the trick, I forgot the last td part. Thanks to Rocket and everyone's help.
Try this:
$("#myDiv table table td:first").text("Picked")
$('#myDiv').find('table table td').eq(0).text(...);
Start your selection at the #myDiv element ($('#myDiv')), then find all the TD element that are inside a table that is inside another table (.find('table table td')), then only alter the first one (.eq(0)).
Documentation:
.find(): http://api.jquery.com/find
.eq(): http://api.jquery.com/eq
The main problem is that you want .eq(0) not .eq(1) as .eq() is 0-based, and you are not selecting the td, only the tr.
Other than that using > direct descendant selectors makes your selection not very robust at all.
Try $('#myDiv table table td').eq(0).text('Picked');
You can try:
$("td:contains('Yes! Pick me!')").text("Picked");
You can use the :contains(text) selector
$('#myDiv td table td:contains(Yes! Pick me!)').text('Picked');
Be careful with nested tables however because if you were to use just
$('#myDiv td:contains(Yes! Pick me!)').text('Picked');
You would get both the cell your after plus the cell it is nested within.
Your child selector query won't work because HTML5 requires the parser to insert <tbody> elements inside your <table> elements, since you've forgotten to put them in yourself. Perhaps you should consider validating your HTML?
If I understand right, .innerHTML should overwrite whatever was in a certain div or span.
For example:
<table width="90%" border="0" align="center" cellpadding="5" cellspacing="0">
<tr>
<td colspan="2" align="left">Via Email:</td>
<td width="1070" align="right"></td>
</tr>
<script>
$('#addEmail').click(function() {
document.getElementById('emailList').innerHTML = "12345";
});
</script>
<span id="emailList">
<tr>
<td width="27" align="left"><img src="icon_mail.png" width="24" height="24"></td>
<td width="228" align="left">123obama#whitehouse.com</td>
<td align="right"><span class="ui-icon ui-icon-close"></span>remove</td>
</tr>
</span>
<tr>
<td colspan="3" align="left"><br>
<input name="input4" type="text" value="vova#kremlin.ru" size="20">
<span class="ui-icon ui-icon-mail-closed"></span>Add Email</td>
</tr>
</table>
Therefor upon click of #addEmail button, everything inside would be removed and replaced by "12345".
Yet in reality it doesn't do anything to that span, but just prints out 12345 in the place, where the script is.
Any ideas what could be wrong?
The HTML is invalid — you can't wrap a <tr> in a <span>. The browser is performing error recovery on your code and producing a DOM that isn't what you expect it to be. When you try to edit the content of the span, the span probably isn't where you think it is.
… you can't put a script between table rows either.
… and you are trying to bind an event handler to a link before the link exists in the document. You either need to move the script so it appears after the link, or move the code that does the work into an event handler that runs after the link exists (such as the ready event).
It's actually your span that's wrong. A span can't ... span (I know, I know) over table rows, so it gets opened and closed somewhere between the rows (or outside the table on some browsers), so when you're overwriting it's html, it ends up somewhere else.
You should name the tr instead and overwrite its html, that should work.
You can't put a <tr> inside a <span> like that. Anyway if you're using jQuery, you should probably use its API around ".innerHTML"
$('#emailList').html("hello world");
That will do some important cleanup work for you. It's not absolutely required, but unless you know for sure what you're doing it's probably a safer option.
You are wrapping a <tr> in a span. That is going to lead to unpredictable results. Especially if you then remove the table row.