Easy way to replace parts of code with other parts of code - javascript

I'm making a small website for a game called League of Legends that compares matchup data (what champion counters a certain champs counters) and prints out results on a webpage. I'm using this html code that shows character portraits with onClick() to make them start a function when clicked
<a href="#" onClick="tristanaweak()"><img src="portraits/Aatrox_Square_0.png" width="25px" height="25px" alt=random></img>
<a href="#" onClick="tristanaweak()"><img src="portraits/Ahri_Square_0.png" width="25px" height="25px" alt=random></img>
<a href="#" onClick="tristanaweak()"><img src="portraits/Akali_Square_0.png" width="25px" height="25px" alt=random></img>
<a href="#" onClick="tristanaweak()"><img src="portraits/Alistar_Square_0.png" width="25px" height="25px" alt=random></img>
<a href="#" onClick="tristanaweak()"><img src="portraits/Amumu_Square_0.png" width="25px" height="25px" alt=random></img>
I've already manually put in the picture filenames (which was very tedious), but I still have to rename the onclick() values (tristanaweak) with the champion name (aatroxweak, ahriweak, etc.). I was thinking of doing this with a loop that edits text, but I don't know how I would go about doing this.
I'm fairly new to using Javascript, is there an easy way to rename all the onClick="tristanaweak()"'s in the html code to the first part of the png filenames in the same lines?

You can do this using PHP. First, create a list of all the champions:
$champs = "aatrox,arhi,akali,alistar,amumu,...";
Then do an explode to separate each champion and store it as an element in an array:
$pieces = explode(",", $champs);
echo $pieces[0]; //this will return aatrox
echo $pieces[1]; //this will return ahri
Now you can use a for loop to echo the desired results:
for($i=0;$i<count($pieces);$i++) {
echo '<!--other stuff here-->';
}
In the end, the result will be something like this:
<!--other stuff here-->
<!--other stuff here-->
etc, etc. I hope this is what you are looking for.

You should chose a different approach in my opinion. In javascript, you can also generate HTML dynamically using javascript function document.createElement(string tagName).
So, one of two possible soulitions would be creating a new images with new event for every champion:
HTML:
<div id="hero_images">
</div>
JS:
var champions = [
{
name: "Veigar",
callback: function() {/**Whatever you wanna do in onclick**/}
},
{
name: "Vladimir",
callback: function() {/**Whatever you wanna do in onclick**/}
},
{
name: "Morgana",
callback: function() {/**Whatever you wanna do in onclick**/}
}
];
//Now lets make an image for every champion:
var container = document.getElementById("hero_images"); //We'll put images in div I've defined in HTML above
for(var i=0; i<champions.length; i++) { //Loop through "champions" which is an array
var a = document.createElement("a");
a.href="#";
a.onclick = champions[i].callback; //Assign function from champion list to this <a>
//Also create the image
var img = document.createElement("img");
img.src = "portraits/"+champions[i].name+"_Square_0.png"; //I suppose image always have champion name in beginning
img.alt = champions[i].name; //Alternative text for no-image users
//Append image to link:
a.appendChild(img);
//Append <a> to <div>
contained.appendChild(a);
}
But in fact, you should use a global function for champions and you should have champion stats defined in the champions I've used. Under such circumstances:
var champions = [
{
name: "Veigar",
stats: {
inteligence: 666,
strength: 1,
/*..whatever you use...**/
}
}
];
for(/**imagine the prewious code here**/) {
...
a.onclick=(function(i) {
ShowHeroStatsOrWhatever(champions[i]);
})(i);
...
}
function ShowHeroStatsOrWhatever(champion) {
alert("Champions intelligence is "+champion.stats.inteligence);
}

Have you played around with jQuery .replaceWith();?
Description: Replace each element in the set of matched elements with
the provided new content and return the set of elements that was
removed.
Or the straight up javascript way (which I use with in conjunction with jQuery over the above 90% of the time) with .replace();
The replace() method searches a string for a specified value, or a
regular expression, and returns a new string where the specified
values are replaced.

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>

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).

trouble with search in angular

I'm new to angular and experiencing some difficulty implementing a 'live search' type of feature. I have my JSON set as a variable in a javascript file and I am able to display that in the html with no problem. I then have a 'list' radio box which changes the size of the display. This is functional as well. I run into trouble, however, when accessing the reverse filter option which is denoted with another radio button. The intended result is to filter the book titles in reverse by their name, ye nothing happens. Here is my JSON if you want to see the structure. And below is the code where I try to perform the filter reverse action:
<div class="container result">
<div ng-class="list ? 'col-md-6' : 'col-md-4'" class="books" ng-repeat="books in books | filter:search | orderBy:'books.doc.name':reverse"> <a href="https://address/{{books.doc.name}}" target="_blank">
<img ng-class="list ? 'col-md-2' : 'col-md-12'" ng-src="{{books.doc.thumbnail_590_url}}" alt="Click to read {{books.doc.name}}" title="Click to read {{books.doc.name}}" class="img-thumbnail" /></a>
<h4 ng-class="list ? 'col-md-10' : 'col-md-12'">{{books.doc.name}}</h4>
</div>
and heres the js:
angular.module("myApp",["ngSanitize"])
.filter('replace', function () {
var pat = / /gi;
return function (text) {
var clean = text.replace(pat, "-");
var temp = clean.split("---");
if (temp.length>1) {
clean = temp[0];
}
return clean;
};
})
.controller("Example", function($scope, $interval) {
$scope.search = "orig";
$scope.books = books;
$scope.reverse = false;
$scope.list = false;
});
I figured this out. Angular filter will not work on a json object, rather the data must be in the form of a json array. I removed the highest level enclosing curly brackets and replaced them with square brackets in addition to removing the numbers and colons like "1272:" that can be seen in the json file I posted. Taking these steps converted my data to a json array and allowed me to use the live search functionality.

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