modify the data-donut attribute of the divs from javascript - javascript

My javascript
var currentMonth= new Date().getMonth();
if (demo.length >= currentMonth){
var d3data = demo[currentMonth];
// output will be ["23", "19"]
now i need to update output values to #donut and #donut1 (data-donut="")
values are coming from json it may change according to month
for reference i have added FIDDLE
http://jsfiddle.net/Qh9X5/3166/
<div class="zipper">
<div class="current">
<div class="title_text">current</div>
<div id="donut" data-donut="42"></div>///here in the data-donut value
</div>
<div class="target">
<div class="title_text">Target</div>
<div id="donut1" data-donut="62"></div>
</div>
</div>
Any help is Appreciated

You can use this to assign the values from the array (assuming the array is the result after parsing it from json)
var d3data = demo[currentMonth];
// assuming that this results in d3data = ["23", "19"];
$(document).ready(function() {
$("div[data-donut]").each(function(i) {
$(this).attr('data-donut', d3data[i]);
});
});
The first value of the array will be assigned to the first div and the second value to the second one.
See JSFiddle

Looks like you want to modify the data-donut attribute of the divs. Hope this will help
document.getElementsById("donut").setAttribute("data-donut","<your value>");
document.getElementsById("donut1").setAttribute("data-donut","<your value>");

This will work
obj = ["23", "19"];
var keys = Object.keys(obj);
for (var i = 0,j=1; i < keys.length; i++,j++) {
var val = obj[keys[i]];
document.getElementById("donut"+j).setAttribute("data-donut", val);
}
<div class="zipper">
<div class="current">
<div class="title_text">current</div>
<div id="donut1" data-donut="42"></div>///here in the data-donut value
</div>
<div class="target">
<div class="title_text">Target</div>
<div id="donut2" data-donut="62"></div>
</div>
</div>

This is not json format ["23", "19"]
e.g this is an array
var d3data = ["23", "19"];
$('#donut').data('donut', d3data[0]);
$('#donut1').data('donut',d3data[1]);

Related

jQuery iterate through elements within another element

I have HTML like this:
<div class="foo">
<div class="bar1">A</div>
<div class="bar2">B</div>
<div class="bar3">C</div>
</div>
<div class="foo">
<div class="bar1">D</div>
<div class="bar2">E</div>
<div class="bar3">F</div>
</div>
<div class="foo">
...etc.
I am trying to iterate through the "foo" divs to create objects like {bar1: A, bar2: B, bar3: C} with code sort of like this:
var arrayOfObjects= [];
var rows = $(".foo");
for (var i=0; i<rows.length; i++) {
var row = rows[i];
arrayOfObjects.push(
{
bar1: row.find(".bar1").text(),
bar2: row.find(".bar2").text(),
bar3: row.find(".bar3").text()
}
);
}
I understand that this doesn't work because the original var rows = $(".foo"); creates an array of DOM elements, which don't have find() as a function. I also know that within the loop, I could start using elementByClass and innerHtml, but I feel like my brain starts crying whenever I start mixing jQuery-style and DOM-style selectors in the same code.
Is there a way to fix my code above so that I'm using jQuery selectors within the loop?
You can wrap your elements as jQuery objectslike this:
arrayOfObjects.push(
{
bar1: $(row).find(".bar1").text(),
bar2: $(row).find(".bar2").text(),
bar3: $(row).find(".bar3").text()
}
);
This makes you row a JQuery object, which has the 'find' method.
You can easily iterate through .row divs by using each(),
var arrayOfObjects= [];
$(".foo").each(function(){
var items = {"bar1" : $(this).find('.bar1').text(),"bar2" : $(this).find('.bar2').text(), "bar3" : $(this).find('.bar3').text()};
arrayOfObjects.push(items); //If you want to push all into an object and then into an array
//or to use it on its own
$(this).find('.bar1').text();
$(this).find('.bar2').text();
$(this).find('.bar3').text();
});
Hope this helps.
//find all the foo, and map them into new elements
var result = $('.foo').map(function(index, element){
//we want to map all the children of the element into a single object
return $(element).children().get().reduce(function(aggregate, childElement){
//get the class off of the child and it's value, put them in the object
aggregate[childElement.className] = childElement.innerText;
return aggregate;
}, {}); //second argument to the reduce() is the starting element
}).get(); //use get() to break the array out of the jQuery object
console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">
<div class="bar1">A</div>
<div class="bar2">B</div>
<div class="bar3">C</div>
</div>
<div class="foo">
<div class="bar1">D</div>
<div class="bar2">E</div>
<div class="bar3">F</div>
</div>
$(document).ready(() => {
var arrayOfObjects = $('.foo').map(function() {
return $(this).find('>*').map(function(obj) {
return {
class: $(this).attr('class'),
text: $(this).text()
};
}).get().reduce( (obj, arr) => {
obj[arr.class] = arr.text;
return obj;
}, {});
}).get();
console.log(arrayOfObjects);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">
<div class="bar1">A</div>
<div class="bar2">B</div>
<div class="bar3">C</div>
</div>
<div class="foo">
<div class="bar1">D</div>
<div class="bar2">E</div>
<div class="bar3">F</div>
</div>
hope this helps you :)
Something along these lines with .each would probably work
const $rows = $('.foo');
let arrayOfObjects = [];
$rows.each(function(i) {
const $row = $(this);
let obj = {};
$row.children().each(function(ch) {
obj = { ...obj, [this.className]: $(this).text() };
});
arrayOfObjects = [ ...arrayOfObjects, obj ];
});
console.log(arrayOfObjects);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">
<div class="bar1">A</div>
<div class="bar2">B</div>
<div class="bar3">C</div>
</div>
<div class="foo">
<div class="bar1">D</div>
<div class="bar2">E</div>
<div class="bar3">F</div>
</div>

How do I convert a HTMLCollection into an array, without emptying it?

I am trying to convert an HTMLCollection of 4 divs into an array, but every method I try seems to result in the array being emptied.
<div class="container">
<div class="shape" id="one"></div>
<div class="shape" id="two"></div>
<div class="shape" id="three"></div>
<div class="shape" id="four"></div>
</div>
Methods I've attempted - as per this previous question:
var shapesHC = document.getElementsByClassName('shape');
//gives HTMLCollection
var shapesArrCall = [].slice.call(shapesHC);
// returns empty array
var shapesArrHC = Array.from(shapesHC);
// returns empty array
var shapesArrHCSpread = [...shapesHC];
// returns empty array
I'd really appreciate if anyone can point out where I'm going wrong here.
Thanks.
Try using this:
setTimeout(() => {
this.convertToArray();
});
convertToArray() {
const shapesHC = document.getElementsByClassName('shape');
const shapesArrHCSpread = [...(shapesHC as any)];
console.log(shapesArrHCSpread);
}

Including the current node in the find scope

Consider the following snippet as an example:
<div class="bar foo">
</div>
<div class="bar">
<div class="foo"></div>
</div>
Given var $set=$('.bar'); I need to select both nodes with foo class. What is the proper way to achieve this. Considering addBack() requires a selector and here we need to use the $set jQuery object and $set.find('.foo') does not select the first node.
use this :
var $set = $(".bar").filters(function () {
var $this = $(this);
if($this.is(".foo") || $this.find(" > .foo").length !== 0){
return true;
} else{
return false;
}
});
Here's one way of going about it:
var set = $('.bar');
var foos = [];
for (var i = 0; i < set.length; i++) {
if ($(set[i]).hasClass('foo')) {
foos.push(set[i]);
}
}
if (set.find('.foo').length !== 0) {
foos.push(set.find('.foo')[0]);
}
console.log(foos);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bar foo"></div>
<div class="bar">
<div class="foo"></div>
</div>
The for loop checks all elements picked up with jQuery's $('.bar'), and checks if they also have the foo class. If so, it appends them to the array. The if checks if any of the elements picked up in set have any children that have the foo class, and also adds them.
This creates an array that contains both of the DIVs with the foo class, while excluding the one with just bar.
Hope this helps :)
test this :
var $newSet = $set.filter(".foo").add($set.has(".foo"));
You could use the addBack() function
var $set=$('.bar');
console.log($set.find(".foo").addBack(".foo"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bar foo">
</div>
<div class="bar">
<div class="foo"></div>
</div>

How to sort a list of nodes by a given array in an efficient way?

I have this HTML which is a list of elements:
<div class="container">
<div class="apple-0">first-apple</div>
<div class="apple-1">second-apple</div>
<div class="apple-2">third-apple</div>
<div class="apple-3">forth-apple</div>
<div class="apple-4">fifth-apple</div>
</div>
I've gotten an array, for example, which is [3,4,0,2,1] I need to sort the list in to this order.By this I mean that the third element <div class="apple-3">third-apple</div> should be the first. The second element should be the forth-apple.
How can I change it in an efficient way? This is the expected output:
<div class="container">
<div class="apple-3">forth-apple</div>
<div class="apple-4">fifth-apple</div>
<div class="apple-0">first-apple</div>
<div class="apple-2">third-apple</div>
<div class="apple-1">second-apple</div>
</div>
jQuery can be used.
You can do this by looping through the array and appending each div by it's matched index. Try this:
var $divs = $('.container > div').detach();
[3, 4, 0, 2, 1].forEach(function(value) {
$divs.eq(value).appendTo('.container');
});
Working example
Note that if you need to support older browsers (< IE9) then you would need to replace forEach() with a standard for loop.
You can try something like this:
$("#sort").on("click", function() {
var data = [3, 4, 0, 2, 1];
var result = "";
data.forEach(function(item) {
result += $(".container").find(".apple-" + item)[0].outerHTML;
});
$(".container").html(result);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class="container">
<div class="apple-0">first-apple</div>
<div class="apple-1">second-apple</div>
<div class="apple-2">third-apple</div>
<div class="apple-3">forth-apple</div>
<div class="apple-4">fifth-apple</div>
</div>
<button id="sort">Sort</button>
Simply iterate the indexes array and keep pushing the child at nth-index
var output = [];
var indexes = [3,4,0,2,1];
indexes.forEach(function(value, index){
output.push($(".container div").eq(indexes[index])[0].outerHTML);
});
console.log(output);
$(".container").html(output.join(""));
Demo
you can try:
UPDATE:
var arr = [3,4,0,2,1];
var nodes = [];
arr.forEach(funtion(value){
var node = $('.container .apple-'+value)[0];
nodes.push(node);
});
$('.container').html(nodes);
demo
Other answers with eq are good, but if you want to sort again with a different array, or the array is unsorted initially, then they would fail. Also you asked for an efficient method, using native loops instead of jquery's each gives performance benefits. So my answer to this is
$(document).ready(function () {
var inputEls = $('#awesomeContainer').find('>').get(),
$output = $('#awesomeOutput'),
order = [3,4,0,2,1],
output = [],
myValue,
newIndex,
i,
length = inputEls.length;
for (i = 0; i < length; i += 1) {
myValue = Number((inputEls[i].className || "").replace("apple-", ""));
if (myValue >= 0) {
myValue = order.indexOf(myValue);
myValue > -1 && (output[myValue] = inputEls[i].outerHTML);
}
}
$output.append(output.join(''));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<b>Input: </b>
<div id="awesomeContainer" class="container">
<div class="apple-0">first-apple</div>
<div class="apple-1">second-apple</div>
<div class="apple-2">third-apple</div>
<div class="apple-3">forth-apple</div>
<div class="apple-4">fifth-apple</div>
</div>
<br/>
<b>Sorted: </b>
<div id="awesomeOutput" class="container">
</div>

Adding get() to line causes "is not a function" error

This is the start of an inventory system I am working on. Basically it takes an array with items and quantities in a compressed form and outputs the items into an item div.
Running the below produces no error:
$('.item_amount').html(collection[itemName].amo);
Adding the get() method after the selector like so:
$('.item_amount').get(i).html(collection[itemName].amo);
produces "$(".item_amount").get(i).html is not a function".
This is what the line is altering:
<div class="item">
<img src="" class="item_image"/>
<div class="item_amount"></div>
</div>
The line that is causing the error is located in a for loop that loops through all the keys in an array. Then outputs the item quantity from the array in the item_amount div based on the index stored in the variable "i". The for loop also creates an object for each item in the array and puts in the a collection object.
Full code below:
<body>
<div class="item">
<img src="" class="item_image"/>
<div class="item_amount"></div>
</div>
<div class="item">
<img src="" class="item_image"/>
<div class="item_amount"></div>
</div>
<div class="item">
<img src="" class="item_image"/>
<div class="item_amount"></div>
</div>
<script type="text/javascript">
var collection = new Object();
function makeItem(itemName, id, amo) {
collection[itemName] = new item(id, amo);
}
function item(id, amo) {
this.id = id;
this.amo = amo;
}
var inventoryCom = "368.9,366.15,384.32"; //compressed inventory
var inventoryArr = inventoryCom.split(',');
for(var i=0; i < inventoryArr.length; i++) {
var itemName = 'item' + (i + 1); //unique name for each item
var itemArr = inventoryArr[i].split('.');
makeItem(itemName, itemArr[0], itemArr[1]);
$('.item_amount').get(i).html(collection[itemName].amo);
}
</script>
</body>
.get(i) returns DOM element, which doesn't have .html() method - that's what js engine wants to say to you.
You need to use .eq(i) instead. Like
$('.item_amount').eq(i).html(collection[itemName].amo);
or
$('.item_amount:eq(' + i + ')').html(collection[itemName].amo);
This line may be a problem
var itemName = 'item' + (i + 1); //
This may increment the array count out of the upper bound. check the itemName value.
Also try to add an alert for this
collection[itemName].amo

Categories