Create variable by html button and use it in outside function - javascript

Is there any way to make it work?
I´ve read that "let can be only available inside the scope it's declared, like in for loop, on the other hand "var" can be accessed outside the loop for example"
HTML:
let create = document.getElementById("create");
let add = document.getElementById("add");
let cart = document.getElementById("cart");
create.onclick = function(){
var foo = "foo";
console.log(foo);
}
add.onclick = function(){
cart.innerHTML += foo;
}
<!DOCTYPE html>
<html>
<body>
<button id="create">create</button>
<button id="add">Add to cart</button>
<h2 id="cart">Cart: </h2>
</body>
<script type="text/javascript" src="test.js"></script>
</html>

You can attach the click event for add inside the show click event handler function by passing the the variable:
let show = document.getElementById("show");
let add = document.getElementById("add");
let cart = document.getElementById("cart");
show.onclick = function(){
var foo = "foo";
console.log(foo);
add.addEventListener('click', function() { addToCart(foo); });
}
function addToCart(f){
cart.innerHTML += f;
}
<button id="show">Show</button>
<button id="add">Add to cart</button>
<h2 id="cart">Cart: </h2>

Related

Why is the done button not working properly?

Apparently I'm trying to create a todo list where I can ofcourse add and remove the tasks. Adding tasks works fine; however clicking on the Done Button works but doesn't do what I want it to do. Basically I have a Logical Error, but I don't know what to do to fix it.
The Code
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1>To-Do List</h1>
<form id="todoForm">
<input id="todoInput" />
<button type="button" onclick="todoList()">New</button>
<button type="button" onclick="">Retrieve</button>
</form>
<ol id="todoList"></ol>
<script>
var todos = []; //Problem is from here
var removed = [];
function todoList() {
var item = document.getElementById("todoInput").value;
todos.push(item);
var text = document.createTextNode(item);
var newItem = document.createElement("li");
newItem.innerHTML = item + ' <button id="Done">Done</button>';
document.getElementById("todoList").appendChild(newItem);
const donebtn = document.getElementById("Done");
donebtn.addEventListener("click", function() {
removetodo(newItem, item)
});
}
function removetodo(item, tasktext) {
const tasklist = document.getElementById("todoList");
tasklist.removeChild(item);
removed.push(tasktext);
}
</script>
</body>
</html>
Thing is, I tried finding solutions to it on Google and other places; yet, I still didnt know how to fix it. I dont want to just change the whole code so it could work. I specifically wanted it in the way I wrote it in
newItem.innerHTML = item + ' Done'; I changed this line the problem was that you are assigning the same id's to all done so I used a count variable which is at the start 0 when you run function if will 0 like done0 when the function run it will increase count++ will increase it next time it will be done1 so your code will work correctly
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1>To-Do List</h1>
<form id="todoForm">
<input id="todoInput" />
<button type="button" onclick="todoList()">New</button>
<button type="button" onclick="">Retrieve</button>
</form>
<ol id="todoList"></ol>
<script>
var todos = []; //Problem is from here
var removed = [];
let count = 0;
function todoList() {
var item = document.getElementById("todoInput").value;
todos.push(item);
var text = document.createTextNode(item);
var newItem = document.createElement("li");
newItem.innerHTML = item + ' <button id="Done'+count+'">Done</button>';
document.getElementById("todoList").appendChild(newItem);
const donebtn = document.getElementById("Done"+count);
donebtn.addEventListener("click", function(){
removetodo(newItem, item)
});
count++;
}
function removetodo(item, tasktext) {
const tasklist = document.getElementById("todoList");
tasklist.removeChild(item);
removed.push(tasktext);
}
</script>
</body>
</html>
one more suggestion
newItem.innerHTML = item + ' <button id="Done'+count+'">Done</button>';
document.getElementById("todoList").appendChild(newItem);
const donebtn = document.getElementById("Done"+count);
donebtn.addEventListener("click", function(){
here in your code const donebtn = document.getElementById("Done"+count); you don't need this line just donebtn.addEventListener("click", function(){ here insted of donebtn you can use newItem.addEventListener and then append it
document.getElementById("todoList").appendChild(newItem); at the last use this.
newItem.innerHTML = item + ' <button id="Done'+count+'">Done</button>';
newItem.addEventListener("click", function(){}
document.getElementById("todoList").appendChild(newItem);
like this
This code will only run when your function is called.
const donebtn = document.getElementById("Done");
donebtn.addEventListener("click", function() {
removetodo(newItem, item)
});
you should put it outside the functions to attach the listener.
The first issue with the code is that when you remove the task from the list, it's not actually removing it from the todos array. To fix this, you can add the following line after removing the task from the list:
todos.splice(todos.indexOf(tasktext), 1);
The second issue is that you are using the same id for all the "Done" <button> elements, in the HTML markup, IDs should be unique. So when you use document.getElementById("Done"), it always returns the first element with that id.
To fix this issue, you can use a class instead of an id and query for all elements with that class and attach an event listener to each button individually.
Updated code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1>To-Do List</h1>
<form id="todoForm">
<input id="todoInput" />
<button type="button" onclick="todoList()">New</button>
<button type="button" onclick="">Retrieve</button>
</form>
<ol id="todoList"></ol>
<script>
var todos = [];
var removed = [];
function todoList() {
let item = document.getElementById("todoInput").value;
todos.push(item);
let text = document.createTextNode(item);
let newItem = document.createElement("li");
newItem.innerHTML = item + ' <button class="doneBtn">Done</button>';
document.getElementById("todoList").appendChild(newItem);
const donebtn = newItem.getElementsByClassName("doneBtn")[0];
donebtn.addEventListener("click", function() {
removetodo(newItem, item);
});
}
function removetodo(item, tasktext) {
const tasklist = document.getElementById("todoList");
tasklist.removeChild(item);
removed.push(tasktext);
todos.splice(todos.indexOf(tasktext), 1);
}
</script>
</body>
</html>
Each time a new task is added, all the "Done" buttons have the same id, which is not allowed in HTML as id values must be unique within a page. This means that only the first "Done" button will respond to the click event, and all the others will be ignored.
One way you can try is to store the task text in a data attribute of the "Done" button, and use it in the removetodo function to identify the task to remove like so ...
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1>To-Do List</h1>
<form id="todoForm">
<input id="todoInput" />
<button type="button" onclick="todoList()">New</button>
<button type="button" onclick="">Retrieve</button>
</form>
<ol id="todoList"></ol>
<script>
var todos = [];
var removed = [];
function todoList() {
var item = document.getElementById("todoInput").value;
todos.push(item);
var text = document.createTextNode(item);
var newItem = document.createElement("li");
newItem.innerHTML = item + ' <button class="Done">Done</button>';
document.getElementById("todoList").appendChild(newItem);
const donebtn = newItem.getElementsByClassName("Done")[0];
donebtn.addEventListener("click", function() {
removetodo(newItem, item)
});
donebtn.setAttribute("data-task", item);
}
function removetodo(item, tasktext) {
const tasklist = document.getElementById("todoList");
tasklist.removeChild(item);
removed.push(tasktext);
}
</script>
</body>

How to set a <div> tag text value from Google Apps Script with JavaScript?

How are the elements foo and bar set to the values for their corresponding variables?
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function sendFoo()
{
var foo = document.getElementById("foo").value;
google.script.run.setFoo(foo);
var bar = google.script.run.getBar();
document.getElementById("foo").value = '';
document.getElementById("bar").childNodes[0].textContent = "put variable here..";
}
</script>
</head>
<body>
foo is:<input type="text" id="foo" />
<input type="button" value="sendFoo" onclick="sendFoo()" /> <br> <br> <br>
bar is: <div id="bar">Change only me<div>but not me</div>
</body>
</html>
code:
const SPREADSHEET_ID = "1L3Sd-J780mQtb7JYsmJzInI1kMdrQA8GbLspQJ5eVW4";
const SPREADSHEET_NAME = "data";
function setFoo(foo) {
// Logger.log("setFoo..");
// Logger.log(foo);
}
function getBar() {
// Logger.log("getBar..");
return "baz";
}
function getUrl() {
// Logger.log("getUrl..");
var url = ScriptApp.getService().getUrl();
return url;
}
function doGet(e) {
// Logger.log("doGet..");
var htmlOutput = HtmlService.createTemplateFromFile('FooBarBaz');
htmlOutput.url = getUrl();
return htmlOutput.evaluate();
}
Server side logs show foo and bar values when uncommented. However, there seems no output from console.log("some text"); from within the function defined on the HTML page.
If you are trying to get the response of the google script function, then you will have to call that with success handler.
google.script.run.getBar() should be updated as:
var bar = '';
google.script.run.withSuccessHandler((response)=>{
bar = response;
console.log(response); // prints 'baz' on console.
}).getBar();
You can use this value to assign to the div or perform some other operations.
function sendFoo()
{
var foo = document.getElementById("foo").value;
google.script.run.setFoo(foo);
google.script.run
.withSuccessHandler((s) => {
document.getElementById("bar").innerHTML = s;
})
.getBar();
document.getElementById("foo").value = '';
document.getElementById("bar").childNodes[0].textContent = "put variable here..";
}
Just including this as a more full answer:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
var foo = "";
var bar = "";
function sendFoo()
{
consoleLogger();
foo = document.getElementById("foo").value;
google.script.run.setFoo(foo);
document.getElementById("fooVal").textContent = foo;
foo = "";
document.getElementById("foo").value = foo;
bar = google.script.run
.withSuccessHandler((success) => {
document.getElementById("bar").innerHTML = success;
})
.getBar();
document.getElementById("bar").textContent = bar;
consoleLogger();
}
function consoleLogger()
{
console.log(foo);
console.log(bar);
}
</script>
</head>
<body>
foo is:<input type="text" id="foo" />
<input type="button" value="sendFoo" onclick="sendFoo()" /> <br> <br> <br> <br> <br> <br> <br>
foo entered: <div id="fooVal"></div>
bar is: <div id="bar"></div>
</body>
</html>
does a bit more logging, shows the foo entered, and bar value from server side.
Ideally, would switch to the # query selector notation rather than using id.

can't change parent element properly in javascript

I have two div elements, in the first one I put three buttons. here is the code
it works properly but the problem is in reset button (it should move all the buttons to start div) when I press it just moves 2 elements back to the starting div. what can be a problem?
function move(element){
let newParent = document.querySelector('#favourites');
newParent.append(element);
}
function reset(){
let startingDiv = document.querySelector('#startingArea');
let favouritesDiv = document.querySelector("#favourites");
var children = favouritesDiv.children;
for(var i=0;i<children.length;i++){
startingDiv.append(children[i]);
}
}
<html>
<head>
<script src="script.js"></script>
</head>
<body>
<h1>Click on your favourite wrestler<h1>
<div id="startingArea">
<button onclick='move(this)' id="cena1">John Cena</button>
<button onclick='move(this)' id="cena2">Jooohn Ceenna</button>
<button onclick='move(this)' id="cena3">JOoOoOOoooOooOOooOohn CeeeeeeEEEnaaaaaaa</button>
</div>
<h3>Your Favourite Wrestlers</h3>
<div id="favourites">
</div>
<br><br><br>
<button onclick="reset()">reset</button>
</body>
</html>
You can use the following code for the reset function and it should work:
function reset(){
let startingDiv = document.querySelector('#startingArea');
let favouritesDiv = document.querySelector("#favourites");
while(favouritesDiv.firstChild) {
startingDiv.append(favouritesDiv.firstChild);
}
}
You need to convert the HTMLCollection you get from the "children" property into a standard array and it works:
var starter = document.querySelector('#startingArea');
var childrenCollection = document.querySelector("#favourites").children;
var children = Array.prototype.slice.call(childrenCollection);
for(var i=0;i<children.length;i++){
starter.append(children[i]);
}
In simple way you can do this way.
function reset() {
let startingDiv = document.querySelector('#startingArea');
let favouritesDiv = document.querySelector("#favourites");
startingDiv.innerHTML = favouritesDiv.innerHTML;
favouritesDiv.innerHTML = "";
}

Trying to set a move in tic tac toe game, but I keep getting undefined when I call back the function

I'm not sure what I'm doing wrong. I'm calling my function with addEventListener down at the bottom, but for some reason my setMove function is giving me undefined. I'm trying to put a 'X' or an 'O' on one of the buttons when clicked, and the way I'm doing that is setting my variable buttonClicked which will give me the DOM object, then I iterate through the object and that's where I get stuck. I'm not sure what to do after that. I'm a beginner in JavaScript, so please take it easy on me. Thank you in advance!!! :)
HTML:
<html>
<head>
<title>Tic Tac Toe</title>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div id="wrap">
<div id="board">
<h2>Tic Tac Toe</h2>
<div>
<button class="btn"></button>
<button class="btn"></button>
<button class="btn"></button>
</div>
<div>
<button class="btn"></button>
<button class="btn"></button>
<button class="btn"></button>
</div>
<div>
<button class="btn"></button>
<button class="btn"></button>
<button class="btn"></button>
</div>
</div>
<div id="gameOutput"></div>
</div>
</body>
</html>
JavaScript:
var players = ['X', 'O'];
var currentMove = 0;
var gameOver = false;
var output = document.querySelector('#gameOutput');
var buttonClicked = document.querySelectorAll('#board .btn');
output.innerText = "Game is ready. " + players[currentMove] + " Turn.";
// sets X or O
var setMove = function (move, mark) {
for (var i = 0; i < move.length; i++) {
move[i].innertText = mark;
}
};
//some code
var buttonClickHandler = function() {
//some more code
if (valid(buttonClicked) === true) {
this.style.backgroundColor = '#0D771A';
console.log(setMove(buttonClicked, players[currentMove]));
} else if (valid(button) === false) {
output.innerText = "That is not a valid move :(";
};
//some more code
});
for (var i = 0;i < buttonClicked.length; i++) {
buttonClicked[i].addEventListener('click', buttonClickHandler);
}
You have an extra bracket after defining the buttonClickHandler function.
Besides, you are using a function valid that is not defined.. Please add it to the question if it's there or define it yourself and try again.
var buttonClickHandler = function() {
//some more code
if (valid(buttonClicked) === true) {
this.style.backgroundColor = '#0D771A';
console.log(setMove(buttonClicked, players[currentMove]));
} else if (valid(button) === false) {
output.innerText = "That is not a valid move :(";
} // <<<<<<<<<<<<<<<<<< removing semi-colon
//some more code
}; // <<<<<<<<<<<<<<< removing extra bracket

Buttons controlling functions in javascripts

I have been making simple Javascript programs that I will run with different websites for my friends, and I have been trying to make a domination style (call of duty gamemode) program using buttons. I have looked at a website and have tried using the set intervals for it but I can't figure out how to make the buttons access the script.
Here is my code:
<!DOCTYPE html>
<html>
<body>
<p id = "blue"></p>
<p id = "red"></p>
<button onclick="StartA()">Start for Red</button>
<button onclick="StopA()">Stop for red</button>
<button onclick="StartB()">Start for Blue</button>
<button onclick="StopB()">Stop for Blue</button>
<script>
var startRed;
var startBlue;
var r=1;
var b=1;
var startA = function(){
var startRed = setInterval(function(){redscore++};,3000)
};
var startB = function(){
var startBlue = setInterval(function(){bluescore++};,3000)
};
var StopA = function(){
clearInterval(startRed);
};
var StopB = function() {
clearInterval(startBlue);
};
document.getElementById("blue").innerHTML=bluescore;
document.getElementById("red").innerHTML=redscore;
</script>
</body>
</html>
JavaScript is case sensitive. You are not consistent with case. Traditionally, JavaScript functions and variables start with a lower case letter and are camel cased.
You were reinitializing variables in functions that were already initialized in the global scope.
You weren't updating the ui with each score change, just at the start.
Below is updated code that should run as you intend. It might be worth while to turn your score keepers into a class, since they are redundant.
Updated Html
<p id="blue"></p>
<p id="red"></p>
<button onclick="startA()">Start for Red</button>
<button onclick="stopA()">Stop for red</button>
<button onclick="startB()">Start for Blue</button>
<button onclick="stopB()">Stop for Blue</button>
Updated javaScript
var startRed;
var startBlue;
var bluescore = 1;
var redscore = 1;
function startA() {
stopA();
startRed = setInterval(function () {
redscore++;
updateUI();
}, 3000)
};
function startB() {
stopB();
startBlue = setInterval(function () {
bluescore++;
updateUI();
}, 3000)
};
function stopA() {
clearInterval(startRed);
};
function stopB() {
clearInterval(startBlue);
};
function updateUI() {
document.getElementById("blue").innerHTML = bluescore;
document.getElementById("red").innerHTML = redscore;
}
updateUI();
jsFiddle
The following code is what you're looking for. The changes are:
Function names now match (startA() => StartA(), startB() => StartB(), etc.)
The <p> elements are updated within the interval (otherwise, they never update)
Remove local vars from within functions
You can view a jsfiddle here: http://jsfiddle.net/5tcNb/
<body>
<script>
var startRed, startBlue;
var redscore = 0, bluescore = 0;
var r = 1, b = 1;
function StartA() {
startRed = setInterval(function() {
redscore++;
document.getElementById("red").innerHTML = redscore;
}, 3000);
};
function StartB() {
startBlue = setInterval(function() {
bluescore++;
document.getElementById("blue").innerHTML = bluescore;
}, 3000);
};
function StopA() {
clearInterval(startRed);
};
function StopB() {
clearInterval(startBlue);
};
</script>
<p id="blue">0</p>
<p id="red">0</p>
<button onclick="StartA()">Start for Red</button>
<button onclick="StopA()">Stop for red</button>
<button onclick="StartB()">Start for Blue</button>
<button onclick="StopB()">Stop for Blue</button>
</body>

Categories