Changing content in multiple classes via JS - javascript

I want to change the HTML-value of the highlighted span below (class=percent-value):
<div id="verfuegbarstd" class="et_pb_number_counter_4" data-number-value="0" data-number-separator="">
<div class="percent">
<p>**<span class="percent-value">0</span>**<span class="percent-sign"></span></p>
</div>
<h3 class="title">Verfügbare Stunden</h3>
<canvas height="0" width="0"></canvas>
</div>
I tried the following:
var verfuegbareStd = document.getElementsByClassName('et_pb_number_counter_4').getElementsByClassName('percent').getElementsByClassName('percent-value');
var budget = document.getElementsByClassName('et_pb_number_counter_2').getElementsByClassName('percent').getElementsByClassName('percent-value');
var lohnProStd = document.getElementsByClassName('et_pb_number_counter_3').getElementsByClassName('percent').getElementsByClassName('percent-value');
var gebrauchteStd = document.getElementsByClassName('et_pb_number_counter_5').getElementsByClassName('percent').getElementsByClassName('percent-value');
function calcVerfuegbareStd() {
var calc = budget.innerHTML / lohnProStd.innerHTML;
verfuegbareStd.innerHTML = calc;
}
calcVerfuegbareStd();
Does that make any sense?

document.getElementsByClassName returns a collection of all elements in the document with the specified class name, as a NodeList object. So thats why i check the length.
You can use also document.querySelector which gets the first element in the document with the class "xxxx" is returned.
I put both!
You can do it with jquery also but i thought you want pure js.
var elements = document.getElementsByClassName('percent-value'); // List of elements
var spanQuery = document.querySelector('.percent-value'); // The first element in the document with the class "myclass" is returned:
spanQuery.innerHTML = 'Hello!!!';
if (elements.length > 0) {
var span = elements[0];
span.innerHTML = 'Hello!!!';
}
<div id="verfuegbarstd" class="et_pb_number_counter_4" data-number-value="0" data-number-separator="">
<div class="percent">
<p>**<span class="percent-value">0</span>**<span class="percent-sign"></span></p>
</div>
<h3 class="title">Verfügbare Stunden</h3>
<canvas height="0" width="0"></canvas></div>

Try this?:
document.getElementsByClassName("percent-value").innerHTML = "the content you want";

It is simpler to use querySelector(). This will return the first element.
var verfuegbareStd = document.querySelector('.et_pb_number_counter_4 .percent .percent-value');
console.log(verfuegbareStd.innerHTML)
<div id="verfuegbarstd" class="et_pb_number_counter_4" data-number-value="0" data-number-separator="">
<div class="percent">
<p>**<span class="percent-value">0</span>**<span class="percent-sign"></span></p>
</div>
<h3 class="title">Verfügbare Stunden</h3>
<canvas height="0" width="0"></canvas>
</div>

Related

Compare order of two HTML elements

I have a function which accepts two parameters, each of type HTML element. It is supposed to return which element appears first in the document order. Is there any simple way to determine this?
Template -
<body>
<div id="div1">
<div id="div2">
</div>
</div>
<div id="div3">
<div id="div4">
</div>
</div>
</body>
JS -
const elem1 = document.getElementById('div2');
const elem2 = document.getElementById('div4');
const firstAppearingElement = checkOrder(elem1, elem2); // it should return elem1
function checkOrder(element1, element2) {
// check which one appears first in dom tree
}
You can try with Node.compareDocumentPosition()
The Node.compareDocumentPosition() method compares the position of the
given node against another node in any document.
The syntax is object.compareDocumentPosition (nodeToCompare);
let first = document.getElementById('a');
let second=document.getElementById('b');
// Because the result returned by compareDocumentPosition() is a bitmask, the bitwise AND operator has to be used for meaningful results.See link above for more
if (first.compareDocumentPosition(second) & Node.DOCUMENT_POSITION_FOLLOWING) {
console.log('element with id a is before element with id b'); //
} else {
console.log('element with id a is after element with id b');
}
<div id="a"></div>
<div id="b"></div>

Child appending / DOM ordering JavaScript

<body>
<div class = "order-1-a">
<div class = "order 2-a">
<div class = "order 3-a"></div>
</div>
<div class = "order 2-b"></div>
<div class = "order 2-c"></div>
<div class = "order 2-d"></div>
</div>
<div class = "order-1-b"></div>
</body>
If I want a div to wrap only class "order-2-a" + being the first child of "class-1-a", how should I script the div with JavaScript?
Probably your best bet is to:
Create a new Element with .createElement().
Append 2-a to the new Element with .appendChild().
Insert the new element before 2b with .insertBefore().
var one_a = document.getElementsByClassName("order-1-a")[0];
var two_a = document.getElementsByClassName("order-2-a")[0];
var two_b = document.getElementsByClassName("order-2-b")[0];
var new_node = document.createElement("div");
new_node.appendChild(two_a);
one_a.insertBefore(new_node, two_b);
console.log(one_a.innerHTML);
<body>
<div class="order-1-a">
<div class="order-2-a">
<div class="order-3-a"></div>
</div>
<div class="order-2-b"></div>
<div class="order-2-c"></div>
<div class="order-2-d"></div>
</div>
<div class="order-1-b"></div>
</body>
This provides the structure you're looking for (albeit not displayed well with console.log()).
Also, please be aware that class names cannot start with numbers, and may yield unexpected results. I've updated most of your classes to start with order in my example, as is with your order-1-a class.
Hope this helps!
You can create a general wrapping function based on a selector. It should get the subject node, then its parent and either it's next sibling or null if there isn't one.
Then create an element of the required type, append the subject node and insert it before the next sibling or as the last node if there wasn't one.
PS.
I've modified the class names to be valid, they can't start with a digit.
// Wrap element with selector in element with tagName
function wrapEl(selector, tagName) {
var node = document.querySelector(selector);
// If there is no subject node, return
if (!node) return;
// Get parent and sibling (or null if there isn't one)
var parent = node.parentNode;
var sibling = node.nextSibling;
// Append stuff
var wrapper = document.createElement('tagName');
wrapper.textContent = 'inserted wrapper'; // Just to show it's there
wrapper.appendChild(node);
parent.insertBefore(wrapper, sibling);
}
window.onload = function() {
wrapEl('.order-2-a', 'div');
}
<body>
<div class = "order-1-a">
<div class = "order-2-a">
<div class = "order-3-a"></div>
</div>
<div class = "order-2-b"></div>
<div class = "order 2-c"></div>
<div class = "order 2-d"></div>
</div>
<div class = "order-1-b"></div>
</body>

JS Remove all elements except a specific ID and its children

Responses to this:
How to remove elements except any specific id
are close to what I want but not quite.
In my case I am asking how I can remove all elements under parent id except id_n and its children: test1 and test2. The elements need to be removed, not just hidden.
<div id = "parent_id">
<div id = "id_1">
<div id = "id_11"> test</div>
<div id = "id_12">test </div>
</div>
<div id = "id_2"> test</div>
<div id = "id_n">id_n<br>
<div id='test1'>test1<br><div>
<div id='test2'>test2<br><div>
</div>
</div>
The result should be:
<div id = "parent_id">
<div id = "id_n">id_n<br>
<div id='test1'>test1<br><div>
<div id='test2'>test2<br><div>
</div>
</div>
Thanks for looking at this. Your suggestions are appreciated.
Using jQuery's siblings you remove all of it's children:
$('#id_n').siblings().remove();
Okay after thinking about this, there is another approach using Array manipulation:
var parentElement = document.getElementById('#parent_id');
parentElement.innerHtml = [].splice.call(parentElement.children).filter(item, function() {
return item.id === childId;
}).reduce((collatedHtml, item, function() {
return collatedHtml + item.innerHtml;
});
This grabs all the direct children of the parentElement and returns a new array (using Array.filter) before using Array.Reduce to collate the innerHtml of all the children.
Note: the reason i'm not using the ... prefix to convert to an Array is because it is not supported in IE 11 and below

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 iterate through all div and get specific property?

what I'm trying to do is iterate over a collection of div, contained in a parent container. My structure is the following:
<div id='main'>
<div data-id='2'>
</div>
<div data-id='3'>
</div>
</div>
My goal is take the field data-id of each div and create an array collection. Previously I used the select where do I get each value of available option, like this:
var available_services = $('#selected-service').find('option', this).map(function ()
{
return this.value;
}).get();
But now I'm using a div collection instead of the select. How I can iterate through all available div?
This should return all data-id values in a list:
var available_services = $('#main').find('div').map(function (item)
{
return item.attr('data-id');
});
I didn't test this, but I think should do the job. (maybe you need to tweak a little bit)
I believe this will do it:
var available_services = [];
$('#main div').each(function(){
available_services.push($(this).data( "id" ));
})
This is the easy way to go:
$(document).ready(function() {
var myCollection = [];
$('#main div').each(function(){
var dataDiv = $(this).attr('data-id');
myCollection.push(dataDiv)
})
});
Try this:
(function(){
var main = $("#main");
var divs = $(main).find("div");
var arrId = divs.map(function(index, div){
return $(div).attr("data-id");
});
console.log(arrId);
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='main'>
<div data-id='2'>
</div>
<div data-id='3'>
</div>
</div>

Categories