Array iteration issue in Javascript - javascript

I´m trying to make a function that reads elements from an array and distributes its values to <tr> tags of a table.
So I wrote this code:
(function () {
"use strict";
var selectQG = {
distributeCat : function (tablerow, categories) {
var tr = $(tablerow), tri = 0;
tr.each(function () {
if (tri > 2) {
for (var i = 0; i<categories.length; i++) {
this.setAttribute('categoria',categories[i]);
}
}
tri++;
});
}
}
var categories = ['1,2','3,4','5,6','7,8','9,10','11,12'];
selectQG.distributeCat('table tr', categories);
} () );
Check this fiddle to see the html code and the function working: http://jsfiddle.net/5kqEf/2/ )
The loop is being executed 6 times and I can´t figure out why. I´m still a novice at programming, so I´m in need of some help to know what I´m doing wrong. Any help would be very appreciated.
EDIT: The ideia is that every <tr> get the array value. It is supposed to happen starting from the 3rd <tr>, that´s why I put that "if" conditional. So, the first <tr> get "categories[1]", the second <tr> get "categories[2]" and so on.

The outer loop is executed 9 times, since you have 9 table tr elements. The .each will loop over every tr element, which happen to be 9 elements. See http://jsfiddle.net/5kqEf/4/
The inner for loop loops over 6 elements (the array var categories = ['1,2','3,4','5,6','7,8','9,10','11,12'];), so that makes sense...
What is your exact question?
If you want to pick a categorie based on index (and startover if there are more tr elements than categories), you might want to replace this:
for (var i = 0; i<categories.length; i++) {
this.setAttribute('categoria',categories[i]);
}
with this
var index = tri % categories.length;
this.setAttribute('categoria',categories[index]);
See https://developer.mozilla.org/en/JavaScript/Reference/Operators/Arithmetic_Operators for use of the modulus operator.

Related

Logical loop confusion javascript [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I have an array of songs, where each song has its index number in the array and the .source property. I wrote a script that creates a table row for each song:
var list = document.getElementsByClassName("preview")[1];
for (y = 0; y < allSongs.length; y ++) {
var row = list.insertRow(-1);
var celeft = row.insertCell(0);
var celright = row.insertCell(1);
celright.innerHTML = allSongs[y].name;
celeft.setAttribute("class", "left");
But now I want to make all those left cells (0) linked to the songs, which I tried to do this way:
x = document.getElementsByClassName("left");
var counter = 0;
while (counter < allSongs.length) {
x[counter+1].addEventListener('click', function() {
document.getElementById("audplayer").setAttribute("src", allSongs[counter].source);
});
counter++;
}
Basically, I made them clickable with the addEventListener property, but the problem is that the addEventListener function is not excecuted with the loop, so the counter value is not saved, and everytime I click one of the table cells, counter has a value of 3 at that moment. I understand where the problem comes from but I cannot solve it. How can this be solved?
More details (if the explanation wasnt clear enough):
I want each of the table cells to perform a different action (play different songs), but they all play the same one - allSongs[3], because counter value is taken when the click event happens, not every time the while loop is executed.
Try replacing your loops with map and _.zip from lodash.
Example pseudocode:
song_and_elem_pairs = _.zip(allSongs, x);
song_and_elem_pairs.map(function (song, elem) {
elem.addEventListener('click', function() {
document.getElementById("audplayer").setAttribute("src",
song.source);
}
});
You can also similarly replace the for (y = 0; y < allSongs.length; y ++) loop with a map.
This is certainly not the only way to do this, but it's how I would approach it and I think it should fix your problem.

How can I loop through an array of divs to show() them?

first post.. experienced with programming but not so much jQuery/javascript.
I have some divs that are hidden at first, and they are assigned id's in ascending order:
<script>
$(document).ready(function() {
$(".over_map").each(function(i) {
$(this).attr('id', "over_map" + (i + 1));
// console.log($(this));
});
});
</script>
Now I want to loop through a dynamic number of these divs and show them. If (eventually, not implemented yet) an SQL call returns 4 records, I would want to show() 4 of the hidden divs. Seems like this should be simple but I am missing something.. limited internet access unfortunately, but I didn't find any stack overflow entries pertaining to it.. any help appreciated!
If you have a set of elements in a jQuery object, you don't need to loop them at all - just call .show() on the set.
e.g.
$('#over_map1, #over_map3').show();
If you have a list of ids that you want to show, you can build the selector string:
function buildSelector(ids) {
var selectors = [];
for (var i = 0; i < ids.length; i++) {
selectors.push("#over-map" + ids[i]);
}
return selectors.join(", ");
}
$(document).ready(function(){
var ids = [1, 3];
$(buildSelector(ids)).show();
});
Demo at http://codepen.io/precise54/pen/nkyzg

How to delete all items from an FormApp object?

I recently asked a question about how to add items to a Google Form from a Google Spreadsheet. And it works great. Instead of using FormApp.create(), though, I'll have to use .openByUrl() because the ID has to stay the same. The problem is that if I run my script again, it'll open the existing form (great) and then append more items to the existing form.
This behaviour makes perfect sense but is not quite what I want. So I thought I'd just remove all existing items before I add new ones from my spreadsheet. I consulted the Google dev site for Form Services and feel like I should have all the pieces. I can't quite put them together, though.
I am now doing this following:
var form = FormApp.openByUrl('https://docs.google.com/forms/d/.../edit');
var items = form.getItems();
for (var i in items) {
form.deleteItem(i);
}
However, that'll give me an out of range error. Can someone point me in the right direction?
The problem is with how you're iterating over the array.
Try this:
var form = FormApp.openByUrl('https://docs.google.com/forms/d/.../edit');
var items = form.getItems();
for (var i=0; i<items.length; i++) {
form.deleteItem(i);
}
function clearForm(){
var items = form.getItems();
while(items.length > 0){
form.deleteItem(items.pop());
}
}
This worked for me when I ran into the same issue:
for (var i=0; i<items.length; i++) {
if (items[i] != null){
form.deleteItem(i);
}
}
Start by deleting the last item and repeat it until all items are deleted. This could be done by a reverse for loop:
function deleteAllItems(){
var form = FormApp.openById(/*put here your form id*/);
var items = form.getItems();
var end = items.length - 1;
for(var i = end ; i >= 0; i--){
form.deleteItem(i);
}
}
Another alternative is avoid of a variable index by using 0, so the first item will be deleted, no matter if a regular or a reverse loop is used. Note: This was already mentioned in a comment to another answer.
I also ran into the same problem. This one worked for me:
function deleteItems(){
var form = FormApp.openById('ID');
var items = form.getItems();
items.forEach(function(e){form.deleteItem(e)})
}
var form = FormApp.openByUrl('https://docs.google.com/forms/.../edit');
var items = form.getItems();
while(items.length > 0)
{
form.deleteItem(items.pop());
}
This works for me.
When you are checking the length of a variable=form.getItems() in a loop, its going to through some error because the length of that is not changing and the loops end up being infinite and throughing error.
So, heres my solution to the problem:
for(;form.getItems().length>0;)
{
form.deleteItem(0);
}
I ran into the same problem. However, I have fixed it by iterating in the reverse order.
var form=FormApp.openByUrl('form url here');
var Items=form.getItems();
var len=Items.length;
for (var i=Items.length-1;i>2;i--){ //Delete every item except first three items
form.deleteItem(i)
}
There are many options for looping over all form items and removing each, the most succinct being:
With Chrome V8 runtime
form.getItems().forEach(form.deleteItem)
Without Chrome V8 runtime
for each (var item in form.getItems()) {
form.deleteItem(item);
}

Looping through objects in an array JS

I'm putting together this script which pulls two child elements from a containing div #mini_ads, adds them to an array. I want to be able to use the array to select them via index in order to manip. them individually.
I know I can just select them w/o even using an array of course, but I want this array as I may add multiple more elements later.
The issue is that I am not able to select the items individually by their index in the array. The current script I've got going is selecting and manipulating both objects in the array as if they're both index[0].
var miniAds = $('#mini_ads');
var elements = miniAds.children();
var changeWtime;
var adsArr = new Array();
var i = 0;
var x = 0;
adsArr.push(elements);
console.log(adsArr);
adsArr[i].css("display", "none");
var changeWtime = setInterval(function () {
for (x; x < 1; x++) {
return x;
while (x > i) {
adsArr[1].css("display", "block");
}
};
}, 5000);
console.log(x);
changeWtime;
I am not sure where I'm going wrong here. Assistance will be much appreciated. Thanks in advance.
Issues with your code
You're creating a double array when you push elements into 'adsArr':
adsArr.push(elements);
You're throwing a return statement in the for loop:
for (x; x < 1; x++ ){
return x;
// ...
You have a double loop for no reason while inside of the for.
Solution
I was going to explain the solution to this verbally, but after coding an example I realized that there is too much to explain this is another solution similar to yours:
var miniAds = $('#mini_ads'),
elements = miniAds.children(),
i = 2,
x = 0;
elements.hide();
var changeWtime = setInterval(function () {
if ( x < i ) {
$(elements[x]).show();
}
x++;
}, 5000);
Link to example on jsbin.
Hi u should push child divs as below function does and after that i believe u can perform ur task...
var adsArr= [];
$('#mini_ads').children().each(
function(i){
adsArr.push(this);
});
In plain Javascript use .styles()
.css() which is a JQuery method but not Javascript
ref http://www.w3schools.com/js/js_htmldom_css.asp

Google-charts remove column with multiple checkboxes

languages: jQuery, javascript
Code below: Working well.
(...)
var check_box_values = $('#myForm [type="checkbox"]:not(:checked)').map(function ()
{
return this.value;
}).get();
Code below: Working well.
function f(check_box_values)
{
(...)
var obj = jQuery.parseJSON(jsonData);
var data = google.visualization.arrayToDataTable(obj);
Code below: for cycle goes fine but if statement never starts
for (var i = 1; i < data.getNumberOfColumns()-1; i++)
{
if ($.inArray(i, check_box_values) > -1)
{
data.removeColumn(i);
}
}
Html code: Working well.
What am I doing wrong?
note: the check_box_values array is populated.
edit: (eg.)
getNumberOfColumns: 6
check_box_values array: [1,3,5]
I see a problem in your code. Once data.removeColumn is called, the column index will be reset, and the result from getNumberOfColumns() will be different than what you expect. In the other words, this function is not designed to be called inside a loop.
Here is an example. Suppose you have five columns with the columIndex ranging from 0-4. You like to remove the 3rd (columnIndex: 2) and the 5th (columnIndex: 4) column. Once your code has been executed the first time, i.e., removeColumn(2), the column index will get shifted and the getNumberOfColumns() will become 4. If you call removeColumn(4), it will cause run-time error because the index is not pointing to any column. You should call removeColumn(3) instead.

Categories