Collect all data attributes? - javascript

My webpage is dynamically generated with, data-runway-link, data-video-link, data-backstage-link, there will be more in the future.....
The patterns are always like this data-xxx-link, what I want to do are, extract the "xxx" text in each of them store them inside an array so that I can refer each of the info using javascript
<li> <a data-season="Designer Profiles" data--link="123" data-video-link="1233"> </a></li>
<li> <a data-season="Spring/Summer 2014" data-Runway-link="abc" data-video-link="abc"> 3.1 Phillip Lim</a></li>
<li> <a data-season="Spring/Summer 2014" data-Runway-link="abc" data-video-link="abc"> Acne Studios</a></li>
<li> <a data-season="Spring/Summer 2014" data-Runway-link="abc" data-video-link="abc"> Aigner</a></li>
<li> <a data-season="Spring/Summer 2014" data-Backstage-link="abc" data-video-link="abc"> Alexander McQueen</a></li>
<li> <a data-season="Spring/Summer 2014" data-Runway-link="abc" data-video-link="abc"> Alexander Wang</a></li>

$('a').each(function(){
console.log($(this).data())
})
result will look like:
{season: 'Designer Profiles', 'runwayLink':'abc' ...}
fiddle:
http://jsfiddle.net/acrashik/NnHqQ/5/
STEP2: removing word link from keys
easiest way would be:
function removeLiknfromKey(data) {
var jsonstr = JSON.stringify(data);
var new_jsonstr = jsonstr.replace(/Link":/g, '":');
var new_obj = JSON.parse(new_jsonstr);
return new_obj;
}
you will have an object with XXX names only.
fiddle:
http://jsfiddle.net/acrashik/NnHqQ/6/
now you can use it nicely, using only name:
data.runway, data.video, data.season ... etc

When you access an element that has any data-* attributes with jQuery, you can access an object containing all of the data-* elements using the data() function.
For example, if you had an element like this:
<a id="elem" data-season="Designer Profiles" data-link="123" data-video-link="1233"> </a>
You could do something like this:
var element_data = $( "#elem" ).data();
Now, each of the keys within element_data will have each data attribute.
element_data[ "season" ]; // "Designer Profiles";
element_data[ "link" ]; // "123";
element_data[ "video-link" ]; // "1233";
Here is the relevant documentation for the data() function: http://api.jquery.com/data/
As you can see, the same function acts as a getter and a setter function. So to retrieve a specific key of data you would do something like this:
var video_link = $( "#elem" ).data( "video-link" ); // "1233"
You could also set the video-link value:
var new_video_link_value = "some other value";
var video_link = $( "#elem" ).data( "video-link", new_video_link_value );
To put all of this to use and to answer your question, what you would do is something like this:
var elems = $("li > a"); // extract all of the relevant anchor tags
var elem_data = [];
$.each( elems, function( index, elem ){
elem_data.push( $(elem).data() );
});
You will now have all of the data attributes for each anchor tag within the elem_data array. What might be a better idea is to give each anchor tag some sort of identifier so that you can map the data back to the relevant element that it came from.

Try this:
$('li a').each(function(){
console.log($(this).data())
});

Related

Get `li` elements and push it into object

I have a simple question!
I have this html and js:
<ul>
<li id="x">foo</li>
<li id="y">bar</li>
</ul>
var data = {
'language': 'fa',
'phrases': {},
};
I want to append all li in the phrases of data for have this output:
{"language":"fa","phrases":{"x":"foo","y":"bar"}}
I try this:
data.phrases.$(this).attr('id') = $(this).html();
And try push this:
data.phrases.push( {$(this).attr('id') : $(this).html()} );
And try extend this:
data.phrases.extend( {$(this).attr('id') : $(this).html()} );
But does not work!
Completed code:
<ul>
<li id="x">foo</li>
<li id="y">bar</li>
</ul>
<div id="result"></div>
var data = {
'language': 'fa',
'phrases': {},
};
//I want to append all `li` in the `phrases` of `data` for have this output:
//{"language":"fa","phrases":{"x":"foo","y":"bar"}}
$("li").each(function() {
//data.phrases.$(this).attr('id') = $(this).html();
//data.phrases.push( {$(this).attr('id') : $(this).html()} );
//data.phrases.extend( {$(this).attr('id') : $(this).html()} );
});
$("#result").html(JSON.stringify( data ));
See here online code: https://jsfiddle.net/NabiKAZ/fw63jd5k/
You cannot .push() into Object.
Use assignment to properties instead:
var data = {
'language': 'fa',
'phrases': {},
};
$("li").text(function(i, txt) {
data.phrases[this.id] = txt;
});
$("#result").html(JSON.stringify( data ));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="x">foo</li>
<li id="y">bar</li>
</ul>
<div id="result"></div>
data.phrases is your object literal
[this.id] is your new object property, where this.id is the current li's ID
= txt; is where you assign to that property the value of the current li text
As you can figure out from above, if you need the entire HTML use .html() instead like:
$("li").html(function(i, html) {
data.phrases[this.id] = html;
});
You're quite close! The issue is that the dot operator in JavaScript cannot be used to evaluate a key then access it. You're looking for the [ ] operator, which can be used to evaluate whatever is in the brackets, then use the value as the key. So try this:
data.phrases[$(this).attr('id')] = $(this).html();
you have the right idea, but you aren't quite using your functions correctly. push is an array method, and extend just isn't a native method. so what we want to do is set the id to the key, and the value to the html
https://jsfiddle.net/fw63jd5k/2/
$("li").each(function(i, el) {
data.phrases[el.id] = $(el).html()
}

How to get value of elements without using IDs in JavaScript

Lets say I had the following code:
<div class="post">
<h2 itemprop="name">
The Post Title
</h2>
<div class="details">
<span>
<em class="date">Jul 17, 2014 </em>
</span>
<span>
Category:
Staff Profile
</span>
</div>
How would I possibly get the values of "The Post Title" and "Staff Profile" using JavaScript without changing the HTML on the page at all? i.e. I couldn't use getElementbyID for example. I could use jQuery if I had to but would rather not if possible.
You can get these values using getElementsByTagName which returns an array
document.getElementsByTagName("a")[0].innerHTML // returns The Post Title
document.getElementsByTagName("a")[1].innerHTML // returns Staff Profile
If these links are the first ones you can use indexes 0 and 1, otherwise you should look for the right index
Update
Another way that may be simple is to select these links inside the div with the class post
var links = document.getElementsByClassName("post")[index].getElementsByTagName("a");
links[0].innerHTML; // returns The Post Title
links[1].innerHTML; // returns Staff Profile
This solution would be the best one if the index of the div with the class post doesn't change
For a jQuery based expression you can use this:
$('a').map(function() {
return [this.href, this.textContent];
}).get();
which should return:
[ [ 'http://www.example.com', 'The Post Title' ],
[ 'http://sitename/category/staff-profile/', 'Staff Profile' ] ]
Should you specifically want the original relative URLs instead of the normalised full URLs, use this.getAttribute(href) in place of this.href
For a pure (ES5) equivalent:
[].map.call(document.getElementsByTagName('a'), function (el) {
return [el.href, el.textContent];
});
Older browsers that don't support the W3C standard .textContent property may require the .innerText property instead, e.g.:
return [el.href, el.textContent || el.innerText];
You can do:
var posts = document.querySelector('.post');
for (var i = 0; i < posts.length; i++) {
var links = document.querySelectorAll('a');
var title = links[0].innerText || links[0].textContent;
var profile = links[1].innerText || links[1].textContent;
}
If you are using a more modern browser, you can use document.querySelectorAll() which takes in CSS style selector syntax.
var aList = document.querySelectorAll('.post a');
for (var i = 0; i < aList.length; ++i) {
alert(aList[i].innerHTML);
}
JSFiddle
I used '.post a' rather than just 'a' because I assume your page may have other 'a' tags in it that you don't necessarily want.

How to change href value using javascript or jquery?

<div class="container-fluid">
<img class="pull-left" onclick="MarkPopup()" style="width:50px;height:50px" src="/assets/mark.jpg">
<ul class="nav pull-right">
<li>
<li>
Contact Club
</li>
<li>
<li class="dropdown">
</ul>
</div>
I want to change the href value "/ContactClub" to "somethingelse". How is this done please?
Two ways ;)
jQuery style:
// Select a with href attribute = /ContactClub
$('a[href="/ContactClub"]').prop('href', 'newhref...');
Pure-js solution (untested)
var elements = document.getElementsByTagName('a');
for (var i = 0; i < elements.length; i++) {
if (element[i].href === '/ContactClub') {
if (element.setAttribute !== 'function') {
element[i].href = 'newhref';
} else {
element[i].setAttribute('href', 'newhref');
}
}
}
I would add an id to the a tag:
<a id="contact_link" href="/ContactClub">Contact Club</a>
And then do either,
$('#contact_link').attr('href', 'new url');
or,
document.getElementById('contact_link').href = 'new url';
Note: You can also use the jQuery prop method in the same fashion as attr above. This is somewhat a matter of preference. As href is principally thought of as an attribute (with a corresponding, but not dynamic or disconnected js property), I would suggest using attr. Other attributes like value will depend on what you're trying to retrieve. Do a bit of research on the differences.
You can use either prop() or attr():
$('a[href="/ContactClub"]').attr('href', 'New Href here');
or:
$('a[href="/ContactClub"]').prop('href', 'New Href here');
Fiddle Demo
try
$("li a").attr("href","new value");

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

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.

How to dynamically build/add list elements (ul, ol, li) using jQuery DOM manipulations?

I am programming an AJAX web page (using IE 8) and need to dynamically build a list in jQuery from the data returned. Later, I will be converting list to jQuery accordian.
I am also trying to learn the proper way to use these jQuery functions and chaining. I am just a jQuery NOOB, but understand JavaScript. I found a good article on jQuery dom functions: http://www.packtpub.com/article/jquery-1.4-dom-insertion-methods
I want to add as much as possible using the jQuery dom functions, and jQuery chaining, without resorting to HTML source code using text. I want to mostly use .wrap(), .appendto(), .attr(), .text(), and .parent().
I don't think that the ".attr("class", "CC_CLASS"). is the best way to add a class.
Given the HTML code:
<div id="outputdiv"></div>
Use jQuery dom functions to change it to be the following:
<div id="outputdiv">
<ul id="JJ_ID">
<li> AAA_text </li>
<li id="BB_ID"> BBB_text </li>
<li class="CC_CLASS"> CCC_text </li>
<li id="DD_ID">DDD_text<br/>
<ol id="EE_ID">
<li> FFF_text </li>
<li id="GG_ID"> GGG_text </li>
<li class="HH_CLASS"> HHH_text </li>
</ol>
</li>
</ul>
</div>
Some code I figured out (ignoring the spaces in text).
var aObj = $('<li></li>').text("AAA_text")
var bObj = $('<li></li>').attr("id", "BB_ID").text("BBB_text");
var cObj = $('<li></li>').attr("class", "CC_CLASS").text("CCC_text");
var dObj = $('<li></li>').attr("id", "DD_ID").text("DDD_text");
var fObj = $('<li></li>').text("FFF_text");
var gObj = $('<li></li>').attr("id", "GG_ID").text("GGG_text");
var hObj = $('<li></li>').attr("class", "HH_CLASS").text("HHH_text");
Somehow add (fObj + gObj + hObj) into eObj ?
var eObj = `*something*`.attr("id", "EE_ID").wrap(`*something*`);
Somehow add (aObj + bObj + cObj+ dObj + eObj) into jObj ?
var jObj = `*something*`.attr("id", "JJ_ID").wrap(`*something*`);
jObj.appendTo("#xmlOutputId")
The .append method returns the same container object you called it on -- make use of this to chain methods pleasantly:
var inner_list = $('<ol/>', {id: "EE_ID" })
.append( $('<li/>', {text: "FFF_text" })
.append( $('<li/>', {id: "GG_ID", text: "GGG_text" })
.append( $('<li/>', {"class": "HH_CLASS", text: "HHH_text" });
var outer_list = $('<ul/>', {id: "JJ_ID" })
.append( $('<li/>', {text: "AAA_text" })
.append( $('<li/>', {id: "BB_ID", text: "BBB_text" })
.append( $('<li/>', {"class": "CC_CLASS", text: "CCC_text" })
.append(
$('<li/>', {id: "DD_ID", text: "DDD_text"})
.append(inner_list)
);
outer_list.appendTo('#xmlOutputId');
You could actually do the entire thing in a single statement with no vars, but in my opinion that would be getting too ugly.

Categories

Resources