how to combine two variables in jquery - javascript

I have two variables like :
<script language="javascript" type="text/javascript">
var count = 1;
calc_my_project_ + count = Math.round( count * 268 / 100); // It shoud be calc_my_project_1 and next time it shoud be calc_my_project_2
count += count + 1;
</script>
At now result is calc_my_project_ + count . how can I do this ?
EDIT : This is my main code :
<script language="javascript" type="text/javascript">
var count = 1;
var str = 'calc_my_project_';
var str2 = 'my_pro_';
var result = str + count;
result = Math.round( #Html.DisplayFor(x => item.ProgressPercent) * 268 / 100);
var secresult = str2 + count;
secresult = "-" + result + "px 0";
var jq3 = jQuery.noConflict();
jq3(document).ready(function () {
jq3("#bar-pro-#barcount1st").css({ "background-position": secresult });
if (#Html.DisplayFor(x => item.ProgressPercent) == 100) {
jq3("#bar-pro-#barcount1st").css({ "background-image": "none" });
jq3("#bar-pro-#barcount2st").css({ "background-image": "none" });
};
});
count++;
</script>
result and secresult return a fixed value I don't want to be like this .

You can do it like:
var myObj = {};
myObj['my_project_' + count] = 'some value';
count++;

try something like this
<script language="javascript" type="text/javascript">
var count = 1;
var str = 'calc_my_project_';
var result = str + count = Math.round( count * 268 / 100);
count += count + 1;
</script>

You could store your calc_my_project_ variable in an array an iterate through it each time
obj = new Array(calc_my_project_1, calc_my_project2, ...);
obj[0] = 1;
obj[1] = 2;
...

Use an array.
var myCount = new Array();
var count = 0;
$("#click").click(function() {
myCount[count] = Math.round( count * 268 / 100);
console.log(count + ' - ' + myCount[count]);
count++;
});​
Fiddle: http://jsfiddle.net/johnkoer/yyakv/1/

If you want to set "global" variables, you can use the global variable container window :
window["calc_my_project_"+ count ] = Math.round( count * 268 / 100);
alternatively you can use eval but there are more risk involved :
eval ("calc_my_project_"+ count +"= Math.round( count * 268 / 100)") ;
else, if you don't need, global variables, you can use the solution provided by Baszz

Related

Unable to target JS generated button within an array with a function, getting "Cannot read property 'setAttribute' of null" error

I'm simply trying to cause a specific button background to change when I click it.
I generated 100 buttons (in the hopes of making a simple game, later on) as an array through a for loop, while assigning an id and a distinct function call (based on the incrementing 'i' value of the loop), and am unable to actually cause the background to change upon clicking, getting the followed error instead
"Uncaught TypeError: Cannot read property 'setAttribute' of null
at showOptions (brain.js:31)
at HTMLButtonElement.onclick (index.html:15)"
My code goes as follows
var btn = [];
function generateBoard() {
for (i = 0; i < 100; i++) {
var modulo = i % 10;
var up, forLeft;
btn[i] = document.createElement("BUTTON");
var element = document.getElementById("body");
//btn[i].innerText = "CLICK ME";
element.appendChild(btn[i]);
btn[i].style.backgroundColor = "white";
btn[i].id = i;
btn[i].style.width = "50px";
btn[i].style.height = "40px";
btn[i].style.position = "absolute";
btn[i].style.top = modulo * 100;
btn[i].style.left = Math.floor(i / 10) * 100;
btn[i].x = (i + 10) % 10;
btn[i].y = Math.floor(i / 10);
document
.getElementById(btn[i].id)
.setAttribute("onclick", "showOptions(i)");
btn[i].innerText = btn[i].id;
console.log(
btn[i].id +
" " +
btn[i].style.left +
" " +
btn[i].style.top +
" " +
btn[i].x +
" " +
btn[i].y
);
}
}
generateBoard();
function showOptions(i) {
document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31
}
in console.log I actually get the correct digit as btn[i].id, oddly enough.
the (index.html:15) line of the error is simply
</html>
There are multiple issues with your code.
You should get body element with getElementsByTagName, which returns array. So pick first element.
Setting onclick attribute should use value of i not text i.
var btn = [];
function generateBoard() {
for (i = 0; i < 100; i++) {
var modulo = i % 10;
var up, forLeft;
btn[i] = document.createElement("BUTTON");
var element = document.getElementsByTagName("body")[0];
//btn[i].innerText = "CLICK ME";
element.appendChild(btn[i]);
btn[i].style.backgroundColor = "white";
btn[i].id = i;
btn[i].style.width = "50px";
btn[i].style.height = "40px";
btn[i].style.position = "absolute";
btn[i].style.top = modulo * 100;
btn[i].style.left = Math.floor(i / 10) * 100;
btn[i].x = (i + 10) % 10;
btn[i].y = Math.floor(i / 10);
document.getElementById(btn[i].id).setAttribute('onclick', 'showOptions(' + i + ')');
btn[i].innerText = btn[i].id;
console.log(btn[i].id + " " + btn[i].style.left + " " + btn[i].style.top + " " + btn[i].x + " " + btn[i].y);
}
}
generateBoard();
function showOptions(i) {
document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31
}
I've reworked your code, fixing a few issues. I assume you have an element with id body, which is distinct from the body element, which can be accessed through document.body.
var buttons = [];
function generateBoard(){
for(i = 0; i < 100; i++) {
var modulo = i % 10;
buttons[i] = document.createElement("BUTTON");
document.getElementById("body").appendChild(buttons[i]);
//buttons[i].innerText = "CLICK ME";
buttons[i].style.backgroundColor = "white";
buttons[i].id = i;
buttons[i].style.width = "50px";
buttons[i].style.height = "40px";
buttons[i].style.position = "absolute";
buttons[i].style.top = modulo * 100;
buttons[i].style.left = Math.floor(i / 10) * 100;
buttons[i].x = (i + 10) % 10;
buttons[i].y = Math.floor(i / 10);
buttons[i].addEventListener('click', function(event) {
// This code is run when the button is clicked
// Note I am passing the element, rather than an id
showOptions(this);
});
buttons[i].innerText = i;
console.log(buttons[i].id + " " + buttons[i].style.left + " " + buttons[i].style.top + " " + buttons[i].x + " " + buttons[i].y);
}
}
generateBoard();
function showOptions(button){
button.style.backgroundColor = "red";
}
Rather than assigning and attempting to use an ID attribute you can target the clicked element by referring to a property of the event itself. If you were to analyse the event ( use console ) you would notice several properties - the target allows access to the element itself which helps simplify the showOptions function. In this instance you could also simply use this to refer to the button itself from within showOptions - which would make it even simpler - such as this.style.backgroundColor='red';
let bttns=[];
const generateBoard=function( s=100 ){
const showOptions=function(e){
e.target.style.backgroundColor='red';
};
for( let i=0; i < s; i++ ){
/* create a new button and add properties */
let bttn=document.createElement('button');
bttn.setAttribute('id',i);
bttn.setAttribute('data-x',((i+10)%10));
bttn.setAttribute('data-y',Math.floor(i/10));
bttn.style.left=( Math.floor( i / 10 ) * 100 )+'px';
bttn.style.top=( ( i % 10 ) * 100 )+'px';
bttn.style.width = '50px';
bttn.style.height = '40px';
bttn.style.position = 'absolute';
bttn.innerText=i;
/* bind event listener */
bttn.addEventListener('click', showOptions );
/* add to the DOM */
document.body.appendChild( bttn );
/* if it is important to have in an array... */
bttns.push( bttn );
}
}
document.addEventListener('DOMContentLoaded',(e)=>{
generateBoard( 100 );
})
Adding arbitrary attributes to elements is not best practise - rather than assigning x and y you should make use of dataset attributes instead - so data-x and data-y would be correct.

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);
}
}

Javascript- Dynamic variable loop

I'm trying to reduce the amount of code I repeat.
Currently I have the below:
var item1H = $(".item-1").height();
var item1W = $(".item-1").height();
$(".item-1 .text").css('margin-left', -item1W/2);
$(".item-1 .text").css('margin-bottom', -item1H/2);
var item2H = $(".item-2").height();
var item2W = $(".item-2").height();
$(".item-2 .text").css('margin-left', -item2W/2);
$(".item-2 .text").css('margin-bottom', -item2H/2);
I'm looking to put this into a for loop where the variable number would count up to whatever number I needed it to stop.
You can make function like this and use whenever you want
toSetMargin(".item-2")
toSetMargin(".item-2")
function toSetMargin(objStr){
var widthTmp = $(objStr + ' .text').height();
var heightTmp = $(objStr + ' .text').height();
obj.css('margin-left', -widthTmp/2);
obj.css('margin-bottom', -heightTmp/2)
}
This code not impact any other code.
You could use $('[class^="item-"]') to get all the elements that have a class that starts with item-, and the loop over them
$('[class^="item-"]').each(function(){
var $elem = $(this);
var item1H = $elem.height();
var item1W = $elem.width();
$elem.find('.text').css({'margin-left': -item1W/2,'margin-bottom':-item1H/2});
});
Ooh boy, one of these problems. This should help (untested):
for(i=1;i<=STOPPING_NUMBER;i++){
window["item"+i+"H"] = $(".item-"+i).height();
window["item"+i+"W"] = $(".item-"+i).width(); //Was height, accident?
$(".item-"+i+" .text").css('margin-left', 0-window["item"+i+"W"]/2); //Hope this works lol
$(".item-"+i+" .text").css('margin-bottom', 0-window["item"+i+"H"]/2);
}
Guessing these lines:
var item1W = $(".item-1").height();
var item2W = $(".item-2").height();
Should have been:
var item1W = $(".item-1").width();
var item2W = $(".item-2").width();
You could do something like:
function setCSS(item,attr,val) {
$(item +" .text").css(attr, (val * -1)/2);
}
var i, max = 10;
for(i=1;i<=max;i++) {
setCSS(".item-"+ i,"margin-left",$(".item-"+ i).width());
setCSS(".item-"+ i,"margin-bottom",$(".item-"+ i).height());
}
Or something less flexible within the function:
function setCSS(item,w,h) {
$(item +" .text").css("margin-left", (w * -1)/2);
$(item +" .text").css("margin-bottom", (h * -1)/2);
}
var i, max = 10;
for(i=1;i<=max;i++) {
setCSS(".item-"+ i,$(".item-"+ i).width()),$(".item-"+ i).height());
}
Something like this should be pretty acceptible in your case, I guess:
for (var i = 1, len = someN; i < len; i++) {
var $item = $('.item-' + i);
$item.find('.text').css({
'margin-left': -$item.width() / 2,
'margin-bottom': -$item.height() / 2
});
}

total values does not change whereas sub-total changes

i have a js code for a sub total and this sub total change when im changing value for its textfields, however as this fields for TotalSavings and TotalVariable changes its supposed to change the value for my TotalExpenses as well but its not doing it. the textfields for my TotalSavings, TotalVariable and TotalExpenses are read-only, how can i make my TotalExpenses change as per value from my sub totals: TotalSavings and TotalVariable
here are my js code for sub total,
$(function() {
$("#Insurance, #COL, #Saveup, #SSS").keyup(function() {
var i = parseInt($("#Insurance").val(), 10);
var c = parseInt($("#COL").val(), 10);
var s = parseInt($("#Saveup").val(), 10);
var e = parseInt($("#SSS").val(), 10);
$("#TotalSavings").val(i + c + s + e);
});
});
$(function() {
$("#Fares, #Recreation, #OtherExpenses").keyup(function() {
var f = parseFloat($("#Fares").val(), 10);
var r = parseFloat($("#Recreation").val(), 10);
var o = parseFloat($("#OtherExpenses").val(), 10);
$("#TotalVariable").val(f + r + o);
});
});
and here is my grand total js code,
$(function() {
$("#TotalSavings, #TotalVariable").keyup(function() {
var t1 = parseFloat($("#TotalSavings").val(), 10);
var t2 = parseFloat($("#TotalVariable").val(), 10);
$("#TotalExpenses").val(t1 + t2);
});
});
Do not use keyUp handler for total value counting, use function for this.
In your case keyUp callback function for TotalSavings and TotalVariable is never called because the changes are made programmatically by script, not by user input.
$(function() {
$("#Insurance, #COL, #Saveup, #SSS").keyup(function() {
var i = parseInt($("#Insurance").val(), 10);
var c = parseInt($("#COL").val(), 10);
var s = parseInt($("#Saveup").val(), 10);
var e = parseInt($("#SSS").val(), 10);
$("#TotalSavings").val(i + c + s + e);
updateTotalExpenses();
});
$("#Fares, #Recreation, #OtherExpenses").keyup(function() {
var f = parseFloat($("#Fares").val(), 10);
var r = parseFloat($("#Recreation").val(), 10);
var o = parseFloat($("#OtherExpenses").val(), 10);
$("#TotalVariable").val(f + r + o);
updateTotalExpenses();
});
});
function updateTotalExpenses() {
var t1 = parseFloat($("#TotalSavings").val(), 10);
var t2 = parseFloat($("#TotalVariable").val(), 10);
$("#TotalExpenses").val(t1 + t2);
});

Categories

Resources