How to make this code work with .each function? - javascript

I have the following piece of code in a script tag that I need to get working for all #tel ID elements on the page. I can only get it to work for the first #tel element. I've been trying to use .each function - but no luck...
The reason being is that I can't seem to get the ACF repeater URL to suit my needs here. The Advanced section of the dynamic content link part is not displaying. So I am trying to make a hack in an HTML widget for this.
But I need it to work for all buttons with button ID #tel.
Here's the code:
var link = document.getElementById('tel');
var href = link.getAttribute('href');
link.setAttribute('href', href.replace('http://', 'tel:'));
<div class="elementor-button-wrapper">
<a href="http://44400907" class="elementor-button-link elementor-button elementor-size-xs" role="button" id="tel">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text elementor-inline-editing" data-elementor-setting-key="text" data-elementor-inline-editing-toolbar="none">
44 40 09 07
</span>
</span>
</a>
</div>

In HTML/javascript element IDs must be unique. So in your case you can use class for that:
var links = document.querySelectorAll('.tel');
for(let i = 0; i < links.length; i++)
{
let link = links[i];
var href = link.getAttribute('href');
link.setAttribute('href', href.replace('http://', 'tel:'));
}
<div class="elementor-button-wrapper">
<a href="http://44400907" class="elementor-button-link elementor-button elementor-size-xs tel" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text elementor-inline-editing" data-elementor-setting-key="text" data-elementor-inline-editing-toolbar="none">44 40 09 07</span>
</span>
</a>
</div>
<div class="elementor-button-wrapper">
<a href="http://44400908" class="elementor-button-link elementor-button elementor-size-xs tel" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text elementor-inline-editing" data-elementor-setting-key="text" data-elementor-inline-editing-toolbar="none">44 40 09 08</span>
</span>
</a>
</div>
<div class="elementor-button-wrapper">
<a href="http://44400909" class="elementor-button-link elementor-button elementor-size-xs tel" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text elementor-inline-editing" data-elementor-setting-key="text" data-elementor-inline-editing-toolbar="none">44 40 09 09</span>
</span>
</a>
</div>

Related

Selecting anchors within div by div id

New to JS, just dipping in to solve a problem (I bet everyone says that!). I need to write a script to select an anchor and insert an <img>.
There are several <a>'s within a div that has an id of _nwa_social_logins. I need to add an img tag to one of those. I'm not sure of the best way of doing this.
It's a captive portal page served up by a product we use, and the bit I'm interested in looks like this:
<div id="_nwa_social_logins">
<a class="btn btn-facebook" href="<url>/guest/social-media.php?oauth_init=1&oauth=facebook" title="">
<i class="icon-facebook"></i> Facebook
</a>
<a class="btn btn-linkedin" href="https://<url>/guest/social-media.php?oauth_init=1&oauth=linkedin" title="">
<i class="icon-linkedin"></i> LinkedIn
</a>
<a class="btn btn-google" href="https://<url>/guest/social-media.php?oauth_init=1&oauth=google" title="">
<i class="icon-google"></i> Google
</a>
<a class="btn btn-twitter" href="https://<url>/guest/social-media.php?oauth_init=1&oauth=twitter" title="">
<i class="icon-twitter"></i> Twitter
</a>
<a class="btn btn-github" href="https://<url>/guest/social-media.php?oauth_init=1&oauth=azure" title=""><img src="images/icon-microsoft.png" align="middle">Microsoft Azure AD
</a>
<a class="btn btn-github" href="https://<url>/guest/social-media.php?oauth_init=1&oauth=amazon" title="">Amazon</a>
</div>
So far I have
let items = document.querySelector('#_nwa_social_logins a');
To be honest I don't know how to even check if that has selected anything.
I need to select the Amazon anchor and set an <img> for the button. If the selection above gives me a list of <a>s (objects?) can I loop through them and look for one that has an href value that ends with 'amazon'?
Thank you
You can do this:
<script>
window.addEventListener('load', () => {
let links = document.querySelectorAll('#_nwa_social_logins a');
links.forEach((link, index) => {
if (link.getAttribute("href").toLowerCase().lastIndexOf('amazon') >= 0)
link.innerHTML = '<img src="someimage">';
});
});
</script>

How to get an Attribute from Each Result of querySelectorAll()

I am trying to do this:
Search for all the spans in my structure
Get the id value from each span
Update the parent with that text for test purposes
The reason for this work is that I am doing front-end customizations for an application and trying get some WAI-ARIA labelled-by values set on a parent element.
The problem is that many of the needed values come from an COTS application that I am working with/around. These needed input are not always set in a good sequence in the DOM.
I have been looking at a JS solution to get around this.
<div class="fluid-form-container">
<ul id="accordionGroup" class="Accordion" data-allow-multiple="">
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion1id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect1" id="accordion1id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="More_Info_Form_Section_Label">More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion2id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect2" id="accordion2id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="Even_More_Info_Form_Section_Label">Even More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
</div>
//My bad javaScript so far
var found_elements = [];
var outers = document.querySelectorAll('.FormSection');
for(var i=0; i<outers.length; i++) {
var elements_in_outer = outers[i].querySelectorAll("span");
var updateValue = elements_in_outer.getAttr("id");
outers[i].closest("h3").innerHTML = updateValue;
}
The expect results:
- parent tag innerHTML set to the id value of each span in the structure
Actual results:
- I'm getting errors because I am not sure what I need to use to get that id from each span found
querySelectorAll() returns a NodeList , so elements_in_outer.getAttr("id") won't work and should be replaced with querySelector()
there is no getAttr, use getAttribute
( i replaced your for with a forEach )
var found_elements = [];
var outers = document.querySelectorAll('.FormSection').forEach(div => {
var elements_in_outer = div.querySelector("span");
var updateValue = elements_in_outer.getAttribute("id");
div.closest("h3").innerHTML = updateValue;
});
<div class="fluid-form-container">
<ul id="accordionGroup" class="Accordion" data-allow-multiple="">
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion1id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect1" id="accordion1id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="More_Info_Form_Section_Label">More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion2id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect2" id="accordion2id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="Even_More_Info_Form_Section_Label">Even More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
</div>
If you know beforehand that you will only use the span elements that have an id, then use [id] in the querySelectorAll selector likewise
document.querySelectorAll('span[id]')
If you will use that as an array, then you need
[... document.querySelectorAll('span[id]')]
Assigning the new value would be something like this:
[... document.querySelectorAll('span[id]')].forEach(s => s.closest("h3").innerHTML = s.id)

Random quote machine or tweet current quote doesn't work

jQuery on click function to tweet current quote doesn't want to work. What is wrong here. I have to build random quote machine and tweet current quote. I've managed to do JSON API but cannot figure out how to tweet current quote. Please help.
HTML:
<div class="container-fluid">
<div class = "well">
<div class="row">
<h2 class="text text-center"><i class="fa fa-quote-left"> </i> Hey, what when and why there is no and yes?</h2>
<p class="author">-Alina Khachatrian</p>
<div class="buttons">
<div class="row">
<div class="col-xs-6">
<a id="tweet-quote" title="Tweet current quote" target="_blank" href="#">
<i class="fa fa-twitter fa-2x"></i>
</a>
</div>
<div class="col-xs-6">
<button type="button" class="btn btn-default btn-transparent" id ="getNewQuote" title="Get a new quote">New Quote</button>
</div>
</div>
<footer class="text-center">
<hr>
<p>Written and coded by Edgar Kiljak.</p>
</footer>
</div>
</div>
JS:
$(document).ready(function(){
$(".btn").on("click", function(){
$.getJSON("http://quotes.stormconsultancy.co.uk/quotes.json", function (json) {
var html = "";
var len = json.length;
var index = Math.floor(Math.random() * len);
var val = json[index];
html += "<div class = 'newQuote'>";
html += "<h3>'" + val.quote + "'</h3>";
html += "</div>";
$(".author").text(val.author);
$(".text").html(html);
$('#tweet-quote').on("click",function(){
window.open("https://twitter.com/intent/tweet?text="+
$(val.quote).text() +"&via=your-app-name&original_referer=your-url");
});
});
});
});
First problem I had was that I couldn't even see the link to Tweet Current Quote. I had to add the text in the anchor:
<a id="tweet-quote" title="Tweet current quote" target="_blank" href="#">
<i class="fa fa-twitter fa-2x"></i>
TWEET CURRENT QUOTE
</a>
Second: it was popping up the new Twitter window, but not filling the text. In your onclick code, the $(val.quote).text() was unnecessary - just use val.quote
Third: you'll see that in addition to opening the new Twitter window, it is opening another occurrence of your own page. This has to do with how you have the tweet-quote anchor defined in your html, but the easiest way to stop it is to add return false in your onclick so that the target in the anchor doesn't fire:
$('#tweet-quote').on("click",function(){
window.open("https://twitter.com/intent/tweet?text="+
val.quote +"&via=your-app-name&original_referer=your-url");return false;
});
Fourth: if you load a second 'New Quote', and then click the 'Tweet This Quote', you'll see that it opens two new windows -- it is tweeting both the old and the new quotes. This is because the on("click") is cumulative. You should clear out any existing function before setting the new one:
$('#tweet-quote').unbind("click");
$('#tweet-quote').on("click",function(){
window.open ...
Fifth: Usually when you post a question here, "doesn't work" is not a sufficient explanation. You should explain what's not working, or what is working differently than you want it to. Error messages if there are any. What you saw in the console logs. Some people get real sticky about that. And some people will probably get sticky about me doing your homework for you. Good luck though!

Get element by classname inside certain div

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/

How can Javascript capture these values?

Let's say I have a webpage that has this in it:
<a href="https://www.youtube.com/analytics?vmv=2#fi=v-FLp5ViIYS7s" class="yt-uix-tooltip" title="View stats">
<span class="vm-video-metric video-view-count">
<span>
<span class="vm-video-metric-icon">
<img src="//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif" alt="">
</span>
<span class="vm-video-metric-value">
1,644
</span>
</span>
</span>
<span class="vm-video-metric video-likes-count">
<span>
<span class="vm-video-metric-icon">
<img src="//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif" alt="">
</span>
<span class="vm-video-metric-value">
13
</span>
</span>
</span>
<span class="vm-video-metric video-dislikes-count">
<span>
<span class="vm-video-metric-icon">
<img src="//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif" alt="">
</span>
<span class="vm-video-metric-value">
3
</span>
</span>
</span>
I would like to capture the three values encapsulated by the <span class="vm-video-metric-value"></span> tags.
In Javascript, this would normally be done using the id tag. But since there is no id tag, how can these values be captured?
Use the getElementsByClassName method, like so.
var elements = document.getElementsByClassName("vm-video-metric-value");
for (var i = 0; i < elements.length; i++) {
console.log(elements[i].innerHTML);
}
var qsa = document.querySelectorAll("span.vm-video-metric-value"), l = qsa.length, i;
var vals = [];
for( i=0; i<l; i++)
vals.push(parseInt(qsa[i].firstChild.nodeValue.replace(/[^0-9]/g,''),10));
vals is now an array containing the numbers you wanted extracted. Requires a browser capable of querySelectorAll, which almost all are (IE7 and down are not).
If you're using jQuery, and you should! It's really simple to learn and it will take you a week tops to start using it:
$('span.vm-video-metric-value').each(function() {
console.log($(this).text());
});
"For each span with class vm-video-metric-value, print the text inside to the console."
Easy as pie!
Please give jQuery a shot, it's a great library.

Categories