JavaScript - Dynamic Array and Looping - javascript

Imagine you have a product page. On this page there are two select inputs with options in them.
There is one for Size and Colour. This can change depending on the product, e.g. a curtain might have a size, length and colour (three select menus).
The array is created dynamically (based on each select menu and its options):
var dynamicArr = [],
i,
j,
opt,
$('.select');
for (i = 0; i < select.length; i += 1) {
opt = select.eq(i).find('option');
if (dynamicArr[i] === undefined) {
dynamicArr[i] = [];
}
for (j = 0; j < opt.length; j += 1) {
dynamicArr[i].push(opt.eq(j));
}
}
Imagine the page had a size and colour drop-down. The above would create an array like this:
dynamicArr = [['size'], ['color']]
I want to loop through each of these separately (in order to get individual values and compare them).
My problem starts here. A dynamic array might have a length of 1, 2, 3, 4, 5, 6 (depending on the select options on the page). I therefore can't do this as there won't always be two selects
for (i = 0; i < dynamicArr[0].length; i += 1) {
}
for (i = 0; i < dynamicArr[1].length; i += 1) {
}
How would I go about finding out the length and looping individually like the above e.g. if there are three selects, it will automatically know there are this many and loop through them like above.
If you are still confused, let me know.
Thanks.

You can always use Array.forEach
dynamicArr.forEach(function(el){
console.log(el);
});

I hope I didn't get you wrong, but here's a solution:
for(i = 0; i < dynamicArr.length; i++) {
for(j = 0; j < dynamicArr[i].length; j++) {
// do something here..
}
}

you should try something like this:
dyn.forEach(function(el){//dyn is the dynamic array
console.log(el); //logs to console
});

Related

Validation of 2 or more groups of radio buttons each containing 4 radios

So I had to include this part in one of our class projects. We were asked to create a quiz webpage with radios and checkboxes, and then to write a JavaScript function to validate the radios. Now, I know that these radios can be verified easily by individuals for loops for each group, but that doesn't sound practical when I have a large number of these groups in my code. So I tried the following code:-
function quizRadioFilled()
{
var check = false;
var c = 0;
var x = 0;
var radiob = [];
radiob[0] = document.getElementsByName('q1');
radiob[1] = document.getElementsByName('q2');
radiob[2] = document.getElementsByName('q3');
radiob[3] = document.getElementsByName('q4');
radiob[4] = document.getElementsByName('q5');
radiob[5] = document.getElementsByName('q9');
radiob[6] = document.getElementsByName('q10');
for(var i = 0; i <= 6; i++)
{
for(var j = 1; j <= radiob[i].length; j++)
{
if(radiob[i].checked)
{
c = 1;
break;
}
}
if(c == 0)
{
check = false;
}
}
if(!check)
{
alert('Please attempt all the questions....');
}
}
I first stored the names of each group in an array. Then looped through this to validate each of these groups. I want to display the alert if a group has no radio button selected. But I am not getting the required result. Though I have completed this project now, I would still like to get this function to work. Kindly provide some suggestions.
You never set check to true anywhere, so it is always false.
radiob[i] is an array (or, more precisely, a NodeList), so radiob[i].checked is always undefined.
Arrays in JavaScript start indexing at 0, and this applies to NodeList as well. So your for (var j = 1; j <= radiob[i].length; j++) loop is not correct.
If you fix these problems then your function should work correctly.

How to delete rows on source right after they were pushed into an array (Sheets)

How to make to make it delete the rows that match a criteria and were pushed into an array?
So far, I got the following, but it gives me out of bounds error:
for (var i = 1; i < values.length; i++) {
if (values[i][0] == productCode) {
data.push([values[i][22],values[i][23],values[i][24],values[i][25]]); //This array is for a certain purpose.
headerData.push(headerValues[i]);//This array is for another certain purpose.
sheet.deleteRow(i+1); //This is the one I'm having trouble with.
}
}
On Source sheet, I got headers
I've seen that delete row actually works from bottom to top, but how I can re-reference i rows within that for loop?
Thanks!
Loop backwards:
for (var i = (values.length-1); i > 0; i--) {
if (values[i][0] == productCode) {
data.push([values[i][22],values[i][23],values[i][24],values[i][25]]); //This array is for a certain purpose.
headerData.push(headerValues[i]);//This array is for another certain purpose.
sheet.deleteRow(i+1); //This is the one I'm having trouble with.
}
}
I would try something like that:
let headerData = []
let data = [];
const headerSize = 1;
for (let i = values.length - 1; i > headerSize; i--) {
if (values[i][0] === productCode) {
let row = [values[i][22],values[i][23],values[i][24],values[i][25]]
data = [row, ...data]
headerData = [headerValues[i], ...headerData]
sheet.deleteRow(i+1);
}
}
use destructuring arrays to keep the values in order

Multiple loops in apps script

I am trying to run a replace text function on my slides based on an two arrays; the first array is the values that are to be replaced and the second array are the values that the corresponding values in the first array should be replaced with.
I.e. the first value in the first array should be replaced by the first value in the second array.
This is my attempt at doing it
function myFunction() {
var currentPresentationSlide = SlidesApp.getActivePresentation().getSlides();
var array1 = ['{{remove}}','{{remove2}}','{{remove3}}'];
var array2 = ['new value','new value2','new value 3'];
for (i = 0, s = 0, x = 0; i < currentPresentationSlide.length, s < array1.length, x < array2.length; i++, s++, x++) {
currentPresentationSlide[i].replaceAllText(array1[s],array2[x])
}
}
What further complicates it is, that the replaceAllText will only run on a single page and not the entire presentation, hence it will have to be run as a loop on each individual page in the slide (which is the reason for the loop with the i variable.
Does anyone know what I am doing wrong, cause this is not working for me
Thanks to Rup in the comments i solved it. Just in case anyone has the same issue this is my solution:
function myFunction() {
var currentPresentationSlide = SlidesApp.getActivePresentation().getSlides();
var array1 = ['{{remove}}','{{remove2}}','{{remove3}}'];
var array2 = ['new value','new value 2','new value 3'];
for (i = 0; i < currentPresentationSlide.length; i++) {
for (s = 0; s < array1.length; s++)
currentPresentationSlide[i].replaceAllText(array1[s],array2[s])
}
}

shift changes the length of the array so the last element is not going to be executed

In JavaScript, for a array, if methods such as pop, shift is used, the length of array changes as well. In my JS code below, it never executes the third elements 'Ds3' in the array since after the notes.shift() is executed, the length of the array becomes 0 so it just jumps out of the for loop, I do not know how to change the code so it can actually execute the 'Ds3'. Hope someone could help me out. Thank you in advance.
Code 1:
$(document).ready(function() {
var notes = ['F2', 'As2','Ds3'];
for(i = 0; i < notes.length; i++) {
$('#_' + notes.shift()).addClass('just_do_it');
alert(notes.length);
}
});
For code 2, I do not know why when I sort of make the one line code to two liner, the code does not work at all. Thank you in advance.
code 2:
$(document).ready(function() {
var notes = ['F2', 'As2','Ds3'];
var count = 0;
for(i = 0; i < notes.length; i++) {
var note = notes.shift();
$('#_' + note).addClass('just_do_it');
count++;
alert(notes.length);
}
});
Is there a reason why you want to empty that array? If insist on it, try changing to a while loop.
var notes = ['F2', 'As2','Ds3'];
var count = 0;
while(notes.length > 0){
var note = notes.shift();
$('#_' + note).addClass('shown');
count++;
alert(notes.length);
}
If I may add, you're also incrementing the count as you loop through the array. Rather you can get the count immediately just by getting the length of the array like this var count = notes.length
Also since you mentioned pop and shift arrays methods, you should checkout other array methods such as forEach, map or reduce
Since shift() is indeed destructive you could simply use the index of that iteration in the loop and leave the array unaltered
for(i = 0; i < notes.length; i++) {
// switch from `notes.shift() to notes[i]
$('#_' + notes[i]).addClass('just_do_it');
count++;
alert(notes.length);// length remains unchanged
}
Or using join() to create a selector for all and not use any loop
$('#_' + notes.join(',#_') ).addClass('just_do_it');
You could also try:
for (var count = notes.length; count > 0; count--) {
$('#_' + notes.shift()).addClass('just_do_it');
}
or
while (notes.length > 0) {
$('#_' + notes.shift()).addClass('just_do_it');
}

How do I find the last item in a js loop so I can add a class to it?

I want to build a list. No problem.
for (i = 0; i < 7; i++) {
$('#domid').append(variable.clone());
}
How do I get the LAST item in the list (in this case i.7) and add a class to it?
for (i = 0; i < 7; i++) {
$('#domid').append(variable.clone());
if (i===7) {
$('.domclass').addClass('last');
};
}
But that won't work. That just makes all of the .todo items have the class when the counter get's to 7.
Any suggestions on how to find this?
Thanks!
$('.domclass:last').addClass('last');
Or, if you'd like to do it in the loop (so, as the commenter pointed out, you don't have to traverse the DOM to get to the element again):
var newElement;
for(var i = 0; i < 7; i++){
newElement = variable.clone();
$('#domid').append(newElement);
if(i === 6) {
$(newElement).addClass('last');
}
}
i never equals 7 because the loop runs while i < 7
eq() with a negative index count backward.
$('.domclass:eq(-1)');
http://api.jquery.com/eq/
One way to do it is within the loop store a reference to the cloned item:
var i,
$item,
$domid = $('#domid');
for (i = 0; i < 7; i++) {
$item = variable.clone();
$domid.append($item);
}
$item.addClass('last');
When the loop ends $item will be the last one added. Of course this assumes the loop will always run for at least one iteration - if the number of iterations is variable and might be zero you could say:
if ($item) $item.addClass('last');
(Note that I'm also storing a reference to the #domid element rather than reselecting it on every iteration.)
This his how I would do it:
var $domid = $( '#domid' );
for ( var i = 0; i < 7; i+= 1 ) {
$domid.append( variable.clone() );
}
$domid.children( ':last' ).addClass( 'last' );

Categories