I'm using the code below to check if var1 exists, then assigning another variable (promt) to store var1 provided that the user types in the variable. Problem is I have about twenty variables I need to check so my code looks like the below times ten:
if (typeof var1 !== 'undefined') {
if(selection==var1){
var promt = var1;
}
}
if (typeof var2 !== 'undefined') {
if(selection==var2){
var promt = var2;
}
}
This (a) makes a ton of inefficient code and (b) may cause errors if I have over twenty variables. Is there a way to check if var1, var2, var3, etc.. exists then stop checking when the variables stop?The goal is to be able to have one hundred variables and still have the same amount of code I would have if there were two.
If your variables are fields on an object you can easily build the field names dynamically:
fieldname = 'var' + index;
if (typeof obj[fieldname] !== 'undefined') {
if (selection == obj[fieldname]){
var promt = obj[fieldname];
}
}
For local variables I however can't provide a solution.
First thing first var is reserved word in javascript, so you cannot use it as variable names, hence I use _var here instead.
I made a jsFiddle for this solution, so check it out pls.
You may also look at the code below:
for (i in _var) {
// Loop through all values in var
if ((typeof _var [i] !== undefined) &&
selection_array.indexOf(_var [i]) >= 0) {
// note that array.indexOf returns -1 if selection_array does not contain var [i]
prompt = _var[i]; // use this if you only want last var[i] satisifying the condition to be stored
prompt_array.push(_var[i]);// use this if you want to store all satisifying values of var[i]
}
}
Also check the below snippet
// Lets declare and give some example value to _var, Note that you cannot use var as variable name as it is a reserver word in javascript
var _var = ['foo1', 'foo2', 'foo3', 'foo4'];
// Declare a variable called prompt (actually not necessary normally)
var prompt;
// Declare a array called prompt_array to store the output
var prompt_array = [];
// Declare and give some example value to selection_array
var selection_array = ['foo2', 'foo3'];
// main program to solve the problem
for (i in _var) {
// Loop through all values in var
if ((typeof _var [i] !== undefined) &&
selection_array.indexOf(_var [i]) >= 0) {
// note that array.indexOf returns -1 if selection_array does not contain var [i]
prompt = _var[i]; // use this if you only want last var[i] satisifying the condition to be stored
prompt_array.push(_var[i]);// use this if you want to store all satisifying values of var[i]
}
}
// output for visualizing the result
document.getElementById('output').innerHTML += 'prompt = ' + prompt + '<br/>';
document.getElementById('output').innerHTML += 'prompt_array = ' + prompt_array.toString();
<div id="output">
</div>
You can ask me through commenting if you have a further problem on this :D.
Related
In the following code, the user is able to create variables utilizing the window object via an input type text element. I've written a function that console logs the name of the variable followed by the value of 0 in which the variable is initialized. This only occurs when the following key string literal, "-nr " precedes the desired name for the created variable.
The goal of this exercise is to increment any created variable value by 1 when the variable name is reentered into the input element. My attempt at doing so is by first writing the first function, varCreate to declare and initialize variables to 0, push them into an array, and console log the variable name followed by its value. The next function which I have a problem with (varPlus) is meant to add 1 to the value of each value when a particular name is entered into the input element however, it adds a few more than 1 even when I utilize a for loop to evaluate if the string literal value of the input element value property is equivalent to each element of the array varArray.
const _in = document.getElementById('in');
var varArray = [];
function varCreate(e) {
let _key = e.key;
if(_key === "Enter") {
if(_in.value.substring(0, 4) == "-nr ") {
window[_in.value.substring(4).replace(/\s/g, "_")] = 0;
varArray.push(_in.value.substring(4).replace(/\s/g, "_"));
console.log("var: " + varArray[varArray.length - 1] + "\nvalue: " + window[varArray[varArray.length - 1]]);
_in.value = "";
}
}
}
function varPlus(e1) {
let _key1 = e1.key;
if(_key1 === "Enter") {
checker = new RegExp(_in.value.replace(/\s/g, "_"), "gi");
for(var i = 0; i < varArray.length; i++) {
if(checker.test(varArray[i])) {
window[varArray[i]] += 1;
console.log("var: " + varArray[i] + "\nvalue: " + window[varArray[i]]);
}
}
delete window["checker"];
}
}
_in.addEventListener('keydown', varCreate);
_in.addEventListener('keydown', varPlus);
<input id='in' type='text' />
The end result when attempting to utilize varPlus is that it'll console log all variable names and values which somehow increment in value when it should only be console logging only the variable name which I'm trying to access via user input followed by its value. I would greatly appreciate it if anyone can shed some light on how I'm encountering these errors.
First of all it is really helpful if you try and make your code executable :)
Now for the user generated variables you could do something like this:
// DOM Elements
const input_variable = document.getElementById("input_variable");
const button_createVariable = document.getElementById("button_createVariable");
// Variables
let userVariables = {};
// Event listeners
window.addEventListener("keyup", event => {if(event.key == "Enter") parseVariable()});
button_createVariable.addEventListener("click", parseVariable);
function parseVariable() {
// Get the variable name and remove all spaces
let variableName = input_variable.value.substring(0, input_variable.value.indexOf("=")).replace(/\s+/g, '');
// Get the variable value and remove all spaces
let variableValue = input_variable.value.substring(input_variable.value.indexOf("=") + 1, input_variable.value.length).replace(/\s+/g, '');
// Add the variable to the object
userVariables[variableName] = variableValue;
// Clear the input
input_variable.value = "";
// Log the object into the console
console.log(userVariables);
}
<input id='input_variable' type='text'/><button id="button_createVariable">Create</button>
WARNING You of course still need to verify the user input. At this state it will accept everything as input. But now you can loop through the object and count up (or whatever) if already exists.
Oh yes btw, the syntax is simply: <name> = <value> eg. foo = 10.. unimportant detail :P
I’ve looked for solutions, but couldn’t find any that work.
I have a variable called onlyVideo.
"onlyVideo" the string gets passed into a function. I want to set the variable onlyVideo inside the function as something. How can I do that?
(There are a number of variables that could be called into the function, so I need it to work dynamically, not hard coded if statements.)
Edit: There’s probably a better way of doing what you’re attempting to do. I asked this early on in my JavaScript adventure. Check out how JavaScript objects work.
A simple intro:
// create JavaScript object
var obj = { "key1": 1 };
// assign - set "key2" to 2
obj.key2 = 2;
// read values
obj.key1 === 1;
obj.key2 === 2;
// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;
// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;
If it's a global variable then window[variableName]
or in your case window["onlyVideo"] should do the trick.
Javascript has an eval() function for such occasions:
function (varString) {
var myVar = eval(varString);
// .....
}
Edit: Sorry, I think I skimmed the question too quickly. This will only get you the variable, to set it you need
function SetTo5(varString) {
var newValue = 5;
eval(varString + " = " + newValue);
}
or if using a string:
function SetToString(varString) {
var newValue = "string";
eval(varString + " = " + "'" + newValue + "'");
}
But I imagine there is a more appropriate way to accomplish what you're looking for? I don't think eval() is something you really want to use unless there's a great reason for it. eval()
As far as eval vs. global variable solutions...
I think there are advantages to each but this is really a false dichotomy.
If you are paranoid of the global namespace just create a temporary namespace & use the same technique.
var tempNamespace = {};
var myString = "myVarProperty";
tempNamespace[myString] = 5;
Pretty sure you could then access as tempNamespace.myVarProperty (now 5), avoiding using window for storage. (The string could also be put directly into the brackets)
var myString = "echoHello";
window[myString] = function() {
alert("Hello!");
}
echoHello();
Say no to the evil eval. Example here: https://jsfiddle.net/Shaz/WmA8t/
You can do like this
var name = "foo";
var value = "Hello foos";
eval("var "+name+" = '"+value+"';");
alert(foo);
You can access the window object as an associative array and set it that way
window["onlyVideo"] = "TEST";
document.write(onlyVideo);
The window['variableName'] method ONLY works if the variable is defined in the global scope. The correct answer is "Refactor". If you can provide an "Object" context then a possible general solution exists, but there are some variables which no global function could resolve based on the scope of the variable.
(function(){
var findMe = 'no way';
})();
If you're trying to access the property of an object, you have to start with the scope of window and go through each property of the object until you get to the one you want. Assuming that a.b.c has been defined somewhere else in the script, you can use the following:
var values = window;
var str = 'a.b.c'.values.split('.');
for(var i=0; i < str.length; i++)
values = values[str[i]];
This will work for getting the property of any object, no matter how deep it is.
It can be done like this
(function(X, Y) {
// X is the local name of the 'class'
// Doo is default value if param X is empty
var X = (typeof X == 'string') ? X: 'Doo';
var Y = (typeof Y == 'string') ? Y: 'doo';
// this refers to the local X defined above
this[X] = function(doo) {
// object variable
this.doo = doo || 'doo it';
}
// prototypal inheritance for methods
// defined by another
this[X].prototype[Y] = function() {
return this.doo || 'doo';
};
// make X global
window[X] = this[X];
}('Dooa', 'dooa')); // give the names here
// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());
The following code makes it easy to refer to each of your DIVs and other HTML elements in JavaScript. This code should be included just before the tag, so that all of the HTML elements have been seen. It should be followed by your JavaScript code.
// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
{
thisid = els[i].id;
if (!thisid)
continue;
val=D.getElementById(thisid);
id[thisid]=val;
}
// Usage:
id.MyDIV.innerHTML="hello";
let me make it more clear
function changeStringToVariable(variable, value){
window[variable]=value
}
changeStringToVariable("name", "john doe");
console.log(name);
//this outputs: john doe
let file="newFile";
changeStringToVariable(file, "text file");
console.log(newFile);
//this outputs: text file
I’ve looked for solutions, but couldn’t find any that work.
I have a variable called onlyVideo.
"onlyVideo" the string gets passed into a function. I want to set the variable onlyVideo inside the function as something. How can I do that?
(There are a number of variables that could be called into the function, so I need it to work dynamically, not hard coded if statements.)
Edit: There’s probably a better way of doing what you’re attempting to do. I asked this early on in my JavaScript adventure. Check out how JavaScript objects work.
A simple intro:
// create JavaScript object
var obj = { "key1": 1 };
// assign - set "key2" to 2
obj.key2 = 2;
// read values
obj.key1 === 1;
obj.key2 === 2;
// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;
// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;
If it's a global variable then window[variableName]
or in your case window["onlyVideo"] should do the trick.
Javascript has an eval() function for such occasions:
function (varString) {
var myVar = eval(varString);
// .....
}
Edit: Sorry, I think I skimmed the question too quickly. This will only get you the variable, to set it you need
function SetTo5(varString) {
var newValue = 5;
eval(varString + " = " + newValue);
}
or if using a string:
function SetToString(varString) {
var newValue = "string";
eval(varString + " = " + "'" + newValue + "'");
}
But I imagine there is a more appropriate way to accomplish what you're looking for? I don't think eval() is something you really want to use unless there's a great reason for it. eval()
As far as eval vs. global variable solutions...
I think there are advantages to each but this is really a false dichotomy.
If you are paranoid of the global namespace just create a temporary namespace & use the same technique.
var tempNamespace = {};
var myString = "myVarProperty";
tempNamespace[myString] = 5;
Pretty sure you could then access as tempNamespace.myVarProperty (now 5), avoiding using window for storage. (The string could also be put directly into the brackets)
var myString = "echoHello";
window[myString] = function() {
alert("Hello!");
}
echoHello();
Say no to the evil eval. Example here: https://jsfiddle.net/Shaz/WmA8t/
You can do like this
var name = "foo";
var value = "Hello foos";
eval("var "+name+" = '"+value+"';");
alert(foo);
You can access the window object as an associative array and set it that way
window["onlyVideo"] = "TEST";
document.write(onlyVideo);
The window['variableName'] method ONLY works if the variable is defined in the global scope. The correct answer is "Refactor". If you can provide an "Object" context then a possible general solution exists, but there are some variables which no global function could resolve based on the scope of the variable.
(function(){
var findMe = 'no way';
})();
If you're trying to access the property of an object, you have to start with the scope of window and go through each property of the object until you get to the one you want. Assuming that a.b.c has been defined somewhere else in the script, you can use the following:
var values = window;
var str = 'a.b.c'.values.split('.');
for(var i=0; i < str.length; i++)
values = values[str[i]];
This will work for getting the property of any object, no matter how deep it is.
It can be done like this
(function(X, Y) {
// X is the local name of the 'class'
// Doo is default value if param X is empty
var X = (typeof X == 'string') ? X: 'Doo';
var Y = (typeof Y == 'string') ? Y: 'doo';
// this refers to the local X defined above
this[X] = function(doo) {
// object variable
this.doo = doo || 'doo it';
}
// prototypal inheritance for methods
// defined by another
this[X].prototype[Y] = function() {
return this.doo || 'doo';
};
// make X global
window[X] = this[X];
}('Dooa', 'dooa')); // give the names here
// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());
The following code makes it easy to refer to each of your DIVs and other HTML elements in JavaScript. This code should be included just before the tag, so that all of the HTML elements have been seen. It should be followed by your JavaScript code.
// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
{
thisid = els[i].id;
if (!thisid)
continue;
val=D.getElementById(thisid);
id[thisid]=val;
}
// Usage:
id.MyDIV.innerHTML="hello";
let me make it more clear
function changeStringToVariable(variable, value){
window[variable]=value
}
changeStringToVariable("name", "john doe");
console.log(name);
//this outputs: john doe
let file="newFile";
changeStringToVariable(file, "text file");
console.log(newFile);
//this outputs: text file
function checkData() {
var temp = 0;
var totalMarks = countMark(temp);
if (totalMarks != 100)
window.alert("Marks must total 100");
}
function countMark(mark) {
var totalMark = 0;
totalMark += parseInt(mark)
return totalMark;
}
function doAdd() {
var taskid = document.getElementById("taskid").value;
var taskname = document.getElementById("taskname").value;
var taskmark = document.getElementById("taskmark").value;
if (taskid.length === 0)
window.alert("Task Id cannot be empty!");
if (taskname.length === 0)
window.alert("Task name cannot be empty!");
if (taskmark.length === 0)
window.alert("Task Mark cannot be empty!");
else if (!markpattern.test(taskmark))
window.alert("Invalid data in mark field");
var marks = parseInt(document.getElementById("taskmark"));
if (marks < 0 || marks > 100)
window.alert("Marks out of range. Please re-enter");
countMark(marks);
}
My question is when i keep call the doAdd() function. my marks will keep adding . want to do like passing reference like in C++ . my function countMark(...) will keep adding .
after that, when my form submitted, my form will call the function checkData()
If my totalmark is not 100 . will prompt out the alert and error.
but my code is not working . I guess that my countMark function wrong somewhere
If I understand you correctly, you're looking for the equivalent of a static variable - something that gets initialized the first time the function is called, and keeps it's value for subsequent calls.
Take a look at this related question: https://stackoverflow.com/a/1535650/2444111
The top answer (by CMS) is talking about class-based static variables, which are not quite the same thing.
The second answer (by Pascal MARTIN) is what you're looking for. It takes advantage of the fact that JS functions are also objects, and stores the variable as a property of the function object. This is a better solution than using a global variable (or a property of window, which is what a global actually is)
There are several issues in your code and it's really hard to say what your intention was. But I will address what I found.
In the following piece of code you are requesting a DOM Element and try to parse it as an Integer. The result of that type convertion is always NaN. Maybe wanted to get the value attribute of your element, like you did before. (Also, don't request the same element multiple times. Request it once, save the result in a variable and use that variable from that on).
var marks = parseInt(document.getElementById("taskmark"));
if (marks < 0 || marks > 100)
window.alert("Marks out of range. Please re-enter");
countMark(marks);
Your function countMark is pretty useless, because it will always return whatever Number you pass to it (see comments in your code).
function countMark(mark) {
var totalMark = 0; //create a new variable with value 0
totalMark += parseInt(mark) //add "mark" to that variable
return totalMark; //return that variable => 0 + mark = mark (and if mark = NaN => 0 + mark = NaN)
}
Maybe you wanted to make totalMark a global variable, than you would need to define it outside of your function:
var totalMark = 0;
function countMark(mark) {
totalMark += parseInt(mark);
return totalMark;
}
Last but not least, lets analyse your function checkData:
function checkData() {
var temp = 0; //create a local variable with value 0
var totalMarks = countMark(temp); //pass 0 to countMark => return 0 => totalMarks = 0
if (totalMarks != 100) //always true since totalMarks is always 0
window.alert("Marks must total 100"); //will always alert
}
i've got an array, and i want to shuffle those according to a certain pattern
(i'm trying to make a rubics cube in javascript).
I want to assign value2 to value 1 and value 1 to value 3 and value 3 to value 2. I can do that within 4 lines of code, but is there a shorter way?
like:
temp = var3; //make temporary variable
(var3 = var2) = var1;//put var2 in var3 and var3 in var1
var1 = temp;//put var3/temp in var1
i know that it doesn't work this way, but do you guys know a way it does work?
that would be usefull when cycling 8 variables.
thanks,
Tempestas Ludi.
If you're dealing with more than 2 variables, it's always best to use an array, since arrays have built in functions you can use
var nums = [1,2,3]; // this is your array. it can have any length you want
// this is one line that does the magic
nums.push(nums.shift()); // to the left
nums.unshift(nums.pop()); // to the right
http://jsfiddle.net/wbKYY/2/
http://jsfiddle.net/wbKYY/4/
Anyway, about your comment. Seeing as the pointers which you will rotate aren't predetermined, and will vary, it's probably best to use a function.A function that will iterate through pointers that you define.
function rotateArr(arr,pointers,dir) {
var narr = arr; // create a local copy we can use it
var savevalue;
if (dir == 1) { // rotate to the right
savevalue = narr[pointers[pointers.length-1]]; // save the last value
for(var i=pointers.length-2;i>=0;i--) {
narr[pointers[i+1]] = narr[pointers[i]];
}
narr[pointers[0]] = savevalue; // set the first value
} else { // rotate to the left
savevalue = narr[pointers[0]]; // save the first value
for(var i=0;i<pointers.length-1;i++) {
narr[pointers[i]] = narr[pointers[i+1]];
}
narr[pointers[pointers.length-1]] = savevalue; // set the last value
}
return narr;
}
// arr is the array of faces
// pointers is the elements which you want to rotate (an array)
// dir is either 1 or -1
you can execute this function with
nums = rotateArr(nums,[pointers],[1,-1]);
// just some examples
nums = rotateArr(nums,[0,1,2,5],1);
nums = rotateArr(nums,[3,6,1,4],-1);
Here's a working example:
http://jsfiddle.net/w2jGr/
However if you prefer to use a prototype function that is just a method of an array, you can define a property and just access it from there.
Object.defineProperty(Object.prototype, "rotateArr", { value: function(pointers,dir) {
var savevalue;
if (dir == 1) { // rotate to the right
savevalue = this[pointers[pointers.length-1]]; // save the last value
for(var i=pointers.length-2;i>=0;i--) {
this[pointers[i+1]] = this[pointers[i]];
}
this[pointers[0]] = savevalue;
} else { // rotate to the left
savevalue = this[pointers[0]]; // save the last value
for(var i=0;i<pointers.length-1;i++) {
this[pointers[i]] = this[pointers[i+1]];
}
this[pointers[pointers.length-1]] = savevalue;
}
}, enumerable : false});
Modifying the prototype of an object is never recommended, but if you aren't going for clean code and want usability or readability, this works great as you can call the function with
nums.rotate([pointers],dir);
http://jsfiddle.net/w2jGr/1/
Why not put your values in an array, and just change the index pointer when you want to use different values?