Can anyone tell me why the variables current and at do not pass to the function but when I sue the console the correct value comes up? I am completely clueless on this one which means it must be simple!
records = [118571, 118666, 118693, 118791, 118827, 118942, 119041, 119144, 119265, 119310, 119430, 119570, 119617, 119726, 119762, 120030, 120086, 120103, 120129, 120145, 120219, 120365, 120441, 120562, 120607, 120932, 121072, 121232, 121260, 121667, 121725, 121764, 121876, 122007, 122008, 122009, 122131, 122458, 122804, 123081, 123156, 123239, 123320, 123413, 123624, 123715, 123842, 123953];
x = 48;
y = 48;
current = 123953;
function changerecord(change) {
var at = records.indexOf(current);
if (change == -1) {
var next = current;//current because we are going back one
var previous = records[at - 3];//-2 because we started on record and are moving 2 back
var moveto = records[at - 2];
x = x - 1;
document.getElementById("count").innerHTML = x + ' of ' + y;
alert("AT : " + at + "\n" + "Previous : " + previous + "\n" + "Next : " + next + "\n" + "x : " + x + "\n" + "y : " + y + "\n" + "moveto : " + moveto + "\n");
var current = moveto;
//document.getElementById('iframe_records').src='recordtemplate.php?flight=' + moveto;
}
else if (change == +1) {
var previous = current;//current because we are going back one
var next = records[at + 2];//-2 because we started on record and are moving 2 back
var moveto = records[at + 1];
x = x + 1;
alert("AT : " + at + "\n" + "Previous : " + previous + "\n" + "Next : " + next + "\n" + "x : " + x + "\n" + "y : " + y + "\n" + "moveto : " + moveto + "\n");
document.getElementById("count").innerHTML = x + ' of ' + y;
var current = moveto;
//document.getElementById('iframe_records').src='recordtemplate.php?flight=' + moveto;
}
}; // lookup
You have some scoping and variable name problems in there:
First of, try to declare variables with var
var records = [...]
var variable = ...
so this is global in the current scope and you also can use it in the function, if the function is also in the scope.
You are just changing the value of current and than inside the function scope, you are using var current = ... Use another name, it's not like they are limited.
var test = 1;
function test() {
console.log(test); // Output: 1
var test = 2;
var oktopus = 8;
console.log(test); // Output: 2
console.log(oktopus); // Output: 8
}
console.log(test); // Output: 1
console.log(oktopus); // undefined oktopus
You can pass current as a parameters, to avoid this problem:
then when you call changerecord, it will be like this:
changerecord(change, 123953)
You have assigned a value to the variable current without declaring it with var keyword. When you do such this, i.e. assign a value to a non-declared variable, that variable become a property on global object (i.e. window).
Another point that you should know is when you declare a local variable with the same name as another variable in parent function scope, the most localized variable will be used in the inner function scope.
// ...
current = 123953; // Global variable
function changerecord(change) { // Local variable
var at = records.indexOf(current); // Local variable will be used
if (change==-1) // Also local one
{
var next = current; // Still local one!
// ...
Note that window.current should work.
try:
$(document).ready(function(){
changerecord(change);
});
Related
I am sure that this has been asked and answered before, but I can't seem to find the right terminology to find an answer. I need to dynamically create a series of functions for later use which use certain values defined by parameters upon creation. For example:
var i = "bar";
var addBar = function(x) {
// needs to always return x + " " + "bar"
return x + " " + i;
}
i = "baz";
var addBaz = function(x) {
// needs to always return x + " " + "baz"
return x + " " + i;
}
alert(addBar("foo")); // returns "foo baz" because i = "baz"
Is there a way I can pass i to these functions so that the original value is used, and not the reference to the variable? Thank you!
You would have to do something that stores the variable. Making a function that returns a function is one way to do it.
var i = "bar";
var addBar = (function (i) {
return function(x) {
return x + " " + i;
}
}(i));
i = "baz";
var addBaz = (function (i) {
return function(x) {
return x + " " + i;
}
}(i));
console.log(addBar("foo"));
console.log(addBaz("foo"));
Okay, that title will sound a bit crazy. I have an object, which I build from a bunch of inputs (from the user). I set them according to their value received, but sometimes they are not set at all, which makes them null. What I really want to do, it make an item generator for WoW. The items can have multiple attributes, which all look the same to the user. Here is my example:
+3 Agility
+5 Stamina
+10 Dodge
In theory, that should just grab my object's property name and key value, then output it in the same fashion. However, how do I setup that if-statement?
Here is what my current if-statement MADNESS looks like:
if(property == "agility") {
text = "+" + text + " Agility";
}
if(property == "stamina") {
text = "+" + text + " Stamina";
}
if(property == "dodge") {
text = "+" + text + " Dodge";
}
You get that point right? In WoW there are A TON of attributes, so it would suck that I would have to create an if-statement for each, because there are simply too many. It's basically repeating itself, but still using the property name all the way. Here is what my JSFiddle looks like: http://jsfiddle.net/pm2328hx/ so you can play with it yourself. Thanks!
EDIT: Oh by the way, what I want to do is something like this:
if(property == "agility" || property == "stamina" || ....) {
text = "+" + text + " " + THE_ABOVE_VARIABLE_WHICH_IS_TRUE;
}
Which is hacky as well. I definitely don't want that.
if(['agility','stamina','dodge'].indexOf(property) !== -1){
text = "+" + text + " " + property;
}
If you need the first letter capitalized :
if(['agility','stamina','dodge'].indexOf(property) !== -1){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
UPDATE per comment:
If you already have an array of all the attributes somewhere, use that instead
var myatts = [
'agility',
'stamina',
'dodge'
];
if(myatts.indexOf(property) !== -1){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
UPDATE per next comment:
If you already have an object with the attributes as keys, you can use Object.keys(), but be sure to also employ hasOwnProperty
var item = {};
item.attribute = {
agility:100,
stamina:200,
dodge:300
};
var property = "agility";
var text = "";
if(Object.keys(item.attribute).indexOf(property) !== -1){
if(item.attribute.hasOwnProperty(property)){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
}
Fiddle: http://jsfiddle.net/trex005/rk9j10bx/
UPDATE to answer intended question instead of asked question
How do I expand the following object into following string? Note: the attributes are dynamic.
Object:
var item = {};
item.attribute = {
agility:100,
stamina:200,
dodge:300
};
String:
+ 100 Agility + 200 Stamina + 300 Dodge
Answer:
var text = "";
for(var property in item.attribute){
if(item.attribute.hasOwnProperty(property)){
if(text.length > 0) text += " ";
text += "+ " + item.attribute[property] + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
}
It's unclear how you're getting these values an storing them internally - but assuming you store them in a hash table:
properties = { stamina: 10,
agility: 45,
...
}
Then you could display it something like this:
var text = '';
for (var key in properties) {
// use hasOwnProperty to filter out keys from the Object.prototype
if (h.hasOwnProperty(k)) {
text = text + ' ' h[k] + ' ' + k + '<br/>';
}
}
After chat, code came out as follows:
var item = {};
item.name = "Thunderfury";
item.rarity = "legendary";
item.itemLevel = 80;
item.equip = "Binds when picked up";
item.unique = "Unique";
item.itemType = "Sword";
item.speed = 1.90;
item.slot = "One-handed";
item.damage = "36 - 68";
item.dps = 27.59;
item.attributes = {
agility:100,
stamina:200,
dodge:300
};
item.durability = 130;
item.chanceOnHit = "Blasts your enemy with lightning, dealing 209 Nature damage and then jumping to additional nearby enemies. Each jump reduces that victim's Nature resistance by 17. Affects 5 targets. Your primary target is also consumed by a cyclone, slowing its attack speed by 20% for 12 sec.";
item.levelRequirement = 60;
function build() {
box = $('<div id="box">'); //builds in memory
for (var key in item) {
if (item.hasOwnProperty(key)) {
if (key === 'attributes') {
for (var k in item.attributes) {
if (item.attributes.hasOwnProperty(k)) {
box.append('<span class="' + k + '">+' + item.attributes[k] + ' ' + k + '</span>');
}
}
} else {
box.append('<span id="' + key + '" class="' + item[key] + '">' + item[key] + '</span>');
}
}
}
$("#box").replaceWith(box);
}
build();
http://jsfiddle.net/gp0qfwfr/5/
function saveForm() {
var array = [];
array.push(txtTName.value + "," + txtTNumber.value + "," + txtProjName.value + "," + getTotal());
var scores = document.getElementById("scores");
scores.innerHTML += "<br \>" + array[0] + array[1] + array[2];
}
Here's my code. So when a button is pushed it calls "saveForm()" which saves the values into an array and displays them. The first time its called it displays "xxxxx undefined undefined" the next time it calls "yyyyyy undefined undefined". Shouldn't it be returning "xxxxx yyyyy undefined"?
I'm only displaying elements 0,1, and 2 right now for testing purposes.
function saveForm(){
var array = [];
var list = txtTName.value + "," + txtTNumber.value + "," + txtProjName.value + "," + getTotal();
array.push(list);
var scores = document.getElementById("scores");
scores.innerHTML += "<br \>" + array[0] + array[1] + array[2];
}
Here's an edited version of saveForm(). The values don't really matter, I'm more wondering if there's a reason its only changing the first element. Do I need to create array outside of the function?
function saveForm() {
var array = [];
array.push(txtTNumber.value);
array.push(txtTNumber.value);
array.push(txtProjName.value);
array.push(getTotal());
document.getElementById("scores").innerHTML += "<br \>" + array.join(', ');
}
var array = [];
function saveForm(){
....
}
I am having trouble getting my code to count the number of times the word 'Yes' appears in a variable. It works if I replace the variable with the string 'YesYesYes.' The result is 3. I want to do the same, but from a variable instead.
Here is my code.
function getAllAnswers() {
var var_allAnswers = document.querySelector('input[name="Q1"]:checked').value + document.querySelector('input[name="Q2"]:checked').value + document.querySelector('input[name="Q3"]:checked').value + document.querySelector('input[name="Q4"]:checked').value + document.querySelector('input[name="Q5"]:checked').value + document.querySelector('input[name="Q6"]:checked').value + document.querySelector('input[name="Q7"]:checked').value + document.querySelector('input[name="Q8"]:checked').value + document.querySelector('input[name="Q9"]:checked').value + document.querySelector('input[name="Q10"]:checked').value + document.querySelector('input[name="Q11"]:checked').value + document.querySelector('input[name="Q12"]:checked').value + document.querySelector('input[name="Q13"]:checked').value + document.querySelector('input[name="Q14"]:checked').value + document.querySelector('input[name="Q15"]:checked').value + document.querySelector('input[name="Q16"]:checked').value + document.querySelector('input[name="Q17"]:checked').value + document.querySelector('input[name="Q18"]:checked').value + document.querySelector('input[name="Q19"]:checked').value + document.querySelector('input[name="Q20"]:checked').value;
document.getElementById("AllAnswers").innerHTML = var_allAnswers;
}
function yesCount() {
var var_yesCount = var_allAnswers.split("Yes").length - 1;
document.getElementById("YesCount").innerHTML = var_yesCount;
}
function noCount() {
var var_noCount = var_allAnswers.split("No").length - 1;
document.getElementById("NoCount").innerHTML = var_noCount;
}
Here is my markup.
<button onclick="yesCount()">Yes Count</button><br/>
Yes Count: <p id="YesCount"></p><br/><br/>
<button onclick="noCount()">No Count</button><br/>
No Count: <p id="NoCount"></p><br/><br/>
All Answers: <p id="AllAnswers"></p><br/><br/>
Does anyone have any ideas?
The variable var_allAnswers called in the yesCount and noCount functions is out of scope, meaning it's inaccessible to your functions. A somewhat hackish fix:
(function()
{
var var_allAnswers;
function getAllAnswers() {
var_allAnswers = document.querySelector('input[name="Q1"]:checked').value + document.querySelector('input[name="Q2"]:checked').value + document.querySelector('input[name="Q3"]:checked').value + document.querySelector('input[name="Q4"]:checked').value + document.querySelector('input[name="Q5"]:checked').value + document.querySelector('input[name="Q6"]:checked').value + document.querySelector('input[name="Q7"]:checked').value + document.querySelector('input[name="Q8"]:checked').value + document.querySelector('input[name="Q9"]:checked').value + document.querySelector('input[name="Q10"]:checked').value + document.querySelector('input[name="Q11"]:checked').value + document.querySelector('input[name="Q12"]:checked').value + document.querySelector('input[name="Q13"]:checked').value + document.querySelector('input[name="Q14"]:checked').value + document.querySelector('input[name="Q15"]:checked').value + document.querySelector('input[name="Q16"]:checked').value + document.querySelector('input[name="Q17"]:checked').value + document.querySelector('input[name="Q18"]:checked').value + document.querySelector('input[name="Q19"]:checked').value + document.querySelector('input[name="Q20"]:checked').value;
document.getElementById("AllAnswers").innerHTML = var_allAnswers;
}
function yesCount() {
var var_yesCount = var_allAnswers.split("Yes").length - 1;
document.getElementById("YesCount").innerHTML = var_yesCount;
}
function noCount() {
var var_noCount = var_allAnswers.split("No").length - 1;
document.getElementById("NoCount").innerHTML = var_noCount;
}
})();
Though you should really be passing the var_allAnswers variable around in your function calls as an argument.
The local variable var_allAnswers you declared in getAllAnswers() can't be used in another function, instead you shoud declare your variable as Global or create a function that returns the variable to deal with. Ex:
var var_allAnswers;
function getAllAnswers() {
var_allAnswers = document.querySelector('...
document.getElementById("AllAnswers").innerHTML = var_allAnswers;
}
getAllAnswers();
It appears you have a problem of scope here.
A var defines a varable which is available only in the block containing it { }
So, when you exit getAllAnswers() your variable var_allAnswers is discarded.
You need to reinitialize it before you could reuse it
function yesCount() {
var_allAnswers = document.querySelector('input[name="Q1"]:checked').value
var var_yesCount = var_allAnswers.split("Yes").length - 1 ;
document.getElementById("YesCount").innerHTML = var_yesCount;
}
I also think it's a problem of scope. In the yesCount() and noCount() functions, the variable var_allAnswers cannot be referred. Marcel's answer is right.
You may want to learn about the block scope in javascript. Here is an article about that:
http://danbeam.org/blog/2011/05/23/turns-out-there-is-block-scope-in-javascript-kinda/
I type in scroll(0,10,200,10);
But when it runs it passes the string "xxpos" or "yypos" and I did try it without the appostraphes, but it just didn't work.
scroll = function(xpos,ypos,time,rounds){
var xxpos = xpos*1;
var yypos = ypos*1;
var rrounds = rounds*1;
var ttime = time*1;
x = 0;
xyz=window.setInterval("scroller('xxpos','yypos','ttime','rrounds')",ttime);
}
function scroller(xpos,ypos,time,rounds){
alert(xpos + ypos + time + rounds);
}
Don't use strings, use closures (anonymous functions).
window.setTimeout(function() {
scroller(xxpos, yypos, ttime, rrounds);
}, ttime);
It should be like this:
xyz=window.setInterval("scroller(" + xxpos + "," + yypos + "...
otherwise you just pass strings xxpos, yypos etc.
do you happen to know that in your code, each call to scroll() builds a timer?
do you mean to do it like it was a loop? then:
xyz = window.setTimeout(function(){
scroller(xxpos,yypos,ttime,rrounds)
},ttime);
You should use closure:
...
xyz = window.setInterval(function() { scroller(xxpos,yypos,ttime,rrounds); }, ttime);
...
That's because the string does not become the variable.
This would work:
window.setInterval("scroller("+ xxpos + "," + yypos + "," + ttime + "," + rrounds + ")",ttime);
Or better:
window.setInterval(function() { scroller(xxpos, yypos, ttime, rrounds); }, ttime);