I guess i need dynamic variables in javascript to do this? - javascript

I am trying to use this stopwatch here: Stopwatch Script but for many counters on the page, that are dynamically created via php loops.
For example:
<button type="button" class="btn" id="bn1" data-bid="n1">Start</button>
<br><br>
<div id=n1></div>
<br><br>
<button type="button" class="btn" id="bn2" data-bid="n2">Start</button>
<br><br>
<div id=n2></div>
Using jquery i am trying to create 2 simple functions. One to start each timer clicked and one to stop it
<script src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
<script language=javascript>
var vars = {};
var bid;
var h = 0;
var m = 0;
var s = 0;
$('[class^=btn]').on('click', function() {
var pause = $(this).text() === 'Stop';
$(this).text(pause ? 'Start' : 'Stop');
bid = $(this).attr('data-bid');
return (this.timvar ^= 1) ? startimer(bid) : stop(bid);
});
function stop(bid) {
clearTimeout(['tm' + bid]);
}
function startimer(bid) {
//vars['tm' + bid] = setInterval('disp('+bid+')',1000);
vars['tm' + bid] = setInterval(function() {
disp(bid)
}, 1000);
}
function disp(bid) {
//alert(bid);
// Format the output by adding 0 if it is single digit //
if (s < 10) {
var s1 = '0' + s;
} else {
var s1 = s;
}
if (m < 10) {
var m1 = '0' + m;
} else {
var m1 = m;
}
if (h < 10) {
var h1 = '0' + h;
} else {
var h1 = h;
}
// Display the output //
str = h1 + ':' + m1 + ':' + s1;
document.getElementById(bid).innerHTML = str;
// Calculate the stop watch //
if (s < 59) {
s = s + 1;
} else {
s = 0;
m = m + 1;
if (m == 60) {
m = 0;
h = h + 1;
} // end if m ==60
} // end if else s < 59
// end of calculation for next display
}
</script>
Somehow i have to be able to execute these 2 functions multiple times for each button, that will use a dynamic 'tm' variable that updates the text inside the n1 and n2..(etc) divs with the timer. And then when the user presses stop to be able to stop that specific tm var.
But...i am kinda lost when it comes to dynamic variables and how to properly pass them around between javascript functions...I am not even sure if there is a simpler way of doing this...I dont know what's the proper term to search for it in google. Any advice ? What am i doing wrong ?
-Thanks

Related

how to use dynamic variable in update.js shopify

I want yo use test variable in update.js but it shows error when I use as variable but when I pass this value directly it works
can someone please tell me how can use dynamic variable to change quantity of existing products in cart
I have updated my code It will allow user to add only 5 items more than 5 items will be removed It will create string which will look like this
32082238341235:0,39470423048307:0,32164693278835:0,32164693835891:1
and finally the all IDs and qunatity will be updated by update.js
I have got error in last step its shows
{"status":404,"message":"Cart Error","description":"Cannot find variant"}
when i try to update all products
jQuery.getJSON('/cart.js', function(cart) {
var items_new = cart.items;
var count = 0;
count = cart.item_count;
var item_to_remove = count - 5;
if (count > 5) {
var item_to_remove = count - 5;
var combine = ""
if (item_to_remove > 0) {
for (var i = 0; i < items_new.length; i++) {
if (count > 5) {
var c_id = items_new[i].variant_id;
var c_quantity = items_new[i].quantity;
if (c_quantity >= item_to_remove) {
var q = c_quantity - item_to_remove
var data_multiple = c_id + ":" + q + ",";
debugger;
count = count - item_to_remove;
console.log(data_multiple);
var combine = combine + data_multiple;
} else {
var data_single = c_id + ":" + 0 + ",";
count = count - c_quantity;
item_to_remove = item_to_remove - c_quantity
console.log(data_single)
var combine = combine + data_single;
}
}
}
console.log(combine.slice(0, -1));
var test = combine.slice(0, -1);
console.log({
updates: {
test
}
});
jQuery.post('/cart/update.js', {
updates: {
test
}
});
}
t._rerenderCart()
}
t.sidebarDrawer.open()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You need to store test as an object within parentheses {} and then pass to updates by using the spread ... operator.
var test = {39470423048307 : 0, 32164693278835 : 0, 32164693835891 : 1};
console.log({updates: {...test}});
jQuery.post('/cart/update.js', {updates:{...test}});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
In your updated code, you are passing a string to updates rather than an object. You should create an object from the data inside the for loop and pass that object to updates. See lines with // CHANGE HERE:
...
var combine = {};
if (item_to_remove > 0) {
for (var i = 0; i < items_new.length; i++) {
if (count > 5) {
var c_id = items_new[i].variant_id;
var c_quantity = items_new[i].quantity;
if (c_quantity >= item_to_remove) {
var q = c_quantity - item_to_remove;
// CHANGE HERE
combine[c_id] = q;
count = count - item_to_remove;
} else {
// CHANGE HERE
combine[c_id] = 0;
count = count - c_quantity;
item_to_remove = item_to_remove - c_quantity;
}
console.log(combine);
}
}
// CHANGE HERE
var test = combine;
console.log({
updates: test
});
jQuery.post('/cart/update.js', {
updates: test
});
...

Javascript navigation with array

I'm trying to make a navigation that chagnes the background of a div using the array data.
It isn't working like I would want it.
I'm trying to use if inside addEventListener with 'click' function.
var designNextBg = document.getElementById('js-nextbg');
var designBg = document.getElementById('js-designBg');
var designBgArray = [
'url(images/ipb.png)',
'url(images/ipg.png)',
'url(images/ipr.png)',
'url(images/ipw.png)',
'url(images/ipy.png)'
];
var positionBg = document.getElementById('js-positionBg');
var i = 0;
designNextBg.addEventListener('click', function(e) {
if (i = 0) {
designBg.style.backgroundImage = designBgArray[i];
i = i + 1;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
} else if (i = 4) {
designBg.style.backgroundImage = designBgArray[i];
i = 0;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
} else {
designBg.style.backgroundImage = designBgArray[i];
i = i + 1;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
};
});
<div id="js-designBg" class="design-bg">
<div class="design-navigation">
<span id="js-positionBg">01/05</span>
<p>
<a id="js-prevbg" class="angle-buttons"><i class="fa fa-angle-left"></i></a>
<a id="js-nextbg" class="angle-buttons"><i class="fa fa-angle-right"></i></a>
</p>
</div>
</div>
your code is way to complicated. I've added two ways to deal with i and keep it inside the bounds. For once, you can do this in the click-handler (currently commented out), or you can just continuously increment/decrement there and compute the actual index inside the array with a oneliner.
var designBg = document.getElementById('js-designBg');
var designBgArray = [
'url(images/ipb.png)',
'url(images/ipg.png)',
'url(images/ipr.png)',
'url(images/ipw.png)',
'url(images/ipy.png)'
];
var positionBg = document.getElementById('js-positionBg');
var i = 0;
var nextButton = document.getElementById('js-nextbg');
var prevButton = document.getElementById('js-prevbg');
nextButton.addEventListener('click', function(e) {
//if(++i === designBgArray.length) i=0;
++i;
updateView();
});
prevButton.addEventListener('click', function(e) {
//if(--i < 0) i += designBgArray.length;
--i;
updateView();
});
function lz(nr){//a simple leading zero function
return String(nr).padStart(2, 0);
}
funciton updateView(){
var len = designBgArray.length;
//get i back into the boundaries
//you could also take care of that in the click-handler
//but this way, it's all in one place
var index = i%len + (i<0? len: 0);
designBg.style.backgroundImage = designBgArray[index];
positionBg.textContent = lz(index+1) + "/" + lz(len);
}
<div id="js-designBg" class="design-bg">
<div class="design-navigation">
<span id="js-positionBg">01/05</span>
<p>
<a id="js-prevbg" class="angle-buttons"><i class="fa fa-angle-left"></i></a>
<a id="js-nextbg" class="angle-buttons"><i class="fa fa-angle-right"></i></a>
</p>
</div>
</div>
This code works for 'NEXT' button with changing background colours replace backgroundImage as per requirement
var designNextBg = document.getElementById('js-nextbg');
var designBg = document.getElementById('js-designBg');
var designBgArray = [
'red',
'green',
'blue',
'yellow',
'cyan'
]; var positionBg = document.getElementById('js-positionBg');
var i = 0;
designNextBg.addEventListener('click', function(e) {
if (i == 0) {
designBg.style.background = designBgArray[i];
i = i + 1;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
} else if (i == 4) {
designBg.style.background = designBgArray[i];
i = 0;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
} else {
designBg.style.background = designBgArray[i];
i = i + 1;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
};
});
<div id="js-designBg" class="design-bg">
<div class="design-navigation">
<span id="js-positionBg">01/05</span>
<p>
<input type ='button' value ='NEXT' id="js-nextbg" class="angle-buttons">
</p>
</div>
</div>
designNextBg.addEventListener('click', function(e) {
if (i = 0) {
designBg.style.backgroundImage = designBgArray[i];
i = i + 1;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
} else if (i = 4) {
designBg.style.backgroundImage = designBgArray[i];
i = 0;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
} else {
designBg.style.backgroundImage = designBgArray[i];
i = i + 1;
positionBg.innerHTML = "0" + (i + 1) + "/05";
return i;
};
});
Here, inside if you must give == or === for comparison. = means assignment operator which always returns true. So i=0 returns true and always the first condition gets passed. So it returns 1. So it changes the span to 01/05.
Taking into account your code and answer posted by Thomas I would provide a working example instead of blank screen and nonexistent background.
Introduced minor code improvements for easier reading, service logic isolation and less letters.
/**
* List of random images
* #type {Array}
*/
var designBgArray = [
'https://picsum.photos/200/300',
'https://picsum.photos/201/300',
'https://picsum.photos/202/300',
'https://picsum.photos/203/300',
'https://picsum.photos/204/300'
];
var getEl = function(id) {
return document.getElementById(id);
},
addClick = function(el, fn) {
el.addEventListener('click', fn);
},
lz = function(nr) {
return String(nr).padStart(2, 0);
};
var designBg = getEl('js-designBg'),
positionBg = getEl('js-positionBg'),
nextButton = getEl('js-nextbg'),
prevButton = getEl('js-prevbg');
var render = function() {
var len = designBgArray.length,
index = i % len + (i < 0 ? len : 0);
console.log('Rendering "i"', i);
designBg.style.backgroundImage = 'url('+designBgArray[index]+')';
positionBg.textContent = lz(index+1) + "/" + lz(len);
};
var i = 0;
render(); // Initial background set (if blank bg is not applicable)
addClick(nextButton, function(e) {
i++;
if (i === designBgArray.length + 1) {
i = 0;
}
render();
});
addClick(prevButton, function(e) {
i--;
if (i < 1) {
i = designBgArray.length;
}
render();
});
.angle-buttons, #js-positionBg {
background-color: white;
}
<div id="js-designBg" class="design-bg">
<div class="design-navigation">
<span id="js-positionBg">01/05</span>
<p>
<a id="js-prevbg" class="angle-buttons"><</a>
<a id="js-nextbg" class="angle-buttons">></a>
</p>
</div>
</div>

Javascript document.getElement innerHTML undefined

I am trying to make the outcome of a function appear in a element outside the script. Instead of the outcome I get an "undefined" message. It is probably just a matter of syntax, but I don't get it to work.
Here is what I did:
<html>
<head>
</head><body>
<table class="mytable">
<tr>
<p><span id="number1">1</span><span> + </span><span id="number2">2</span><span> = </span></p>
<p><span id="sr">here goes the range of solutions to select of</span></p>
<p><span id="quote">here goes the quote</span></p>
</table>
<form id="myForm">
<div id="display" style="height: 20px; width: 100%;"></div>
<script>
var plusorminus1 = Math.random() < 0.5 ? -1 : 1;
var plusorminus2 = Math.random() < 0.5 ? -1 : 1;
var plusorminus3 = Math.random() < 0.5 ? -1 : 1;
var plusorminus4 = Math.random() < 0.5 ? -1 : 1;
var plusorminus5 = Math.random() < 0.5 ? -1 : 1;
var plusorminus6 = Math.random() < 0.5 ? -1 : 1;
var plusorminus7 = Math.random() < 0.5 ? -1 : 1;
function sortfunction(a, b){
return (a - b)
}
var number1;
var number2;
number1 = Math.floor((Math.random() * 15) + 1);
number2 = Math.floor((Math.random() * 15) + 1);
document.getElementById("number1").innerHTML = number1;
document.getElementById("number2").innerHTML = number2;
var answer = parseInt(number1,10)+parseInt(number2,10);
var addarr = []
while(addarr.length < 7){
var randomnumber = Math.ceil(Math.random()*10)
if(addarr.indexOf(randomnumber) > -1) continue;
addarr[addarr.length] = randomnumber;
}
var var1 = answer;
var var2 = answer + (plusorminus1 * addarr[0]);
var var3 = answer + (plusorminus2 * addarr[1]);
var var4 = answer + (plusorminus3 * addarr[2]);
var var5 = answer + (plusorminus4 * addarr[3]);
var var6 = answer + (plusorminus5 * addarr[3]);
var var7 = answer + (plusorminus6 * addarr[3]);
var myarray=[var1,var2,var3,var4,var5,var6,var7];
myarray=myarray.sort(sortfunction);
for(var i = 0; i < myarray.length; i++)
{
var sr = (function(val) {
btn = document.createElement('button');
btn.data = val;
btn.innerHTML = val;
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
return btn.data = val;
})(myarray[i]);
document.getElementById("sr").innerHTML = sr; //only shows the last value in the array
}
function checkAnswer(evt) {
if (evt.target.data == answer) {
display.innerHTML = ("correct");
} else {
display.innerHTML = ("Not correct");
}
document.getElementById("quote").innerHTML = evt.target.data; //does not work
}
</script>
</FORM>
</body>
</html>
So, what I want is the following:
- show the range of answers to select from within the span above.
- show the answer (correct/not correct) in the span above.
Well, maybe it is possible to make the whole code more elegant, but these are my predominant problems here.
The reason you're getting undefined is that you never return anything from the function which is assigned to the variable sr (and subsequently set as the content of a div with that same id)
var sr = (function(val) {
btn = document.createElement('button');
btn.data = val;
btn.innerHTML = val;
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
})(myarray[i]);
document.getElementById("sr").innerHTML = sr;
sr has the value undefined --^
It is not clear what you meant to put as the innerHTML of the div with an id of sr.
You set the inner HTML to sr, which is the return value of the function:
var sr = (function(val) {
// ...
// nothing is returned
})(myarray[i]);
document.getElementById("sr").innerHTML = sr;
But this function doesn't return anything!
Make it return something using the return keyword.
var sr = (function(val) {
// ...
return "I <3 Stack Overflow";
})(myarray[i]);

Change innertext of element dynamically inside for loop of a function

Issue : Upon entering a higher number like 10000, innertext of the new paragraph element is updated only after the for loop ends. Please help to make the innertext get updated for each number.
The increment function is called when an onchange event happens after sending a number as a input to the input element.
JAVASCRIPT :
function increment() {
var count = document.getElementById('ac_count').value; //ac_count is the id of the input element
var stat = document.createElement("p");
stat.id = "current_status";
stat.innerText = "";
document.body.appendChild(stat);
stat.style.display = "block";
for (g = 1; g < count; g++) {
stat.innerText = Number(g + 1) + " out of " + count + " records have been processed";
}
}
The DOM doesn't redraw until the executing thread is free. You need to introduce async delays to your code to see a progressive update.
function increment() {
var count = document.getElementById('ac_count').value;
var stat = document.createElement("p");
stat.id = "current_status";
document.body.appendChild(stat);
var g = 1
var itvl = setInterval(function() {
update(g);
g += Math.floor(Math.random() * 20) + 1
if (g >= count) {
clearInterval(itvl);
update(count);
}
}, 10)
function update(g) {
stat.textContent = g + " out of " + count + " records have been processed";
}
}
<input type=number value=10000 id=ac_count>
<button onclick="increment()">CLICK ME</button>
I'm not suggesting that this is a good solution, but this should achieve the effect you're looking for
function increment() {
var count = document.getElementById('ac_count').value; //ac_count is the id of the input element
var stat = document.createElement("p");
stat.id = "current_status";
stat.innerText = "";
document.body.appendChild(stat);
stat.style.display = "block";
updateInnerText(0, count);
}
function updateInnerText(number, max){
if(number < max){
stat.innerText = Number(number + 1) + " out of " + count + " records have been processed";
setTimeout(function(){
updateInnerText(number+1, max);
}, 500);
}
}

Assigning a value to a global variable through input method

Good day. Have patience first of all since I am just a new enthusiast to Javascript and programming in general. The concern about my project is that I want to assign a value to a global variable through input method and run it through. I've tried, researched and nothing more work for me at this time. So I am asking anyone for ideas, how will it be possible. Your assistance will definitely help me in my learning process.
Initially, the code looks likes this: Here the global variable numItems is defined by 30. That variable numItems is also mentioned within two other functions below. What I want to do is change that number through input method. I've tried...
numItems = 30;
var xvalue = [];
var yvalue = [];
for (var i=0; i < numItems; i++) {
xvalue.push(i % 9); yvalue.push((i % 9)+1);
}
followed by several functions....
This is my try, but it seems this is not working... Any assistance will be greatly appreciated.
numItems = document.getElementById("numInput");
numItems.addEventListener("input", whatValue);
function whatValue() {
var num = parseFloat(numItems.value);
document.getElementById("numInput") = num;
}
var xvalue = [];
var yvalue = [];
for (var i=0; i < numItems; i++) {
xvalue.push(i % 9); yvalue.push((i % 9)+1);
}
followed by several functions....
Here is the whole code when I applied Michael's suggestions below: It works, but my concern now are the undefined variables in the output---> undefined + undefined or undefined - undefined
<body>
<input id="numInput">
<select id="processMath">
<option value="add">Addition</option>
<option value="sub">Subtraction</option>
</select>
<button onclick="newExercise()">New Exercise</button>
<button onclick="createExercise()">Create Exercise</button>
<div id="tableOne"></div>
</body>
<script type="text/javascript">
numItems = document.getElementById("numInput");
numItems.addEventListener("input", whatValue);
function whatValue() {
numItems = parseFloat(document.getElementById("numInput").value);
}
xvalue = [];
yvalue = [];
for (var i=0; i<numItems ; i++) {
xvalue.push(i % 9); yvalue.push((i % 9)+1);
}
function tableOne (operator) {
var valtp = '';
var spc = '<table border="1" width="80%"><tr>';
i = 0;
while (i < numItems ) {
a = xvalue[i];
b = yvalue[i];
spc += '<td align="right">'+a;
if (operator == 'add') { spc += '<br>+ '+b; valtp = a+b; }
if (operator == 'sub') { spc += '<br>- '+b; valtp = a-b; }
spc += '<br>_____';
i++;
if ((i % 5) == 0) { spc += '</tr><tr>'; }
}
spc += '</tr></table>';
return spc;
}
function createExercise() {
var a = 0; var b = 0; var spc = '';
var spc = '';
var sel = document.getElementById('processMath').value;
switch (sel) {
case 'add' : spc += tableOne(sel); break;
case 'sub' : spc += tableOne(sel); break;
}
document.getElementById('tableOne').innerHTML = spc;
}
function makeRandom() {
return (Math.round(Math.random())-0.5);
}
function newExercise() {
xvalue.sort(makeRandom);
yvalue.sort(makeRandom);
}
</script>
Unless I've misunderstood you, it looks like your whatValue() function is trying to change the input value, instead of changing the numItems variable, but it's failing on both counts.
function whatValue() {
var num = parseFloat(numItems.value);
document.getElementById("numInput") = num;
}
Should be:
function whatValue() {
numItems = parseFloat(document.getElementById("numInput").value);
}
Now, your numItems variable should change every time numInput changes.
But, even though numItems changes, it won't make the rest of your code run again. So your two arrays will still look like they did when numItems was 30.

Categories

Resources