Loop through elements with greasemonkey - javascript

I have the following working code on greasemonkey:
var qtt = 100;
var filler1 = document.getElementById("s1_0");
var filler2 = document.getElementById("s2_0");
var filler3 = document.getElementById("s3_0");
var filler4 = document.getElementById("s4_0");
var filler5 = document.getElementById("s5_0");
var filler6 = document.getElementById("s6_0");
var filler7 = document.getElementById("s7_0");
filler1.value = qtt;
filler2.value = qtt;
filler3.value = qtt;
filler4.value = qtt;
filler5.value = qtt;
filler6.value = qtt;
filler7.value = qtt;
Where the "sN_0" are the names of inputs, the code works, but I was wondering if there is a better way to do the same, to loop through all the id names or something.

here is a simple loop doing that your code does
var qtt=100;
for (var i =1;i<8;i++){
document.getElementById("s"+i+"_0").value=qtt
}

If you can use jQuery, try the following.
var qtt = 100;
$('[id]').each(function() {
if(/^s\d_0$/.test(this.id)) {
this.value = qtt;
}
});
Demo

Related

I have a misunderstanding with localStorage

I'm currently beginning to learn how to use javascript, and I have a small problem.
I'm making a minigame of 'find the random number', and I'm trying to implement a localStorage savestate that let me keep my game as it was when I closed it, but without success. Here's the part of my JS
where I'm stuck.
let Rndm = Math.floor(Math.random() * 100) + 1;
var tentatives = document.querySelector('.tentatives');
var resultat = document.querySelector('.resultat');
var plusoumoins = document.querySelector('.plusoumoins');
var valider = document.querySelector('.valider');
var essai = document.querySelector('.essai');
var nmbrmax = 1000;
var nmbrtent = 1;
let j1 = document.getElementById("j1");
let j2 = document.getElementById("j2");
var joueur1 = document.getElementById("joueur1");
var joueur2 = document.getElementById("joueur2");
let nomsjoueurs = document.getElementById("nomsjoueurs");
let tour = document.getElementById("tour");
var playerTurn = 0;
const partiesauvee = []
function sauvegarder() {
partiesauvee.push(tentatives.textContent);
partiesauvee.push(resultat.textContent);
partiesauvee.push(plusoumoins.textContent);
partiesauvee.push(nmbrmax);
partiesauvee.push(nmbrtent);
partiesauvee.push(joueur1.value);
partiesauvee.push(joueur2.value);
localStorage.setItem('sauvegard', JSON.stringify(partiesauvee))
}
function refresh() {
const partiesauvee = JSON.parse(localStorage.getItem('sauvegard'));
var tentatives = JSON.parse(localStorage.getItem('sauvegard'));
var resultat = JSON.parse(localStorage.getItem('sauvegard'));
var plusoumoins = JSON.parse(localStorage.getItem('sauvegard'));
var nmbrmax = localStorage.getItem('sauvegard');
var nmbrtent = localStorage.getItem('sauvegard');
var joueur1 = JSON.parse(localStorage.getItem('sauvegard'));
var joueur2 = JSON.parse(localStorage.getItem('sauvegard'));
}
window.addEventListener('DOMContentLoaded', refresh);
When the sauvegarder function is activated, the console.log(localstorage) find all the values,
but I can't find a way to return them to their places. Someone have an idea? Thanks !
You're storing an array. You need to assign each array element to a different DOM element.
function refresh() {
const storage = localStorage.getItem('sauvegard');
if (!storage) { // nothing saved
return;
}
const partiesauvee = JSON.parse(storage);
tentatives.textContent = partiesauvee[0];
resultat.textContent = partiesauvee[1];
plusoumoins.textContent = partiesauvee[2];
nmbrmax.textContent = partiesauvee[3];
nmbrtent.textContent = partiesauvee[4];
joueur1.textContent = partiesauvee[5];
joueur2.textContent = partiesauvee[6];
}

Reading values from input fields created in an array with document.createElement()

I'm trying to build a table that the user can hit "new line" to create a new row of the table. I do this by foo.push(document.createElement("INPUT"));
function newLine() {
sArr.push(document.createElement("INPUT"));
sArr[sArr.length-1].setAttribute("type", "text");
document.body.appendChild(sArr[sArr.length-1]);
gArr.push(document.createElement("INPUT"));
gArr[gArr.length-1].setAttribute("type", "text");
document.body.appendChild(gArr[gArr.length-1]);
tArr.push(document.createElement("INPUT"));
tArr[tArr.length-1].setAttribute("type", "text");
document.body.appendChild(tArr[tArr.length-1]);
//alert(sArr.length+", "+gArr.length+", "+tArr.length);
var x = document.createElement("br");
document.body.appendChild(x);
}
function calc(){
var temp = 0;
var total = 0;
for(i = 0; i<sArr.length; i++){
total = total + calc2(i);
}
var o = document.getElementById("output");
o.value = total;
}
function calc2(i){
alert(i);
var s = document.getElementById(sArr[i]);
var g = document.getElementById(gArr[i]);
var t = document.getElementById(tArr[i]);
var VO2walkmin = 3.28;
var VO2rest = 3.05;
var C1 = 0.32;
var C2 = 0.19;
var C3 = 2.66;
var Cdecline = 0.73;
var s2 = s.value;
var g2 = g.value;
var t2 = t.value;
var negGrade = g.value;
if(g2 < 0){g2 = 0};
VO2move = ((C1 * g2)+VO2walkmin)+((1+(C2*g2))*(C3*(s2^2)));
VO2inc = VO2rest+(t2*VO2move);
VO2dec = VO2rest+(Cdecline*(t2*VO2move))
//var o = document.getElementById("output");
return VO2inc;
}
When run, I get the error:
Uncaught TypeError: Cannot read property 'value' of null
from line 66. Specifically, this line:
var s2 = s.value;
I'm struggling to find my mistake here... and all help is appreciated.
You create a new element, but it has no ID. And so you can't fetch it by ID. The result of document.getElementById(sArr[i]) will be null.
Check this answer to see how ID can be assigned to a newly created element:
Create element with ID
There's no need to use document.getElementById. sArr[i] is the input element itself, not its ID, so you can just read its value directly.
var s = sArr[i];
var g = gArr[i];
var t = tArr[i];

How to make this jQuery code more simple and effective

I have follow two functions here which working great!
As you can see these two functions are almost the same, except the code which comes below the last comment in each function.
How do I make that more simple. Could I make a code-"holder" - Where I only include a part of a code from another file? So I don't have too have the "same" code in each functions?
Should I use some kind of classes or? - I have never worked with classes.
/// Function (add_new_field)
$(document).on("click", '.add_new_field', function(e) {
e.preventDefault();
var flex0 = $(this);
var flex1 = $(this).parent().closest('div');
var flex2 = $(flex1).parent().closest('div');
var flex3 = $(flex2).parent().closest('div');
var flex4 = $(flex3).parent().closest('div');
var flex5 = $(flex4).parent().closest('div');
var flex6 = $(flex5).parent().closest('div');
/*console.log(
' -> WrapID:'+flex6.attr('id')+
' -> accordionContentID:'+flex5.attr('id')+
' -> acContentBoxID:'+flex4.attr('id')+
' -> acChildBoxID:'+flex3.attr('id')+
' -> acBabyBoxID:'+flex2.attr('id')+
' -> SecondID:'+flex1.attr('id')+
' -> FirstID:'+flex0.attr('id')
);*/
var wrapID = flex6.attr('id'); // wrapID
var accordionContentID = flex5.attr('id');
var acContentBoxID = flex4.attr('id'); // sharedID
var acChildBoxID = flex3.attr('id'); // langID
var acBabyBoxID = flex2.attr('id'); // langID
var SecondID = flex1.attr('id'); // OLD : AddLangBoxID
var FirstID = flex0.attr('id'); // OLD : add_new_fieldID
// there is a lot more code here...
)};
/// Function (del_field)
$(document).on("click", '.del_field', function(e) {
e.preventDefault();
var flex0 = $(this);
var flex1 = $(this).parent().closest('div');
var flex2 = $(flex1).parent().closest('div');
var flex3 = $(flex2).parent().closest('div');
var flex4 = $(flex3).parent().closest('div');
var flex5 = $(flex4).parent().closest('div');
var flex6 = $(flex5).parent().closest('div');
var wrapID = flex6.attr('id'); // wrapID
var accordionContentID = flex5.attr('id');
var acContentBoxID = flex4.attr('id'); // sharedID
var acChildBoxID = flex3.attr('id'); // langID
var acBabyBoxID = flex2.attr('id'); // langID
var SecondID = flex1.attr('id'); // OLD : AddLangBoxID
var FirstID = flex0.attr('id'); // OLD : add_new_fieldID
// there is a lot more code her
)};
How could I make something like this.
/// I want to include this code into the functions. So I don't have to write it twice.
var flex0 = $(this);
var flex1 = $(this).parent().closest('div');
var flex2 = $(flex1).parent().closest('div');
var flex3 = $(flex2).parent().closest('div');
var flex4 = $(flex3).parent().closest('div');
var flex5 = $(flex4).parent().closest('div');
var flex6 = $(flex5).parent().closest('div');
var wrapID = flex6.attr('id'); // wrapID
var accordionContentID = flex5.attr('id');
var acContentBoxID = flex4.attr('id'); // sharedID
var acChildBoxID = flex3.attr('id'); // langID
var acBabyBoxID = flex2.attr('id'); // langID
var SecondID = flex1.attr('id'); // OLD : AddLangBoxID
var FirstID = flex0.attr('id'); // OLD : add_new_fieldID
Thank you.
If you want to do something like classes in javascript, your best bet is to use prototyping, since javascript doesn't have classes.
In this case, I'm not sure what your code does, so prototyping might not be the best answer. Your other option is to encapsulate all of your variable definitions in another function, and call that function in both of your click functions. It would return an object with attributes, rather that a bunch of vars.
var myVarFn = function(){
var returnObject = {};
returnObject.flex0 = $(this);
returnObject.flex1 = $(this).parent().closest('div');
...
returnObject.wrapID = flex6.attr('id'); // wrapID
...
return returnOBject
}
And to use it in click, with this defined the same as in the scope of the click function:
$(document).on("click", '.del_field', function(e) {
var dataObject = myVarFn.call(this);
//Other code
};
And in the other click event,
$(document).on("click", '.add_new_field', function(e) {
var dataObject = myVarFn.call(this);
//Other code
};
You will have to modify your other code to use dataObject.flex0 instead of flex0 and so on.
Create a global object
var allId = new Object();
And a function that can be called whenever needed..
function getAllIDs(el) {
var id = ["wrapID", "accordionContentID", "acContentBoxID", "acChildBoxID", "acBabyBoxID", "SecondID", "FirstID"];
var flex;
for (var i = 0; i <= 6; i++) {
if (i == 0) {
flex = $(el).parent().closest('div');
} else {
flex = $(flex).parent().closest('div');
}
allId.id[i] = $(flex).parent().closest('div').attr('id');
}
}
Further, on jQuery event you can call getAllIDs function
$(document).on("click", '.add_new_field', function (e) {
e.preventDefault();
getAllIDs(this);
});
More details about javascript objects

JQuery Swap input values in rows

I am working on a table that I need to be able to move rows up and down.
The problem is that I cannot re-insert the row before the previous or next row, because my application relies on the names of the input fields to stay in the same order.
My solution is to swap the values of the input fields, which works, but my code is very ugly and repetitive.
$(document).ready(function(){
$(".up,.down").click(function(){
var row = $(this).parents("tr:first");
var rowdata1 = row.find('.rowdata1').val();
var rowdata2 = row.find('.rowdata2').val();
var rowdata3 = row.find('.rowdata3').val();
var rowdata4 = row.find('.rowdata4').val();
var rowdata5 = row.find('.rowdata5').val();
if ($(this).is(".up")) {
var tmp1 = row.prev().find('.rowdata1').val();
var tmp2 = row.prev().find('.rowdata2').val();
var tmp3 = row.prev().find('.rowdata3').val();
var tmp4 = row.prev().find('.rowdata4').val();
var tmp5 = row.prev().find('.rowdata5').val();
row.prev().find('.rowdata1').val(rowdata1);
row.prev().find('.rowdata2').val(rowdata2);
row.prev().find('.rowdata3').val(rowdata3);
row.prev().find('.rowdata4').val(rowdata4);
row.prev().find('.rowdata5').val(rowdata5);
row.find('.rowdata1').val(tmp1);
row.find('.rowdata2').val(tmp2);
row.find('.rowdata3').val(tmp3);
row.find('.rowdata4').val(tmp4);
row.find('.rowdata5').val(tmp5);
//row.insertBefore(row.prev());
} else {
var tmp1 = row.next().find('.rowdata1').val();
var tmp2 = row.next().find('.rowdata2').val();
var tmp3 = row.next().find('.rowdata3').val();
var tmp4 = row.next().find('.rowdata4').val();
var tmp5 = row.next().find('.rowdata5').val();
row.next().find('.rowdata1').val(rowdata1);
row.next().find('.rowdata2').val(rowdata2);
row.next().find('.rowdata3').val(rowdata3);
row.next().find('.rowdata4').val(rowdata4);
row.next().find('.rowdata5').val(rowdata5);
row.find('.rowdata1').val(tmp1);
row.find('.rowdata2').val(tmp2);
row.find('.rowdata3').val(tmp3);
row.find('.rowdata4').val(tmp4);
row.find('.rowdata5').val(tmp5);
//row.insertAfter(row.next());
}
});
});
I created a fiddle: http://jsfiddle.net/29T7V/
I would really appreciate any suggestions on how to simplify my code.
Any ideas on how to update my code to handle x amount of inputs in the rows would be absolutly awesome! TIA!
Something like this maybe
$(document).ready(function () {
$(".up, .down").on('click', function () {
var row = $(this).closest('tr').first(),
way = $(this).hasClass('up') ? 'prev' : 'next';
for (var i=1; i<6; i++) {
var sel = '.rowdata'+i,
tmp1 = row.find(sel).val(),
tmp2 = row[way]().find(sel).val();
row.find(sel).val(tmp2);
row[way]().find(sel).val(tmp1);
}
});
});
FIDDLE
Something wich would work with any number of columns:
$(document).ready(function () {
$(".up, .down").click(function () {
var $row = $(this).closest("tr"),
$swap = $row[$(this).is('.up') ? 'prev' : 'next']();
if (!$swap) return;
$row.find('td').each(function() {
var $input = $(this).find('input, select'),
$swapInput, $swapVal;
if ($input.length) {
$swapInput = $swap.children('td:eq(' + this.cellIndex + ')').find('input, select');
$swapVal = $swapInput.val();
$swapInput.val($input.val());
$input.val($swapVal);
}
});
});
});
Demo: http://jsfiddle.net/29T7V/

This code doesnt work. trying to use a loop to get the sizes of my images the first one comes but the others dont

$j(document).ready(<script type="text/JavaScript">
function getProps(){
var imgwidth = [];
var imgheight = [];
var w, h;
var width = document.getElementById('des').clientWidth;
var height = document.getElementById('des').clientHeight;
img = document.getElementById('des').getElementsByTagName('img').length;
w = document.getElementById('des').getElementsByTagName('img');
h = document.getElementById('des').getElementsByTagName('img');
for ( count = 0; count < img; count++){
imgwidth[count] = w.item(count).clientWidth;
imgheight[count] = h.item(count).clientHeight;
}
</script>);
I think this is what you want, I refactored your code a little:
function getProps()
{
var imgwidth = [];
var imgheight = [];
var images = document.getElementById('des').getElementsByTagName('img');
var count = images.length;
for ( i = 0; i < count; i++)
{
imgwidth[i] = images[i].clientWidth;
imgheight[i] = images[i].clientHeight;
}
console.log(imgwidth);
console.log(imgheight);
}
$(document).ready(function()
{
getProps()
});​
I have set up a jsfiddle for you to demonstrate this: http://jsfiddle.net/JbpdW/
Edit
If you use jQuery (what you obvilously do), you can simplify that process a little by using:
$("#des img").each(function(i)
{
imgwidth[i] = this.clientWidth;
imgheight[i] = this.clientHeight;
});
with jquery it is very short:
$j(function() {
var result=$j.map($('#des img'),function(el,i) {
var $el=$j(el); //optimize
return {width:$el.width(),height:$el.height()};
});
console.log(result);
});
please note that i used array of objects instead of two variables, it easer to work with one variable than with two :)
http://jsbin.com/uzikeh/2/edit

Categories

Resources