I'm pretty new to javascript. I have this sample table. I want to be able to get the "http://www.msn.com" but haven't been able to do so. How should I do this?
thanx in advance
j
<body>
<div id="tableContainer">
<table width="100%">
<thead>
<tr>
<th width="16%" > </th >
<th width="62%"> Otras acciones</th >
<th class="sort" width="2%"> Código certificado</th>
<th class="sort" > Descripción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="iconos" >
<span class="sigAccion">
<a href="#" class="sigIcnHref" title="Duplicar" />
<span class=" btnDuplicar">
</span></a>
<a href="http://www.msn.com" class="sigIcnHref" title="Modificar" />
<span class=" btnModificar">
</span></a>
</span> </td>
<td class="AccionRegistro">
<ul>
<li>
<a href="#" >Docència </a></li>
<li>
<a href="#" >Matrícula(S) </a></li>
<li>
<a href="#" >Plans(1) </a></li>
<li>
<a href="#" >Professors(1) </a></li>
<li>
<a href="#" >Horaris(9) </a></li>
<li>
<a href="#" >HorarisProfessors(1) </a></li>
</ul></td>
<td > <sup>2</sup>CAMD</td>
<td> Cert. Alumno Matriculado Ext.</td>
</tr>
</tbody>
</table>
</div>
</body>
straight javascript is pretty easy.
grab a reference to a known element above the a element higher up the tree
get a list of a elements under the known element
match the href property to the value you know
var anchor = null;
var container;
var items;
container = document.getElementById('tableContainer');
items = container.getElementsByTagName('a');
for (var j = 0; j < items.length; j++) {
if (items[j].href === 'http://www.msn.com') {
anchor = items[j];
break;
}
}
it would be better if you could directly reference the table element and then get a list of a elements from there, but if that's the only table in tableContainer it's fine.
for checking the href property for a known value, i usually go with a case-insensitive regex but this should be fine for your case.
Using a framework like jQuery it's pretty simple:
var href = $('#tableContainer .iconos a[title=Modificar]').attr('href');
Using plain Javascript it's more complicated if you can't simply add an id to the element to make it easier to locate it. You can for example look through all links in the page:
var href;
var links = document.links;
for (var i = 0; i < links.length; i++) {
if (links[i].title == 'Modificar') href = links[i].href;
}
you can also do this by using jQuery
$('#tableContainer a').each(function() {
if (this.href == 'http://www.msn.com'){
// Do something like $(this).hide();
}
else {
// Do somthing like $(this).show();
}
});
here is an example of JSFiddle
If the structure is always like this, a code for Prototype would look like this:
var allLinks = $$('#tableConatiner tbody tr td span a');
var msnLInk = allLinks[1].href;
You can also use jQuery with a similar selector or even pure JS which will need some additional selections. But using an id attribute (e.g. "msnLink") you can get it using a direct selection:
var msnLink = $('msnLink').href;
I can you extend the code with an ID?
EDIT: If the title or class is unique and always the same you can also use one of the following lines:
var msnLink = $$('a[class="sigIcnHref"]').first().href;
var msnLink = $$('a[title="Modificar"]').first().href;
Can you give us some more information about the structure and what you want to do with the element after selecting it?
Related
I have the following code where I want to retrieve the value of the span element inside an anchor tag, inside a list element with an id.
parseInt($('#top_cart_button.span').text(), 10);
<li id="top_cart_button">
<a href="default.asp?cmd=showCart" rel="nofollow">
<span>€ 55,00</span>
</a>
</li>
How can I do it?
Thank you
#top_cart_button.span will try to find the first element with class span that is a child of the element with id top_cart_button. You want to find the element with the tag span and not the class. To do so, remove the .. Then, to remove the extra character, you can extract only the numbers from the input using the extractDigits function below.
Here's a working example:
let InputText = $('#top_cart_button span').text();
let InputDigitsOnly = extractDigits(InputText);
function extractDigits(input) {
return input.match(/\d+/g).map(Number);
}
console.log(parseInt(InputDigitsOnly, 10));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li id="top_cart_button">
<a href="default.asp?cmd=showCart" rel="nofollow">
<span>€ 55,00</span>
</a>
</li>
EDIT:
var prezzo = parseInt($('.mainPriceAmount').text().split(",")[0], 10);
var InputText = $('#top_cart_button span').text().split(",")[0];
var InputDigitsOnly = extractDigits(InputText);
function extractDigits(input) {
return input.match(/\d+/g).map(Number);
}
var carrello = parseInt(InputDigitsOnly, 10);
var somma = prezzo + carrello;
var customLink = '<img alt="Hello" src="https://ps.w.org/click-fraud-check/assets/icon-128x128.png?rev=2160665"/>';
if (prezzo >= 199 || somma >= 199) {
$('#customHTML').show();
$('#sped').html(customLink);
}
#customHTML {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th scope="row">Cart:</th>
<td>
<p id="top_cart_button"><span>€ 199,00</span></p>
</td>
</tr>
<tr class="price">
<th scope="row">Price:</th>
<td data-label="">
<h3 class="mainPrice"><span class="mainPriceAmount">99,00</span></h3>
</td>
</tr>
<tr id="customHTML" style="display:none">
<th scope="row">Shipping:</th>
<td>
<p id="sped"></p>
</td>
</tr>
</table>
span is not a class but an element, this works:
parseInt($('#top_cart_button span').text(), 10);
<li id="top_cart_button">
<a href="default.asp?cmd=showCart" rel="nofollow">
<span>0,00</span>
</a>
</li>
If its necessarily inside an anchor tag. (meaning if you want to ignore other spans that are not inside the "a" tag. )
$("li#top_cart_button a span").text(); //or html() if you are trying to get html.
and same for the function
parseInt($("li#top_cart_button a span").text(), 10);
You're almost nearly there just remove the "." between top_cart_button and span.
$('$('#top_cart_button span')')
Gets the span "element" in top_cart_button whereas your statement has a "." prefix which gets the first element with span "class" name.
function getDigitsFromString(str){
const regex = /\d+[.]?\d+/g;
const result = regex.exec(str.replace(',','.'));
if(result[0] !== null){
return parseFloat(result[0]);
}
return;
}
console.log(getDigitsFromString($('#top_cart_button > a > span').text()));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li id="top_cart_button">
<a href="default.asp?cmd=showCart" rel="nofollow">
<span>€ 55,55</span>
</a>
</li>
I am trying to click some buttons in a page which has this html code
<div class="a">
<span>
<a class="b" role="button">test</a>
</span>
</div>
So what i've tried is to take ONLY the div's class a
var buttons = document.getElementsByClassName('a').getElementsByClassName('b');
for(var i = 0; i <= buttons.length; i++)
buttons[i].click();
Is there anyway to get the button with class name b but Only the one that is inside the div with class name a ??
P.S. i have also tried and this
var buttons = document.getElementsByClassName('a').getElementsByTagName('span').getElementsByClassName('b');
for(var i = 0; i <= buttons.length; i++)
buttons[i].click();
But i get an empty array [ ] as a response when I console.log(buttons)
You can use querySelector to overcome the issue.
document.querySelectorAll("div.a a.b");
You can use jquery and do
var buttons = $('.a > .b');
Here's an XPath solution:
let res = document.evaluate('//*[#class="a"]//*[#class="b"]',document,null,XPathResult.ANY_TYPE,null);
res.iterateNext().click();
<div class="a">
<span>
<a class="b" role="button" onclick="console.log('clicked!')">test</a>
</span>
</div>
Unfortunately Internet Explorer still doesn't support the XPath API.
Since only one div will be assigned the class='a', you can either supply an ID instead, or, you can do this :
var spans = document.getElementsByClassName('a')[0].getElementsByTagName('span');
// [0] indicates the first element with the class='a'
for(var i = 0; i < spans.length; i++) {
spans[i].getElementsByClassName('b')[0].click();
}
<div class="a">
<span>
<a class="b" role="button" href="javascript:void(0)" onclick="console.log(this.innerHTML+' was clicked !')">test 1</a>
</span>
<span>
<a class="b" role="button" href="javascript:void(0)" onclick="console.log(this.innerHTML+' was clicked !')">test 2</a>
</span>
<span>
<a class="b" role="button" href="javascript:void(0)" onclick="console.log(this.innerHTML+' was clicked !')">test 3</a>
</span>
</div>
This works perfectly, here it is : https://jsfiddle.net/nd8m7mms/4/
I have a number of <li> items, which call the same onmouseover javascript function.
The function needs to extract some data from the element that calls it, to fill some name and tel variables. This data is typed in capitals in the html code below.
Any idea on how to do this is really appreciated.
My HTML:
<li id="item1" onmouseover= "onmouseoveragent(this)" >
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme"> NAME TO BE PASSED TO JS
<strong class="tel">NUMBER TO BE PASSED TO JS</strong>
</p>
</li>
MY javascript:
<script language="javascript" type="text/javascript">
function onmouseoveragent(e) {
var name = e.?????;
var tel = e.?????;
};
</script>
yes you do something like this
JAVASCRIPT:
var elements = document.getElementsByClassName('data-item');
var mouseoverHandler = function() {
var name = this.getElementsByClassName('name')[0].textContent,
tel = this.getElementsByClassName('tel')[0].textContent;
alert('Name - ' + name + "\nTel - " + tel);
}
for( var i = 0; i < elements.length; i++ ) {
var current = elements[i];
current.addEventListener('mouseover', mouseoverHandler);
}
HTML MARKUP:
<li id="item1" class="data-item">
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme">
<span class="name">John Smith</span>
<strong class="tel">555-666-777</strong>
</p>
</li>
<li id="item1" class="data-item">
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme">
<span class="name">Caprica Smith</span>
<strong class="tel">545-334-641</strong>
</p>
</li>
MDN - document.getElementsByClassName();
MDN - element.textContent
It won't be e.something because e is referring to the event that just happened, that has nothing to do the other elements in the DOM
Demo
Well, there is an easier way to do it, just traverse the childNodes of your current hovered element and parse the results. Here is a working JSFiddle of the snippet below(yes, it works with all the LIs matching that structure):
function onmouseoveragent(e) {
var children = this.childNodes,
name = null,
tel = null;
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.tagName === 'P') {
name = child.firstChild.nodeValue; // the first node is the text node
tel = child.childNodes[1].firstChild.nodeValue; // the strong's text node
break; // let's stop the iteration, we've got what we needed and the loop has no reason to go on
}
}
console.log(name, tel); // "NAME TO BE PASSED TO JS " "NUMBER TO BE PASSED TO JS"
}
The only difference in HTML is that you need to pass your handler this way:
<li id="item1" onmouseover="onmouseoveragent.call(this, event)">
So this inside the handler will refer to the element and not to the global object.
I suggest you two thing one change the structure of you li tag i.e; make the tag as shown
<li id="item1" class="someClass" >
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme">NAME TO BE PASSED TO JS </p>
<strong class="tel">NUMBER TO BE PASSED TO JS</strong>
</li>
remove strong from p because when you try to fetch p(data to be passed the strong tag will come along with it so better change it)
and also try jquery it will give you more flexibility and ease of use(what i feel)
$(".someClass").mouseover(function(e){
var name = $(e.target).find("p:first").html()
var tel = $(e.target).find("strong:first").html()
})
try this
function onmouseoveragent(e) {
var text = e.getElementsByClassName('hideme')[1].textContent;
var name = text.split("\n")[0]; var num = text.split("\n")[1]; alert(name); alert(num); }
I want to change the function name inside of a for loop to something like this.
<script>
for (var x=1;x<10;x++){
function name_x(){
code
}
</script>
So, 10 functions are produced with the names name_1, name_2 etc.
Thanks
Edit:
This is what I need a for loop around to create 5 functions id_1, id_2, id_3, id_4, id_5
<html>
<head>
<script>
function id_1(a){
var id = document.getElementById(a);
if (id.innerHTML==="innerHTML2"){
id.innerHTML="innerHTML1";
}
else if (id.innerHTML==="innerHTML1"){
id.innerHTML="innerHTML2";
}
}
</script>
</head>
<body>
<a id="id1" href="javascript:id_1('id')">innerHTML1</a>
<a id="id2" href="javascript:id_2('id')">innerHTML1</a>
<a id="id3" href="javascript:id_3('id')">innerHTML1</a>
<a id="id4" href="javascript:id_4('id')">innerHTML1</a>
<a id="id5" href="javascript:id_5('id')">innerHTML1</a>
</body>
</html>
This looks pretty nefarious, but if you're in a browser you could use window as the global object. Otherwise, define some object to house the methods:
var obj = {}, x;
for (x = 1; x < 10; x++) {
obj['name_' + x]() { /* code */ }
}
Then you can call via obj.name_1() or obj['name_1']().
You can create an array of functions instead:
var fs = [];
for (var x = 1; x < 10; x++){
fs.push( function() {
/* code */
});
}
fs[1](); // call second function
You could use an object instead, but I wouldn't recommend it.
Since you have code that should apply directly to the link you clicked on, you can pass a reference to the link using this. Also, the javascript code will need to be placed in onclick, not href. If you need an href value to make it appear like a link, you can use #:
<a id="id1" href="#" onclick="javascript:swapContents(this);">innerHTML1</a>
Then you can use the argument passed in as a reference to the element (it is a good programming practice to use meaningful function names, so I've renamed the function to swapContents):
function swapContents(el){
if (el.innerHTML === "innerHTML2"){
el.innerHTML = "innerHTML1";
} else if (el.innerHTML === "innerHTML1"){
el.innerHTML = "innerHTML2";
}
}
Also, all elements should have a unique id value according to the HTML spec. If you want them to be unified in some way, give them the same class or name, or a custom made-up attribute:
<a id="id1" class="id" href="#" onclick="javascript:swapContents(this);">innerHTML1</a>
<a id="id2" class="id" href="#" onclick="javascript:swapContents(this);">innerHTML1</a>
<a id="id3" class="id" href="#" onclick="javascript:swapContents(this);">innerHTML1</a>
<a id="id4" class="id" href="#" onclick="javascript:swapContents(this);">innerHTML1</a>
<a id="id5" class="id" href="#" onclick="javascript:swapContents(this);">innerHTML1</a>
Demo: http://jsfiddle.net/V6yG9/
I need to get the name of the previous sibling . to keep it simple i have some sample code
<html>
<head>
<script type="text/javascript">
function myFunction()
{
var itm=document.getElementById("item2");
alert(itm.previousSibling.name);
}
</script>
</head>
<body>
<p name='pn'>paragraph</p>
<button id='item2' onclick="myFunction()">Try it</button>
</body>
</html>
Edit:
<table id="sort">
<tr name="nodrag nodrop">
<td colspan=3><strong><a style="cursor:pointer;" class="toggle">Group 1</a></strong> </td>
<td style="text-align: right;"><a class="button3" href="#" ><span> Edit </span></a> <a class="button3" href="#" ><span> Delete </span></a></td>
</tr>
<tr id="1" class="tr_group"'>
<td style="width:10px;" class="dragHandle"> </td>
<td>Umair Iqbal</td>
<td><span style="font-size: 12px; color: #999; line-height: 100%;">A Student at TUM</span></td>
<td style="text-align: right;"><a class="button3" href="#" ><span> Edit </span></a> <a class="button3" href="#" ><span> Delete </span></a></td>
</tr>
The Ist row is the previous sibling of the second row. I want the name of the 1st row and all my ids will be dynamic
thanks
Using jQuery it would be:
$('#item2').prev().attr("name");
With regular javascript you would need to use the following function (to ensure whitespace nodes are ignored)
getPreviousSiblingName(document.getElementById("item2"))
function getpreviousSiblingName(element) {
var p = element;
do p = p.previousSibling;
while (p && p.nodeType != 1);
return p.attributes["name"].value;
}
That's because more likely your previousSibling will be a text node and not an element node. You need previousElementSibling (where supported) or a loop that will get the previousElement until the nodeType will be 1 (Node.ELEMENT_NODE).
In addition, name is not applying to p element (see https://developer.mozilla.org/en/DOM/Element.name) it could be better if you use a custom attribute (like an HTML5 data-* attribute, in your case data-name maybe) and therefore use dataset to get the attribute's value, or a generic getAttribute.
Of course library like jQuery can help to abstract all those things, the explanation is related to just vanilla JavaScript.