Hide and show spans with a specific class - javascript

I'm i'm trying to display songs made by an artist when i click the artist's name.
Here's my HTML
<div id="artists">
<span class="artist" id="Eminem" onclick="showSongs("Eminem")">Eminem</span>
</div>
<div id="songs">
<span style="display:none;" class="Eminem" id="Eminem - Survival" onclick="playSong('Eminem - Survival');">Survival</span>
</div>
And here is my Javascript
function showSongs(artist) {
document.getElementsByClassName(artist).styles.display="inline";
}
This is not all my code, I have more artists and more songs.
but the point is that i want the songs from an artist to display when i click the artists name
I have googled it for a while now, All i found was that i had to display span tags as inline.
If you need more information just ask and i'll edit the post

First, adjust the artist name you are sending to use single quotes, you are breaking the string by using double quotes.
<span class="artist" id="Eminem" onclick="showSongs('Eminem')">Eminem</span>
Then when you get elements by class name you are retrieving a collection and need to loop through them. Shown below:
function showSongs(artist) {
var elements = document.getElementsByClassName(artist);
for(var i = 0; i < elements.length; i++) {
elements[i].style.display="inline";
}
}
Here is a jsFiddle.

EDIT: Ah yes, see the other answers for the other half of the problem.
This code should work, the only thing I see wrong with it is this line:
<span class="artist" id="Eminem" onclick="showSongs("Eminem")">Eminem</span>
You should use single quotes inside the showSongs call:
<span class="artist" id="Eminem" onclick="showSongs('Eminem')">Eminem</span>
If that does not solve the problem, it is probably caused by some other code on the page.

getElementsByClassName returns an array-like collection. I don't think you can change the style this way.. Maybe you could try this :
function showSongs(artist) {
var artists = document.getElementsByClassName(artist);
for(var i = 0; i < artists.length; i++) {
artists[i].style.display="inline";
}
}
Would be a lot easier with jquery.

Here you go: http://jsfiddle.net/LVRGZ/3/
<div id="artists">
<span class="artist" onclick="showSongs('Eminem')">Eminem</span>
</div>
<div id="Eminem" style="display:none;">
<span id="Eminem - Survival" onclick="playSong('Eminem - Survival');">Survival</span><br/>
<span id="Another Song" onclick="playSong('Eminem - 2');">Another Song</span><br/>
<span id="A Third Song" onclick="playSong('Eminem - 3');">A Third Song</span><br/>
</div>
<script>
showSongs=function(id) {
alert("Showing "+id);
document.getElementById(id).style.display='';
}
</script>

Related

How can I add the same XML tags multiple times, with different content?

I have some problems with my code. I want to create an XML Document with JQuery / JavaScript. I am now at the point, where I want to create a few Tags and populate them each with the same tags but different content inside the tags.
Here is the code for better understand
function setItems(xmlDoc, channelTag){
const itemList = [];
const itemTitle = xmlDoc.createElement("title");
const itemLink = xmlDoc.createElement("link");
const itemGuid = xmlDoc.createElement("guid");
const itemMediaContent = xmlDoc.createElement("media:content");
const itemMediaDescription = xmlDoc.createElement("media:description");
itemList.push(itemTitle, itemLink, itemGuid, itemMediaContent, itemMediaDescription);
for (var i = 0; i < jsonObj.length; i++){
var item = xmlDoc.createElement("item");
channelTag.appendChild(item);
//Populate the <item> with the tags from "itemList" and content from "jsonObj"
$.each(itemList, function(index) {
$(channelTag).children('item')[i].appendChild(itemList[index]).textContent = jsonObj[0].title;
})
}
}
The Output of the code looks like this:
<item></item>
<item></item>
<item>
<title>Something</title>
<guid>Something</guid>
<link>Something</link>
<media:content>Something</media:description>
<media:description>Something</media:description>
</item>
It always populates the last item-Tag but not the ones above. What I want is that every item-Tag has the same child-Tags (e.g. title, link, guid and so on). Is there something i am missing some unique tags or something like that?
Edited:
Here is some minimal HTML and XML. The values for the function "xmlDoc" and "channelTag" just contains some Document Elements, where my items should be appended, like so:
<rss>
<channel>
<title>SomeTitle</title>
<atom:link href="Link" rel="self" type="application/rss+xml"/>
<link>SomeLink</link>
<description>SomeDesc</description>
<item></item>
<item></item>
<item></item>
</channel>
</rss>
<div class="col-5 col-sm-5 col-lg-3 order-2 count">
<a class="guid1"><img class="card-img image1"></a>
</div>
<div class="col-7 col-sm-7 col-lg-5 order-2">
<div class="card-body">
<a class="guid1">
<h5 class="card-title title1 overflow-title"></h5>
</a>
<p class="card-text body1 text-body overflow-body"></p>
<div class="card-body subtitle">
</div>
</div>
</div>
There are several issues with your code but the area we mostly want to focus on is this:
for (var i = 0; i < jsonObj.length; i++){
var item = xmlDoc.createElement("item");
channelTag.appendChild(item); // you're adding a node here
$.each(itemList, function(index) {
$(channelTag).children('item')[i].appendChild(... // and here
})
}
Instead of appending nodes multiple times per iteration, you should create and populate your node before add it it to channelTag.
Here's a way your could do it:
// use a "$" sign as a variable name prefix, so you know it's a Document Element and not a regular javascript variable
var $item = xmlDoc.createElement("item");
// you don't need jQuery for this iteration
itemList.forEach(function (item, index) {
$item.appendChild(itemList[index]).textContent = jsonObj[0].title;
});
// if "channelTag" is a Document Element, rename it "$channelTag"
$channelTag.appendChild(item);
Couple things about the code above:
you don't need jQuery, use forEach instead
there is no way telling what type is channelTag. If it is a selector (of type string), use $(selector), but you are using the appendChild() method before, suggesting it's actually a Document Element. In that case you don't need to wrap it with $()
I don't have the context needed to test this code, so no guarantee it'll work out of the box. But try and re-read your code and go through it top-to-bottom. For each variable, describe its type and value. I found that to be helpful when I'm lost in code.

how can i get an attribute value of all links on a page?

i'm trying to get a list of values of 'data-ctorig' property on all links marked with 'gs-title' class on this page.
i can get one the value of first link
document.querySelector('a.gs-title').getAttribute('data-ctorig')
but can have others.
also, i can get a list of nodelist (idk what is this) using
document.querySelectorAll('a.gs-title')
but i dont know how can i get a list of attribute values based in this node list.
also i've tried use :nth-of-type() but i got only null after first value
var x = document.querySelector("a.gs-title:nth-of-type(1)").getAttribute("data-ctorig")
i'm also using python with selenium webdriver to do this so if someone know how to do it on python 'll help me on the same way.
First use querySelectorAll to get all the .gs-title nodes.
var gstitles = document.querySelectorAll('a.gs-title')
You can use gstitles.length now to determine how many there are.
gstitles.length;
Next we need to setup a for loop.
Check out the code snippet below.
for (i=0;i<gstitles.length;i++)
{
console.log(gstitles[i].getAttribute('data-ctorig'));
}
var gstitles = document.querySelectorAll('a.gs-title')
for (i=0;i<gstitles.length;i++)
{
console.log(gstitles[i].getAttribute('data-ctorig'));
}
<div class="gs-title"><a class="gs-title" href="https://www.teses.usp.br/teses/disponiveis/27/27151/tde-19032008-183924/publico/AmandaTojal.pdf" target="_blank" dir="ltr" data-cturl="https://www.google.com/url?q=https://www.teses.usp.br/teses/disponiveis/27/27151/tde-19032008-183924/publico/AmandaTojal.pdf&sa=U&ved=0ahUKEwiWo7TB3-bhAhUF16wKHaWeCXoQFggEMAA&client=internal-uds-cse&cx=011662445380875560067:cack5lsxley&usg=AOvVaw2g3t_0fFH8wjhfjcku0DL3" data-ctorig="https://www.teses.usp.br/teses/disponiveis/27/27151/tde-19032008-183924/publico/AmandaTojal.pdf"><b>AMANDA</b> PINTO DA FONSECA TOJAL</a></div><div class="gs-title gsc-table-cell-thumbnail gsc-thumbnail-left"><a class="gs-title" href="https://www.teses.usp.br/teses/disponiveis/27/27151/tde-19032008-183924/publico/AmandaTojal.pdf" target="_blank" dir="ltr" data-cturl="https://www.google.com/url?q=https://www.teses.usp.br/teses/disponiveis/27/27151/tde-19032008-183924/publico/AmandaTojal.pdf&sa=U&ved=0ahUKEwiWo7TB3-bhAhUF16wKHaWeCXoQFggEMAA&client=internal-uds-cse&cx=011662445380875560067:cack5lsxley&usg=AOvVaw2g3t_0fFH8wjhfjcku0DL3" data-ctorig="https://www.teses.usp.br/teses/disponiveis/27/27151/tde-19032008-183924/publico/AmandaTojal.pdf"><b>AMANDA</b> PINTO DA FONSECA TOJAL</a></div><div class="gs-title"><a class="gs-title" href="https://www.google.com/url?q=http://www.teses.usp.br/teses/disponiveis/17/17153/tde-06012017-103806/publico/AmandaMizukamiDOCorrig.pdf&sa=U&ved=0ahUKEwiWo7TB3-bhAhUF16wKHaWeCXoQFggGMAE&client=internal-uds-cse&cx=011662445380875560067:cack5lsxley&usg=AOvVaw0Jdjapa8W60DfKRyUIAdoH" target="_blank" dir="ltr" data-cturl="https://www.google.com/url?q=http://www.teses.usp.br/teses/disponiveis/17/17153/tde-06012017-103806/publico/AmandaMizukamiDOCorrig.pdf&sa=U&ved=0ahUKEwiWo7TB3-bhAhUF16wKHaWeCXoQFggGMAE&client=internal-uds-cse&cx=011662445380875560067:cack5lsxley&usg=AOvVaw0Jdjapa8W60DfKRyUIAdoH" data-ctorig="http://www.teses.usp.br/teses/disponiveis/17/17153/tde-06012017-103806/publico/AmandaMizukamiDOCorrig.pdf"><b>AMANDA</b> MIZUKAMI</a></div>
You meant this? :)
var links = document.querySelectorAll('a.gs-title');
var list = [];
links.forEach((link) => {
list.push(link.getAttribute('data-ctorig'));
});
console.log(list);
<a class="gs-title" data-ctorig="Test1"><b>AMANDA</b> MIZUKAMI</a>
<a class="gs-title" data-ctorig="Test2"><b>AMANDA</b> MIZUKAMI</a>
<a class="gs-title" data-ctorig="Test3"><b>AMANDA</b> MIZUKAMI</a>

How to search for <p> by id for condition in Javascript, and then output text in another <p>?

Sorry, I tried to search for an answer, but I couldn't find exactly what I was looking for.
I am trying to make and webpage using Javascript, and I need some sort of decoder. For example, I have one abbreviation which is "NN", which stands for "Noun Nominative". Another abbreviation is "NA" which stands for "Noun Accusative". Another is "AN" which is "Adjective Nominative". There are many (too many) mixed-and-matched instances of these abbreviations, so I am trying to make a easy way for my Javascript/HTML code to search the whole page for every instance of "N" when it is the part of speech, and then output "Noun" in a different <p> when the abbreviation containing "N" is clicked. I hope this makes sense. So I came up with this:
document.querySelector("div.abbreviation").onclick = parseWord;
function parseWord(event) {
if (event.target.id === 'noun') {
document.getElementById("part-of-speech-decoded").innerHTML = "Noun";
}
}
<div class="abbreviation">
<p id="noun">N</p>
<p id="nominative">N</p>
</div>
<div id="decoder">
<p id="part-of-speech-decoded"></p>
<p id="case-decoded"></p>
</div>
Obviously, it is not correct by a long shot and the formatting is terrible (I am very new to coding), but I hope you can see what I am trying to do. So I want my function to search if p id = "noun", then when the div containing p id="noun" is clicked, I want the word "Noun" to show up in where p id="part-of-speech-decoded" is.
Any help would be appreciated!
You can use event.target.id and capitalise the first letter:
document.querySelector("div.abbreviation").onclick = parseWord;
function parseWord(event) {
var word = event.target.id.charAt(0).toUpperCase() + event.target.id.slice(1);
document.getElementById("part-of-speech-decoded").innerHTML = word;
}
<div class="abbreviation">
<p id="noun">N</p>
<p id="nominative">N</p>
</div>
<p id="part-of-speech-decoded"></p>
To achieve expected result, use below option of creation options Object with 'id' and its value to be displayed
document.querySelector("div.abbreviation").onclick = parseWord;
let abbrArr = {
'noun' : 'Noun',
'nominative' : 'Nominative',
'nn':'Noun Nominative',
'na':'Noun Accusative',
}
function parseWord(event) {
document.getElementById("part-of-speech-decoded").innerHTML = abbrArr[event.target.id];
}
<html>
<body>
<div class="abbreviation" onclick="parseWord(this)">
<p id="noun">N</p>
<p id="nominative">N</p>
<p id="nn">NN</p>
<p id="na">NA</p>
</div>
<div id="decoder">
<p id="part-of-speech-decoded"></p>
<p id="case-decoded"></p>
</div>
</body>
</html>
codepen - https://codepen.io/nagasai/pen/jJvxpY?editors=1010

Trying to split an Alt tag in an Object and then place it all into an Array

I have some products on a page that I need to grab the Alt tag from. I need to turn them into an Object. After that they need to go into an Array.
I was thinking of creating a for loop to loop through the Alt tags, but I am stuck as to how to Split the Alt tag at the pipe '|'.I keep getting an Invalid or unexpected Token. This is code and below that is what I have.
Right at the end I have the jQuery version that works fine, but I want to know the Vanilla Javascript way. As I want to step away from jQuery and learn how to code better in Javascript.
<div class="product col-xl-3 col-lg-3 col-md-4 col-sm-6 col-12" alt="0016|AUX Cable|2.39|5m|Black|2|Tech-Aux">
<a href="/0016/product">
<img class="productImage" src="/static/store/images/products/download-10.jpg">
</a>
<a href="/0016/product">
<h3>AUX Cable</h3>
</a>
<h4 class="price">£2.39</h4>
<input type="button" class="button style_one addToCartOne" value="Add To Cart">
</div>
<div class="product col-xl-3 col-lg-3 col-md-4 col-sm-6 col-12" alt="0015|USB 2 Type A|3.49|10m|Black|300|Tech-Usb">
<a href="/0015/product">
<img class="productImage" src="/static/store/images/products/download_Jb4ucER.jpg">
</a>
<a href="/0015/product">
<h3>USB 2 Type A</h3>
</a>
<h4 class="price">£3.49</h4>
<input type="button" class="button style_one addToCartOne" value="Add To Cart">
</div>
Here is my code:
var products = document.querySelectorAll('.product');
for(var i=0; i<products.length; i++){
products[i].alt.split(“|”);}
Thank you for any advise. Also any help as to where I can look this up in the future would be great as well.
This is the jQuery code that works. And this is what I want to achieve in Javascript:
var products = [];
$.each($(".product"), function(){
var prodOb = {};
var prodDetails = $(this).attr("alt").split("|");
prodOb.id = prodDetails[0];
prodOb.name = prodDetails[1];
prodOb.price = prodDetails[2];
prodOb.brand = "Some Company";
products.push(prodOb)
})
console.log(products)
You're really close, you've done the big that people find tricky (using the DOM instead of jQuery to find the elements).
Two things:
You seem to have stopped in the middle. You have the code using jQuery to do this, and most of that code has nothing to do with jQuery, but you haven't used that code in your attempt.
You're using fancy quotes (“”), but JavaScript requires boring straight up-and-down quotes (").
If we just copy the code from the sample using jQuery into the code you've already written, and fix the quotes, use elements instead of products to conflict with the array you're creating, use a reasonable placement for }, and add a missing semicolon or two, we get:
var products = [];
var elements = document.querySelectorAll('.product');
for (var i = 0; i < elements.length; i++){
var prodDetails = elements[i].getAttribute("alt").split("|");
var prodOb = {};
prodOb.id = prodDetails[0];
prodOb.name = prodDetails[1];
prodOb.price = prodDetails[2];
prodOb.brand = "Some Company";
products.push(prodOb);
}
console.log(products);
Or we can use Array.prototype.map, but for one it isn't a lot more concise:
var products = Array.prototype.map.call(
document.querySelectorAll('.product'),
function(element) {
var prodDetails = elements.getAttribute("alt").split("|");
return {
id: prodDetails[0],
name: prodDetails[1],
price: prodDetails[2],
brand: "Some Company"
};
}
);
console.log(products);
Note: We have to use .getAttribute("alt") instead of .alt because the HTML is invalid. div elements have no alt attribute. I have to admit in the first version of this question I didn't look at the HTML and assumed that it was valid, where the alt attribute is used on an img element (which has the .alt property).

Javascript Need to pull a value from a function within an array

Here is my code:
<script>
window.addEvent('domready', function(){
new Request.Stocks({
stocks: ['SXCL'],
onComplete: function(yahoo){
var result = '';
Array.each(Array.from(yahoo.query.results.quote), function(quote){
result += '<div class="company-ticks"></div>
<span class="company">Steel Excel ({Name})</span>
<span class="sub-info"> - OTC Markets<span> </div> <div><span class="value">
{LastTradePriceOnly}</span><span class="changeup">
<img src="change-up.gif" class="change-img" />{Change}
({ChangeinPercent})</span></div></div>'.substitute(quote);
}, this);
$('stocks').set('html', result);
},
onRequest: function(script){
$('stocks').set('text', 'Loading...');
}
}).send();
// Request.Stocks.element.js
});
</script>
You see where I have the variable {Change]. I need to determine if this variable is a positive or negative value. If it is positive then it should display the class as "changeup" and the image as change-up.gif. If the value is negative then the class displayed should be "changedown" and the image would be change-down.gif
The images are a green arrow up and a red arrow down. The classes make the color altrenate between red and green.
Because this is within an array thats being called using a function I'm not sure how to go about this. I assume I would have to split up my "result" into 3 sections. The section before, the section that sets the class and the image, and then the rest of the result.
Any help would be appreciated.
This uses Javascript with mooTools. It's pulling a stock quote from yahoo.
I made the assumption that the Change variable was a property of the quote object. Otherwise that's an easy fix in the code bellow.
Array.each(Array.from(yahoo.query.results.quote), function (quote) {
quote.changeImage = (quote.Change > 0) ? 'change-up.gif' : 'change-down.gif';
result += '<div class="company-ticks"></div>
<span class="company">Steel Excel ({Name})</span>
<span class="sub-info"> - OTC Markets<span> </div> <div><span class="value">
{LastTradePriceOnly}</span><span class="changeup">
<img src="{changeImage}" class="change-img" />{Change}
({ChangeinPercent})</span></div></div>'.substitute(quote);
}, this);
Please note, producing HTML in the was you are doing is a bit risky and hard to maintain.

Categories

Resources