Vanilla Javascript for loop to remove html elements from selected collection - javascript

var overrideField = document.querySelectorAll('.form_style_override_field');
overrideField.forEach(function (e) {
e.parentNode.parentNode.remove();
});
I am trying to learn vanilla javascript and trying to remove an element which is pulled by classname.
var overrideField = document.getElementsByClassName('form_style_override_field');
for (var i = 0; i < overrideField.length; i++)
{
var controlGroup = overrideField[i].parentNode.parentNode;
controlGroup.remove();
}
var overrideField = document.getElementsByClassName('form_style_override_field');
for (var i = 0; i < overrideField.length; i++)
{
var controlGroup = overrideField[i].parentNode.parentNode;
controlGroup.remove();
}
<div class="tab-pane active show" id="general">
<div class="control-group">
<div class="control-label">Label 1</div>
<div class="controls">
<span class="form_style_override_field"></span>
Control Group 1
</div>
</div>
<div class="control-group">
<div class="control-label">Label 2</div>
<div class="controls">
<span class="form_style_override_field"></span>
Control Group 2
</div>
</div>
</div>
The overrideField variable sees 2 elements and it will only remove the last one. Can anyone help me figure it out please.
Thanks!

getElementsByClassName returns a live collection, so when you remove an element in your for loop the collection (and length) changes so your loop never gets to the last element. Use querySelectorAll instead to return a static collection and then remove the elements.
For example:
var elems = document.querySelectorAll('.class-to-remove');
elems.forEach(function(elem) {
elem.remove();
});

Related

Get values from ID HTML and save in array

I'm doing a view where once I click I'm displaying
For Loop
I am having a view that captures a QR code and displays it on the screen, what I want to do next is take these values by iterating the elements with a for loop and save it in an array, in this case my ID is id="scanned-result" and I want to iterate each containing values and saving to an array.
I am doing this but for some reason it is not performing the operation correctly. I would like to know what I should correct?
function SubmitCodes() {
var QRCodeval= document.querySelectorAll('scanned-result');
var arr = [];
for (var i in QRCodeval) {
alert(QRCodeval[i]);
arr.push( QRCodeval[i]);
}
alert(arr.val);
}
VIEW
<div class="container">
<div class="row">
<div class="col-md-12" style="text-align: center;margin-bottom: 20px;">
<div id="reader" style="display: inline-block;"></div>
<div class="empty"></div>
<div id="scanned-result">
<div>[1] - https://www.investopedia.com/terms/q/quick-response-qr-code.asp</div>
<div>[2] - https://www.dropbox.com/s/705b6p4a2ydvayx/EN-Poster.pdf?dl=0</div></div>
</div>
</div>
</div>
There are several issues with your code. To select element by ID using querySelector you need to use # selector, also to select the divs inside you can use element > element selector.
var QRCodeval = document.querySelectorAll("#scanned-result>div");
querySelectorAll returns a nodeList. So you need to iterate through it to get value of individual elements. But you should not use for..in. You can use forEach instead.
function submitCodes() {
var QRCodeval = document.querySelectorAll("#scanned-result>div");
var arr = [];
QRCodeval.forEach((el) => arr.push(el.innerHTML));
console.log(arr)
}
submitCodes();
<div class="container">
<div class="row">
<div class="col-md-12" style="text-align: center;margin-bottom: 20px;">
<div id="reader" style="display: inline-block;"></div>
<div class="empty"></div>
<div id="scanned-result">
<div>[1] - https://www.investopedia.com/terms/q/quick-response-qr-code.asp</div>
<div>[2] - https://www.dropbox.com/s/705b6p4a2ydvayx/EN-Poster.pdf?dl=0</div>
</div>
</div>
</div>
</div>
To get the text inside of the elements you can use innerHTML.
Since there is no <scanned-result></scanned-result> element on your page, as charlietfl pointed out, you won't get any results.
Since your HTML markup is the following:
<div id="scanned-result">
<!-- … -->
</div>
You are looking for an ID.
And the valid ID query in a CSS selector is a #, because of that you should query like:
var QRCodeval = document.querySelectorAll('#scanned-result')
I've changed the iteration to fill the array with the lines inside the ID scanned-result. Would that help ?
function SubmitCodes() {
var QRCodeval = document.getElementById('scanned-result').children;
var arr = [];
for (var i = 0; i < QRCodeval.length; i++) {
arr.push(QRCodeval[i].innerText)
}
console.log(arr)
}
<div class="container">
<div class="row">
<div class="col-md-12" style="text-align: center;margin-bottom: 20px;">
<div id="reader" style="display: inline-block;"></div>
<div class="empty"></div>
<div id="scanned-result">
<div>[1] - https://www.investopedia.com/terms/q/quick-response-qr-code.asp</div>
<div>[2] - https://www.dropbox.com/s/705b6p4a2ydvayx/EN-Poster.pdf?dl=0</div>
</div>
</div>
</div>
</div>

Index of getElementsByClassName is undefined but not the whole object

I am trying to loop over elements with a specific class and attach an ID to them.
var items = document.getElementsByClassName("item");
for(var i = 0; i < items.length; i++)
{
items[i].id = "item_" + i;
}
console.log(items);
If I run that I get the error Cannot set property 'id' of undefined
However the console.log(items) returns me the correct collection of items:
HTMLCollection []
0: div.item
1: div.item
length: 2
__proto__: HTMLCollection
But as soon as I try to get the index console.log(testimonials[0]) it is undefined.
HTML:
<div class="slider">
<div class="item">
Item 1
</div>
</div>
<div class="slider">
<div class="item">
Item 2
</div>
</div>
The issue could be your script is running before the DOM is fully ready.
To solve the issue, you can place your code at the bottom of the body.
OR:
Try wrapping your code with DOMContentLoaded, this will ensure that your code will be executed once the DOM is fully ready.
<script>
document.addEventListener("DOMContentLoaded", function(event) {
var items = document.getElementsByClassName("item");
for(var i = 0; i < items.length; i++)
{
items[i].id = "item_" + i;
}
console.log(items);
});
</script>
<div class="slider">
<div class="item">
Item 1
</div>
</div>
<div class="slider">
<div class="item">
Item 2
</div>
</div>
With vanilla js always do DOM related operations after DOM is ready to use. And also before accessing/working with any DOM element check that it isn't nullable (not equal to null). With these practices you won't see any error with DOM elements because it is the safe way with manipulating with DOM elements. In regular loop always cache array.length. Avoid using anonymous function it is non-future proof and not debug-friendly way. Also write all js in separate js file.
HTML
<div class="slider">
<div class="item">
Item 1
</div>
</div>
<div class="slider">
<div class="item">
Item 2
</div>
</div>
JS
document.addEventListener("DOMContentLoaded", onDomReadyHandler);
function onDomReadyHandler(event) {
var items = document.getElementsByClassName('item');
var itemsLen = items.length;
for(var i = 0; i < itemsLen; i++) {
items[i].id = "item_" + i;
}
console.log(items);
}
Check this code:
<html>
<head>
<script>
window.onload = function(e){
var allItem = document.getElementsByClassName("item");
for(var i = 0; i < allItem.length; i++)
{
document.getElementsByClassName("item")[i].setAttribute("id", "item_" + i);
}
};
</script>
</head>
<body>
<div class="slider">
<div class="item" id="">
Item 1
</div>
</div>
<div class="slider">
<div class="item" id="">
Item 2
</div>
</div>
</body>
</html>
Hope it helps you.
Try using
items[i].setAttribute("id", "item_" + i);
Fore more details you can visit documentation of
https://www.w3schools.com/jsref/met_element_setattribute.asp
https://www.w3schools.com/jsref/met_element_getattribute.asp
Fiddle for it:
https://jsfiddle.net/abdulrauf618/n14v58zs

Add JS array values to multiple divs

I have an array
var arr = [3,0,1,0,0];
and multiple divs.
<div class="fb0"></div>
<div class="fb1"></div>
<div class="fb2"></div>
<div class="fb3"></div>
<div class="fb4"></div>
and more.
How to add values from an array alternately by numbers in an array to div numbers by classes.
<div class="fb0">3</div>
<div class="fb4">0</div>
<div class="fb2">1</div>
<div class="fb3">0</div>
<div class="fb1">0</div>
You can use jQuery's .each() to loop through all the div. Inside event handler function use the index to take the item from the array and set the text of the current element:
var arr = [3,0,1,0,0];
$('[class^=fb]').each(function(idx){
if(arr.length >= idx) // check if the array length is grater/equal to the current index.
$(this).text(arr[idx]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fb0"></div>
<div class="fb1"></div>
<div class="fb2"></div>
<div class="fb3"></div>
<div class="fb4"></div>
JavaScript solution with Document.querySelectorAll() and Array.prototype.forEach():
var arr = [3,0,1,0,0];
var elements = [].slice.call(document.querySelectorAll('[class^=fb]'));
elements.forEach(function(div, idx){
if(arr.length >= idx) // check if the array length is grater/equal to the current index.
div.textContent = arr[idx];
});
<div class="fb0"></div>
<div class="fb1"></div>
<div class="fb2"></div>
<div class="fb3"></div>
<div class="fb4"></div>
You can use querySelectorAll to select the div's and than using forEach you can add the values to each div accordingly.
function update(){
let arr = [3,0,1,0,0];
let divs = document.querySelectorAll('[class^=fb]')
divs.forEach((e,i)=>{
e.innerHTML = arr[i]
})
}
<div class="fb0"></div>
<div class="fb1"></div>
<div class="fb2"></div>
<div class="fb3"></div>
<div class="fb4"></div>
<button onClick=update()>Click me to see output</button>

Copy Class Values to Div

I have HTML File:
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="Function()">Whatever</button>
<div id="result"></div>
I'd like my function to take values from all four divs with class "um-field-value"
<div class="um-field-value">Value1</div>
And past them in Div "result"
Essentially, I want a script to simply copy values given in class um-field-value and paste it in a "result" div. I tried following:
function Function() {
var x = document.getElementsByClassName("um-field-value");
document.getElementsById('result').innerHTML = x;
}
But that doesn't work at all.
I am somewhat new to coding so I am not entirely sure if it is even possible. Googled for over an hour but couldn't find any solutions.
document.getElementsByClassName gets the HTML nodes themselves but then you have to extract the values from within the HTML nodes, combine them, and set that to your result div. Example snippet below:
function myFunction() {
var valueNodes = Array.prototype.slice.call(document.getElementsByClassName("um-field-value"));
var values = valueNodes.map(valueNode => valueNode.innerHTML);
var result = values.join(' ');
document.getElementById('result').innerHTML = result;
}
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="myFunction()">Whatever</button>
<div id="result"></div>
Use querySelectorAll to get all the dom with this class um-field-value and iterate over that to get the innerHTML
There is a typo in your code.It is getElementById instead of getElementsById. There is an extra s
function Function() {
var x = document.querySelectorAll(".um-field-value");
let result = '';
for (var y = 0; y < x.length; y++) {
result += x[y].innerHTML;
}
document.getElementById('result').innerHTML = result;
}
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="Function()">Whatever</button>
<div id="result"></div>
You are on the right track. document.getElementsByClassName will return a NodeList. You need to get the innerText for each of the elements in that list. Depending on the browser you can either use forEach or a regular for loop to iterate over the list.
function Function() {
var fieldsList = document.getElementsByClassName("um-field-value");
var fieldValues = [];
fieldsList.forEach(function(field) { fieldValues.push(field.innerText) });
document.getElementsById('result').innerHTML = fieldValues.join(", ");
}
This is a simple and readable solution that uses a loop to get the text inside each element and add it to a string. getElementsByClassName returns an array of all elements found, so a loop is needed to get the text inside each with textContent.
function Function() {
var result = '';
var fields = document.getElementsByClassName("um-field-value");
for (var i=0; i<fields.length; i++) {
result += fields[i].textContent + '\n';
}
document.getElementById('result').innerHTML = result;
}
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="Function()">Whatever</button>
<div id="result"></div>

How to wrap div around multiple of the same class elements

I'm trying to wrap multiple same class divs into a div and to skip divs not with the same class. .wrap doesn't combine them, and .wrapAll throws the non-classed divs underneath. I've been tinkering around with attempts to create an alternate solution but with no avail.
Original:
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div>Skip in wrap</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
continued...
Wanted Result:
<div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
</div>
<div>Skip in wrap</div>
<div>
<div class="entry">Content</div>
<div class="entry">Content</div>
<div class="entry">Content</div>
</div>
You can loop pretty quickly through your <div> elements using a for loop. In the below code, just change the initial selector here to grab all those siblings divs, e.g. #content > div.entry or wherever they are:
var divs = $("div.entry");
for(var i=0; i<divs.length;) {
i += divs.eq(i).nextUntil(':not(.entry)').andSelf().wrapAll('<div />').length;
}​
You can give it a try here. We're just looping through, the .entry <div> elements using .nextUntil() to get all the .entry elements until there is a non-.entry one using the :not() selector. Then we're taking those next elements, plus the one we started with (.andSelf()) and doing a .wrapAll() on that group. After they're wrapped, we're skipping ahead either that many elements in the loop.
I just whipped up a simple custom solution.
var i, wrap, wrap_number = 0;
$('div').each(function(){ //group entries into blocks "entry_wrap_#"
var div = $(this);
if (div.is('.entry')) {
wrap = 'entry_wrap_' + wrap_number;
div.addClass(wrap);
} else {
wrap_number++;
}
});
for (i = 0; i <= wrap_number; i++) { //wrap all blocks and remove class
wrap = 'entry_wrap_' + i;
$('.' + wrap).wrapAll('<div class="wrap"/>').removeClass(wrap);
}
You could alternatively append new divs to your markup, and then append the content you want wrapped into those.
If your markup is this:
<div class="wrap">
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-1"></div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-2"></div>
<div class="col-2"></div>
</div>
Use the following to append two new divs (column-one and column-two) and then append the appropriate content into those divs:
// Set vars for column content
var colOne = $('.col-1').nextUntil('.col-2').addBack();
var colTwo = $('.col-2').nextAll().addBack();
// Append new divs that will take the column content
$('.wrap').append('<div class="column-first group" /><div class="column-second ground" />');
// Append column content to new divs
$(colOne).appendTo('.column-first');
$(colTwo).appendTo('.column-second');
Demo here: http://codepen.io/zgreen/pen/FKvLH

Categories

Resources