I am wondering how I would create a variable on the click of a button, so I could make a random name generator, like this:
<input class="varValue" placeholder="Name to be generated">
<button class="createVar></button>
<script>
var createVar = document.querySelector(".createVar");
var varValue = document.querySelector(".varValue");
var nameNumber = 0;
var getValue = function(){
varValue.value = //new var with ascending values or something;
nameNumber = nameNumber + 1;
};
createValue.addEventListener("click", getValue(), false");
//then some Math.random using, nameNumber, anyway I'll figure it out
</script>
So how would I make the variables on the click of the button?
Also no jQuery please.
The function getValue() [which I don't see declared, so it should be declared somewhere] is in charge of any new logic attached to that event in this case.
To create and do something with those variables simply do it right inside that function.
I believe you meant createVar.addEventListener() and not createValue
Related
I am trying to make a web tool that takes user imputed values as a list of objects and a number of objects to randomly choose and then will print out the number of objects chosen from the list at random when the button is clicked. However i have not been able to get anything to print. I have tried to call the variables both with qoutes and without them and i still haven't gotten the compute to print any results in the final read only textbox. I think the issue is somewhere in my script functions but i cant figure out where and i've spent hours looking up syntax and possible issues to no avail. Ive tried to work with inner.html without success and the current method (document.getById....) is copied from http://www.mauvecloud.net/randomchooser.html that works to randomly choose one thing and print the result.
<html>
<style></style>
<head>
<title>Random Chooser</title>
<script>
Array.protoype.chooseFromArray() = function(){
var chosenIndex = Math.floor(Math.random() * ValueArray.length);
var elementPicked = ValueArray["chosenIndex"];
ValueArray.splice("chosenIndex",1);
return elementPicked;
}
function chooseRandomly(){
var ValueArray = document.getElementById("valuelist").value.split("\n");
var numItems = document.getElementById("items").value;
var ReturnArray = [];
for(i=0; i < numItems; i++){
var element = ValueArray.chooseFromArray();
ReturnArray.push("element");
}
document.getElementById("result").value = ReturnArray.toString();
}
</script>
<body>
Enter some values, one on each line, then click the choose button to pick randomly.
<form action onsubmit="return false;">
<textarea id="valuelist" rows="15" cols="60"></textarea>
<br>
<br>
Randomly choose <input type="number" id="items" > items
<br>
<input type="button" value="Choose" onclick="chooseRandomly();return false">
<br>
<br>
<input id="result" type="text" size="80" value readonly="readonly">
<br>
<br>
</form>
</body>
</html>
You're confused on a few JavaScript syntax points. I won't bother correcting the non-idiomatic style, you should read more about that here on your own once you understand the changes outlined below.
First, here's the cleaned up and fixed version so we can take a look at it together:
Array.prototype.chooseFromArray = function() {
var chosenIndex = Math.floor(Math.random() * this.length);
var elementPicked = this[chosenIndex];
this.splice(chosenIndex, 1);
return elementPicked;
}
function chooseRandomly() {
var ValueArray = document.getElementById("valuelist").value.split("\n");
var numItems = document.getElementById("items").value;
var ReturnArray = [];
for (var i = 0; i < numItems; i++) {
var element = ValueArray.chooseFromArray();
ReturnArray.push(element);
}
document.getElementById("result").value = ReturnArray.toString();
}
window.chooseRandomly = chooseRandomly;
First thing's first, to reference a function from HTML on JSFiddle you'll need it to be defined on the window. You don't normally need to do that, so you can mostly ignore that point.
Generally, you have several syntax errors.
Defining a property on an object (prototypes are objects (MDN)) happens just like variable assignment, so you just write object.<property_name> = value. You were calling chooseFromArray then assigning to that call (which is just invalid syntax).
When creating functions for prototypes, this will usually reference the object calling the function. In this case, any array calling chooseFromArray will have itself bound to the this reference inside the prototype function.
When accessing properties through the indexer you just pass the string. If it's a variable, you don't surround it with strings. Ex:
var chosenIndex = 123;
var elementPicked = this["chosenIndex"];
// This is the same as this.elementPicked;
var elementPicked = this[chosenIndex];
// This is what you want as you're accessing the `123` property on `this`
The same goes for passing variables to functions. You just pass the variable. Anything inside of 's, ' ` 's and "s are string literals and will not reference any variables.
I was wondering if it was possible to create a new variable when a button is pressed. For example: if I have a variable named enemy1 and the button is pressed, Can a variable named enemy2 be created? I'm sorry if this seems like a silly question. I wanted to create a for loop where I can define a variable thats name changes depending on 'i'.
Probably best to use an Array (adding new values on click) or Object (adding new keys on click). I think you should use an Array, so here is an example:
const enemies = [];
class Enemy {
speak () {
return 'COME AT ME BRO!!!';
}
}
document.querySelector('#createEnemy').addEventListener('click', function(event) {
const enemy = new Enemy();
enemies.push(enemy);
console.log(enemies.length, 'enemies say', enemy.speak());
}, false);
<button id="createEnemy">Create Enemy</button>
You do not require dynamic variable, instead you need one variable that would contain dynamic size (dynamic number of enemies). Following is the code you need. Here you can see demo
<button id='createEnemy' onclick='addEnenemy()'>Add Enenmy</button>
<div id='enemiesContainer'> </div>
<script>
var enemies = [];
var enemyDiv = document.getElementById('enemiesContainer');
function addEnenemy() {
var newEnenmy = 'enemy'+(enemies.length+1);
enemies.push(newEnenmy);
//following will show it in your page
enemyDiv.innerHTML = enemyDiv.innerHTML + '<br/><label>'+newEnenmy+'</label>';
console.log(enemies); //shows in console
}
</script>
I need to pass a value from html and use it to find a var in my Js, so according to the value in theId on my html I could use the var in my js. How can I do that?
HTML
<input id="Waist" type="checkbox" onchange="getToWork(this.id)" >Waist
<script> tag on HTML
function getToWork(theId){
usedCheckBox(theId);
}
myJs.js
function usedCheckBox(theId){
var temp1 = theId.name; - will be undefined
var temp2 = Waist.name; - will work
}
var Waist = {name:"bob",age:"17"}
The problem with your code is, you are not using document.getElementById as below:
JS:
document.getElementById("Waist").addEventListener("change",function(evt){
getToWork(this.id);
})
function getToWork(theId){
usedCheckBox(theId);
}
function usedCheckBox(theId){
console.log(theId);
console.log(Waist);
var temp1 = document.getElementById("Waist").val; // will return Waist
var temp2 = Waist.val(); // generate error, don't know what you want
}
var Waist = "change today!"
Fiddle:
https://jsfiddle.net/xLvzah8w/1/
I understood your question now and for that you should create one parent object as shown:
function usedCheckBox(theId){
var temp1 = parent[theId].name; // will return bob
console.log(temp1);
var temp2 = parent.Waist.name; // will return bob
console.log(temp2);
}
var parent = {
Waist : {name:"bob",age:"17"}
}
The reason why your code doesn't work is because you are trying to access property of a string. 'theId' is a string with value 'Waist' where Waist is an object so error occurs.
Updated fiddle: https://jsfiddle.net/xLvzah8w/2/
The correct way to proceed with this is:
In place of var temp1 = theId.val();
Use document.getElementById(theId).value
When you do: theId.val(), it makes sense that it's undefined. Calling getToWork(this.id) is sending a string, not an HTML element. Therefore calling .val() on a string is undefined.
If you're trying to get the text value stored in the checkbox element that was pressed, you need to change to ...
function getToWork(arg) {
console.log(document.getElementById(arg).value);
}
<input id="Waist" type="checkbox" value="INPUT_BOX" onchange="getToWork(this.id)"> Waist
You should avoid using the onclick attribute and rather listen for the event "js side" (addEventListener/attachEvent).
In the context of those eventhandlers, this generally represents the element the event listener has been attached to:
document.getElementById("Waist").addEventListener("change",getToWork);
function getToWork(){
usedCheckBox(this);
}
function usedCheckBox(elem){
var value = elem.value ;
}
What I am trying to do is rewrite content on the page depending on which object I have selected. I have some objects like so:
function floorPlan(name,rev,sqft,bedrm,bthrm) {
this.name = name;
this.rev = rev;
this.sqft = sqft;
this.bedrm = bedrm;
this.bthrm = bthrm;
}
// 1BR Plans
var a1 = new floorPlan('A1',false,557,1,1);
var a2 = new floorPlan('A2',false,652,1,1);
var a3 = new floorPlan('A3',false,654,1,1);
var a4 = new floorPlan('A4',false,705,1,1);
var a5 = new floorPlan('A5',false,788,1,1);
// The Selected plan
var currentPlan = floorPlan.a1;
I am having the user control this via a .click() function in a menu:
$('.sideNav li').click(function() {
// Define the currentPlan
var current = $(this).attr('id');
var currentPlan = floorPlan.current;
});
The problem is that currentPlan keeps coming back as undefined and I have no idea why. Should I be defining currentPlan differently? I can't seem to find any resources to help me find the answer.
UPDATED:
I switched out a few parts per your suggestions:
// The Selected plan
var currentPlan = a1;
and....
// Define the currentPlan
var current = $(this).attr('id');
currentPlan = current;
However, everything is still returning undefined in the click function (not initially though).
First of all $('this') should be $(this)
Secondly you're trying to use a read ID from your LI as a variable name. That doesn't work. If you store your plans in an array you can use the ID to search in that array:
var plans=Array();
plans["a1"]=new floorPlan('A1',false,557,1,1);
plans["a2"]=new floorPlan('A2',false,652,1,1);
Then your jQuery code should be altered to this:
$('.sideNav li').click(function() {
// Define the currentPlan
var current = $(this).attr('id');
var currentPlan = plans[current];
alert(currentPlan);
});
I created a JSFiddle for this. Is this what you were looking for?
Use as floorPlan.currentPlan = a1;
instead of var currentPlan = floorPlan.a1;
Please create a plunker and will correct if any issue.
I spot two errors.
When you write var inside a function, that variable is only accessible with that function. Right now you are creating a new variable in your anonymous function that is "hiding" the global variable with the same name.
So, first remove the var keyword from the assignment in the anonymous function (the one you call on "click").
Secondly I think you mean to assign floorPlan[current].
The final line should read:
currentPlan = floorPlan[current];
I've heard a lot of rumblings about how "evil" or even "misunderstood" the eval function is, so I've decided to remove it from my code. The problem is I don't know what to replace it with.
Here's a quick rundown of my current code. I have a series of arrays (just 2 for the example below) declared at the beginning, and then based on a button click one of them gets loaded into a variable that is passed into a function.
Here's some basic HTML
<div class="button" data-name="button1">Button1</div>
<div class="button" data-name="button2">Button2</div>
and the JS (with jQuery)
var butName = null;
var eArray = null;
var button1Logo = ["..path/to/pic1.png","..path/to/pic2.png"];
var button2Logo = ["..path/to/pic3.png","..path/to/pic4.png"];
$(".button").mouseup(function(){
/*give a butName*/
butName = $(this).attr("data-name");
/*give the array from the button*/
eArray = eval(butName + "Logo");
});
Doing it this way assigns the array to the variable and not just a string that says "butnameLogo" which is why I used eval. But I'm looking to get away from that.
I know I can add a new attribute to the html and just retrieve that for the variable but I don't want to add more html when I can possibly do it with JS.
I've also tried making an object with strings loaded into it as seen in this answer: https://stackoverflow.com/a/16038097/1621380 but that resulted in just a string again, and not assigning a variable.
Wondering if you smart people have any better suggestions!
Replace
var button1Logo = ["..path/to/pic1.png","..path/to/pic2.png"];
var button2Logo = ["..path/to/pic3.png","..path/to/pic4.png"];
with an object, where the keys are your button names:
var buttonLogos = {
button1: ["..path/to/pic1.png","..path/to/pic2.png"],
button2: ["..path/to/pic3.png","..path/to/pic4.png"]
};
Then instead of the eval you can simply do
eArray = buttonLogos[butName]
(or buttonLogos[butName + "Logo"] if you want to call the keys button1Logo and button2Logo, but I can't really see the point now that they are nicely contained within a buttonLogos object)
Use an object:
var butName = null;
var buttonsLogos = {
button1: ["..path/to/pic1.png", "..path/to/pic2.png"],
button2: ["..path/to/pic3.png", "..path/to/pic4.png"]
};
$(".button").mouseup(function(){
/*give a butName*/
butName = $(this).attr("data-name");
/*give the array from the button*/
eArray = buttonsLogos[butName];
});
Consider making the data available as properties of an object, then you can control access to the object through scope and only need one (global?) variable for all such data.
If global scope is needed, then:
var dataObj = {
button1Logo: ["..path/to/pic1.png","..path/to/pic2.png"],
button2Logo: ["..path/to/pic3.png","..path/to/pic4.png"]
}
and later:
var eArray = dataObj[this.data-name + 'Logo'];
You may want to call the data object something more meaningful than dataObj though.
The best option is to define an object which holds all our button paths:
var buttons = {
"1": ["..path/to/pic1.png", "..path/to/pic2.png"],
"2": ["..path/to/pic3.png", "..path/to/pic4.png"]
};
$(".button").mouseup(function(){
/* give a butName */
var butName = $(this).attr("data-name");
/* give the array from the button */
var eArray = buttons[butName];
});
If your variables reside in the global scope, you could use the bracket notation to access them:
eArray = window[butName + "Logo"];
Note that this solution is not recommended. The first code sample is much cleaner and more maintainable.
Imagine a situation where you would have to move all the code into a 'deeper' context (!= global context). Nothing would work anymore.
You can do this very nicely with arrays and array indexes. You needn't find and use variable names at all. Even your data- attributes are unnecessary.
var eArray;
var buttonLogos = [
["..path/to/pic1.png","..path/to/pic2.png"],
["..path/to/pic3.png","..path/to/pic4.png"]
];
var buttons = $(".button").mouseup(function(){
var idx = buttons.index(this);
eArray = buttonLogos[idx];
});
The key line in this is buttons.index(this). This method call gets the position of the current element among all the elements matched by $(".button"). We then use this index to select the relevant element from the buttonLogos array.
You're taking a very circuitous route by using eval here.
You'd be much better off doing something like this:
var paths = {
button1: ["..path/to/pic1.png","..path/to/pic2.png"],
button2: ["..path/to/pic3.png","..path/to/pic4.png"]
};
$(".button").mouseup(function(){
/*give the array from the button*/
eArray = paths[$(this).attr("data-name")];
});
eval should only be used if you need to execute code (usually from a 3rd party source), and even that is rare. If you ever find yourself saying "i should use eval here", there's almost definitely a better alternative, and you should try and find it.