How to get buttons to disable after a condition has been met? - javascript

From the code in my previous question, i now have a function "knapsack" that is supposed to disable the buttons when the total weight(tot_weight) is greater than or equal to the maximum weight("max_weight"). I need it to disable all the "add" buttons when the condition is met.(this will cause no more input to be accepted when max capacity is reached)
My code does not work correctly, it justs disable the last button after only selecting one item (i dont think it checks the condition).
arr_items = new Array();
knap = new Array();
let input = document.getElementById("userinput");
let input2 = document.getElementById("itemName");
let input3 = document.getElementById("itemWeight");
let input4 = document.getElementById("itemValue");
let ul = document.getElementById("list");
let ul2 = document.getElementById("knap")
let listCount = 0;
let myfunction2;
let knapsack;
let max_weight;
myfunction2 = () =>{
input.value = "";
}
let inputLength=() => input2.value.length;
let addValues = () =>{
inputs = {
name : input2.value,
weight : parseFloat(input3.value),
value : parseInt(input4.value)
}
arr_items.push(inputs);
console.log(arr_items);
createListElement();
myfunction2();
}
let createListElement = () => {
var li = document.createElement("li");
li.appendChild(document.createTextNode(input2.value));
ul.appendChild(li);
input2.value = "";
input3.value = "";
input4.value = "";
let btn = document.createElement("button");
btn.appendChild(document.createTextNode("Add"));
li.appendChild(btn);
btn.className = "butt";
btn.id = listCount;
btn.onclick = addTo;
listCount++; // increment the list count variable
console.log(input.value);
max_weight = input.value;
knapsack = (max_weight,knap)=>{
let tot_weight = 0;
for(i=0; i<knap.length;i++){
tot_weight = knap[i].weight + tot_weight;
}
console.log(tot_weight);
console.log(max_weight);
if (tot_weight >= max_weight){
btn.disabled = true;
}
}
}
function addTo(){
var li2 = document.createElement("li");
var id = parseInt(this.id); // retrieve the id of the button
li2.appendChild(document.createTextNode(arr_items[id].name));
ul2.appendChild(li2);
knap.push(arr_items[id]); //use the id of the button to select array to push to knap from the array item
console.log(knap);
knapsack(max_weight,knap);
}
let addListAfterClick = () =>{
if (inputLength() > 0) {
addValues();
}
}
<!DOCTYPE html>
<html>
<head>
<title>KnapSack</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>KnapSack</h1>
<div>
<input id="userinput" type="number" placeholder="Enter Capacity">
</div><br>
<div>
<p>Items Information:</p>
<input id="itemName" type="text" placeholder="enter item name">
<input id="itemWeight" type="number" placeholder="enter item weight(kg)">
<input id="itemValue" type="number" placeholder="enter item value">
<button onclick="addListAfterClick()" id="value">Enter</button>
</div>
<ul id="list">LIST OF 20 ITEMS TO CHOOSE FROM
</ul>
<ul id="knap"> LIST OF ITEMS IN KNAPSACK
</ul>
<div>
<button onclick="myFunction()" id="done">Done</button>
</div>
<p id="demo"></p>
<script type="text/javascript" src="script.js"></script>
<script src="jquery-3.2.1.min.js" ></script>
</body>
</html>

From your code max_weight is being reset every time the "Add" button is clicked, this might make the condition to disable the "Add" buttons behave abnormally.
To disable all the buttons, you have to get all the buttons you created with the ClassName you assigned to them. Here is the modification of your code
arr_items = new Array();
knap = new Array();
let input = document.getElementById("userinput");
let input2 = document.getElementById("itemName");
let input3 = document.getElementById("itemWeight");
let input4 = document.getElementById("itemValue");
let ul = document.getElementById("list");
let ul2 = document.getElementById("knap")
let listCount = 0;
let myfunction2;
let knapsack;
let max_weight;
let tot_weight = 0;
myfunction2 = () =>{
//input.value = ""; I had to comment this line out to avoid resetting max_weight value everytime the add button is click
// since we need to evaluate it everytime
}
let inputLength=() => input2.value.length;
let addValues = () =>{
inputs = {
name : input2.value,
weight : parseFloat(input3.value),
value : parseInt(input4.value)
}
arr_items.push(inputs);
console.log(arr_items);
createListElement();
myfunction2();
}
let createListElement = () => {
var li = document.createElement("li");
li.appendChild(document.createTextNode(input2.value));
ul.appendChild(li);
input2.value = "";
input3.value = "";
input4.value = "";
let btn = document.createElement("button");
btn.appendChild(document.createTextNode("Add"));
li.appendChild(btn);
btn.className = "butt";
btn.id = listCount;
btn.onclick = addTo;
listCount++; // increment the list count variable
console.log(input.value);
max_weight = input.value;
knapsack = (max_weight,knap)=>{
for(i=0; i<knap.length;i++){
tot_weight = knap[i].weight + tot_weight;
}
console.log(tot_weight);
console.log(max_weight);
if (tot_weight >= max_weight){
let buttons = document.getElementsByClassName("butt"); // get all the buttons
for( let button of buttons){
button.disabled = true; // disable all the buttons
}
}
}
}
function addTo(){
var li2 = document.createElement("li");
var id = parseInt(this.id); // retrieve the id of the button
li2.appendChild(document.createTextNode(arr_items[id].name));
ul2.appendChild(li2);
knap.push(arr_items[id]); //use the id of the button to select array to push to knap from the array item
console.log(knap);
knapsack(max_weight,knap);
}
let addListAfterClick = () =>{
if (inputLength() > 0) {
addValues();
}
}
<!DOCTYPE html>
<html>
<head>
<title>KnapSack</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>KnapSack</h1>
<div>
<input id="userinput" type="number" placeholder="Enter Capacity">
</div><br>
<div>
<p>Items Information:</p>
<input id="itemName" type="text" placeholder="enter item name">
<input id="itemWeight" type="number" placeholder="enter item weight(kg)">
<input id="itemValue" type="number" placeholder="enter item value">
<button onclick="addListAfterClick()" id="value">Enter</button>
</div>
<ul id="list">LIST OF 20 ITEMS TO CHOOSE FROM
</ul>
<ul id="knap"> LIST OF ITEMS IN KNAPSACK
</ul>
<div>
<button onclick="myFunction()" id="done">Done</button>
</div>
<p id="demo"></p>
<script type="text/javascript" src="script.js"></script>
<script src="jquery-3.2.1.min.js" ></script>
</body>
</html>
I think this should work as expected

The issue is that in createListElement() you are only disabling the button you just created:
let btn = document.createElement("button");
...
if (tot_weight >= max_weight){
btn.disabled = true;
}
What you want is for all buttons to be disabled, so you could do something like getting all buttons by className, and disabling them in a loop:
allButtons = document.getElementsByClassName( "butt" );
if (tot_weight >= max_weight){
for ( const button of allButtons ) {
button.disabled = true;
}
}
The conditional is definitely being checked every time. This should fix it.

Related

disable button if the input field is empty and enable if there is text

I am a new learner and I am facing a problem. I want to create a simple messaging app and I want that if there is no text inside the input field then the button should be disabled. Help me out.
Here is the code:
let sendMessage = document.getElementById("sendMessage");
sendMessage.addEventListener("click", () => {
let val = document.getElementById("val");
let p = document.createElement("p");
let pTxt = document.createTextNode(val.value);
p.appendChild(pTxt);
val.value = "";
let messages = document.getElementById("messages");
messages.appendChild(p);
if (val.value === "") {
sendMessage.disabled = true;
} else {
sendMessage.disabled = false;
}
});
<div id="messages"></div>
<input type="text" id="val" />
<button id="sendMessage">Send</button>
You should use input event to set disabled to false or true. Set disabled to true by default and after button was clicked.
let sendMessage = document.getElementById("sendMessage");
let input = document.getElementById("val");
sendMessage.addEventListener("click", () => {
let val = document.getElementById("val");
let p = document.createElement("p");
let pTxt = document.createTextNode(val.value);
p.appendChild(pTxt);
val.value = "";
let messages = document.getElementById("messages");
messages.appendChild(p);
sendMessage.disabled = true;
});
input.addEventListener("input", () => {
if(input.value.length > 0){
sendMessage.disabled = false;
} else {
sendMessage.disabled = true;
}
});
<body>
<div id="messages"></div>
<input type="text" id="val"/>
<button id="sendMessage" disabled>Send</button>
<script src="app.js" type="text/javascript"></script>
</body>
Simply create a disabled class for the button if you use custom button.
Then listen to the input change and toggle the class on button if the input have value.
With your code :
const button = document.getElementById('sendMessage');
const input = document.getElementById('message-input');
const messagesBox = document.getElementById('messages');
input.addEventListener('input', () => sendMessage.disabled = input.value === '');
button.addEventListener('click', () => {
let p = document.createElement('p');
let pTxt = document.createTextNode(input.value);
p.appendChild(pTxt);
messagesBox.appendChild(p);
});
<body>
<div id="messages"></div>
<input type="text" id="message-input" />
<button id="sendMessage" disabled >Send</button>
<script src="app.js" type="text/javascript"></script>
</body>
Set a keyup input handler for the input field and a click handler for the button. In the snippet event delegation is used.
document.addEventListener(`input`, handle);
document.addEventListener(`click`, handle);
function handle(evt) {
const isInput = evt.target.closest(`#val`);
const isBttn = evt.target.closest(`#sendMessage`);
if (isInput) {
document.querySelector(`#sendMessage`).disabled = !isInput.value.trim();
}
if (isBttn) {
isBttn.disabled = isBttn;
const inputField = document.querySelector(`#val`);
document.querySelector(`#messages`).insertAdjacentHTML(`beforeend`,
`<li>${inputField.value.trim()}</li>`);
inputField.value = ``;
inputField.focus();
}
}
<ul id="messages"></ul>
<input type="text" id="val" />
<button id="sendMessage" disabled>Send</button>

Getting an Uncaught TypeError: Cannot set property 'onclick' of null with <script> at the end

I've looked at previous questions like this and cannot find the answer to my problem. I am working in javascript creating a checkout screen and I have two onclicks for two different html files but when I go to the html file for both it says that the other onclick is null. I have tried window.load and moving the script to the bottom of the
var cart = [];
var search = document.getElementById("addItem");
let placement = 0;
var cartElement = document.getElementById("showCart");
var cartTotal = document.getElementById("totalCart");
search.onclick = function(e) {
var userInput = document.getElementById("query").value;
var cartHTML = "";
e.preventDefault();
placement = 0;
for (i = 0; i < menu.length; i++) {
if (menu[i][0].includes(userInput)) {
cart.push(menu[i]);
placement++;
}
}
if (placement == 0) {
alert("Menu option not included. Please try again.");
}
cart.forEach((item, Order) => {
var cartItem = document.createElement("span");
cartItem.textContent = item[0] + " (" + item[1] + ")";
cartHTML += cartItem.outerHTML;
});
cartElement.innerHTML = cartHTML;
}
window.onload = function() {
var checkout = document.getElementById("addCartButton");
checkout.onclick = function(event) {
cart.forEach()
var cartTotalHTML = "";
event.preventDefault();
cart.forEach(Item, Order => {
var totalInCart = 0;
var writeCart = document.createElement("span");
totalInCart += Order[1];
});
writeCart.textContent = cartTotal += item[1];
cartTotalHTML = writeCart.outerHTML;
cartTotal.innerHTML = cartTotalHTML;
console.log(cartTotal);
}
}
<h3>Search for items in the menu below to add to cart</h3>
<form id="searchMenu">
<input type="search" id="query" name="q" placeholder="Search Menu..."></inpuut>
<input type = "Submit" name= "search" id="addItem" ></input>
</form>
<h4>Your cart: </h4>
<div class="Cart">
<div id="showCart"></div>
</div>
<script src="Script.js"></script>
<h4>Cart</h4>
<button id='addCartButton' class="Cart">Add Cart</button>
<div class="ShowCart">
<div id="totalCart"></div>
</div>
<script src="Script.js"></script>

To-Do-List Delete All Function

How can I fix the function to delete all todoItems? My guess is that the for loops is not working right :\ I appreciate any help with my problem! I have only 1-month of experience with javascript.
How can I fix the function to delete all todoItems? My guess is that the for loops is not working right :\ I appreciate any help with my problem! I have only 1-month of experience with javascript.
function selectColorStatus(event){
let target = event.target;
target.classList.toggle('todoTextSelected');
}
function createToDoItem(userInputValue){
// To-Do Item Container
let todoItem = document.createElement("div");
todoItem.classList.add("row", "flx");
todoItem.onclick = selectColorStatus;
// Clear List
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function (){
for(let i = 0; i < todoItem; i++){
todoItem.remove();
}
}
// Inner Text
let todoText = document.createElement('div');
todoText.classList.add('grow');
todoText.innerText = userInputValue;
// Date
let CreateDate = document.createElement('div');
CreateDate.classList.add('date');
let date = new Date();
year = date.getFullYear();
month = date.getMonth();
day = date.getDay();
CreateDate.innerText = 'Created at ' + year + '-' + month + '-'+ day;
// Delete Button
let deleteBtn = document.createElement('div');
deleteBtn.classList.add('btnDelete');
deleteBtn.innerText = 'X';
deleteBtn.onclick = function(){
todoItem.remove();
}
todoItem.appendChild(todoText);
todoItem.appendChild(CreateDate)
todoItem.appendChild(deleteBtn);
let todoItemsContainer = document.getElementById('todoItemsContainer');
todoItemsContainer.appendChild(todoItem);
}
// Item Entry and Validation
function ToDoItemHandler(){
let userInput = document.getElementById('toDoEntry');
let userInputValue = userInput.value;
if(userInputValue == ''){
alert('Entry can not be empty!')
}else{
createToDoItem(userInputValue);
userInput.value = '';
}
}
// Add Item Button
let btnAddItem = document.getElementById('btnAddItem');
btnAddItem.onclick = ToDoItemHandler;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href = './style/style.css' rel='stylesheet'>
<title>To-Do-List</title>
</head>
<body>
<div id = 'container'>
<div id="toDoHeader">
<h1>To-Do List</h1>
<div id = 'toDoContent'>
<input type = 'text' id = 'toDoEntry' name = 'toDoEntry' placeholder = 'Add item here'>
<button type = 'button' id = 'btnAddItem' name = 'addToDoList'>Add</button>
<button type = 'button' id = 'btnDeleteItem' name = 'deleteList'>Delete All</button>
</div>
</div>
<div id="todoItemsContainer">
</div>
</div>
<script src = './js/app.js'></script>
</body>
</html>
Change your delete function to
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function (){
const items = document.querySelectorAll('.row') // select all todos
items.forEach(el => {
el.remove() // remove each one
})
}
function selectColorStatus(event) {
let target = event.target;
target.classList.toggle('todoTextSelected');
}
function createToDoItem(userInputValue) {
// To-Do Item Container
let todoItem = document.createElement("div");
todoItem.classList.add("row", "flx");
todoItem.onclick = selectColorStatus;
// Clear List
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function () {
const items = document.querySelectorAll('.row')
items.forEach(el => {
el.remove()
})
}
// Inner Text
let todoText = document.createElement('div');
todoText.classList.add('grow');
todoText.innerText = userInputValue;
// Date
let CreateDate = document.createElement('div');
CreateDate.classList.add('date');
let date = new Date();
year = date.getFullYear();
month = date.getMonth();
day = date.getDay();
CreateDate.innerText = 'Created at ' + year + '-' + month + '-' + day;
// Delete Button
let deleteBtn = document.createElement('div');
deleteBtn.classList.add('btnDelete');
deleteBtn.innerText = 'X';
deleteBtn.onclick = function () {
todoItem.remove();
}
todoItem.appendChild(todoText);
todoItem.appendChild(CreateDate)
todoItem.appendChild(deleteBtn);
let todoItemsContainer = document.getElementById('todoItemsContainer');
todoItemsContainer.appendChild(todoItem);
}
// Item Entry and Validation
function ToDoItemHandler() {
let userInput = document.getElementById('toDoEntry');
let userInputValue = userInput.value;
if (userInputValue == '') {
alert('Entry can not be empty!')
} else {
createToDoItem(userInputValue);
userInput.value = '';
}
}
// Add Item Button
let btnAddItem = document.getElementById('btnAddItem');
btnAddItem.onclick = ToDoItemHandler;
<div id = 'container'>
<div id="toDoHeader">
<h1>To-Do List</h1>
<div id = 'toDoContent'>
<input type ='text' id='toDoEntry' name ='toDoEntry' placeholder = 'Add item here'>
<button type ='button' id='btnAddItem' name ='addToDoList'>Add</button>
<button type ='button' id='btnDeleteItem' name ='deleteList'>Delete All</button>
</div>
</div>
<div id="todoItemsContainer">
</div>
</div>
simply do:
// Clear List
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function () {
document.getElementById('todoItemsContainer').innerHTML = ''
}

Adding an event listener to DOM elements pushed into an array

Apologies for the poorly-worded question. It's my first question here!
I am trying to make an application whereby one can log the scores of players from any game and see the results at the end of the game (see the code snippet below).
So far, I have managed to push players and their scores (initially empty arrays) into the main array and thereby presented these players in a list (see below):
HTML
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
JavaScript
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
This gives me a list with the players' names, inputs to enter scores and buttons to log the scores. So far, so good.
But...
I am just trying to get each button to work. As you can see above, I gave each submit button classes ("submitScoreBtn"). I'm at the stage where I want to make sure that my new buttons work. Here's my code so far:
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
for (var x = 0; x < submitScore.length; x++){
submitScore[x].addEventListener("click", () => {
alert("selected");
});
}
I initially was getting errors without adding a for loop. Now I don't get any errors, but I also don't get any alerts. I'm just not sure why these buttons do not work.
Please see the code snippet below.
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
for (var x = 0; x < submitScore.length; x++){
submitScore[x].addEventListener("click", () => {
alert("selected");
});
}
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
Being as you're dynamically creating the buttons, it might be easier to simply add the function to the button's onclick.
You can still access the event object from this click by sending it as a parameter, like:
<input type='submit' onclick='submitScoreClick(event)' class='submitScoreBtn'>
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' onclick='submitScoreClick(event)' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
function submitScoreClick (e) {
alert("selected");
};
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
At the point in time when this code is run:
for (var x = 0; x < players.length; x++){
submitScore[x].addEventListener("click", (event) => {
event.alert("selected");
});
}
players.length is equal to 0. So the code is essentially never executed.
remove the for loop and add this code
document.addEventListener('click', function (event) {
if ( event.target.classList.contains( 'submitScoreBtn' ) ) {
alert("selected");
}
}, false);
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push({
player: entered,
score: []
});
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i = 0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className = "each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
document.addEventListener('click', function(event) {
if (event.target.classList.contains('submitScoreBtn')) {
alert("selected");
}
}, false);
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
The easiest solution is to use variables and createElement just like you do with toAdd. This way each created entry will remember its own inputs (local variables to the function), and you can use for example the score input variable in the click handler without confusion of which number input belongs to which entry.
I removed the class for the inputs because it's not needed to select them anymore, but you can still add some for styling for example. If you want to add classes to select them all, be sure to run querySelectorAll each time, so that added elements are actually selected.
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
var addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
var createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " ";
var enterScore = document.createElement("input");
enterScore.type = 'number';
enterScore.placeholder = 'enter score';
var submitScore = document.createElement("input");
submitScore.type = 'submit';
submitScore.addEventListener("click", () => {
alert("selected score: " + enterScore.value);
});
newLi.appendChild(enterScore);
newLi.appendChild(submitScore);
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>

Element text not changing when passing selected textContent and new value to an update function

I'm creating a CRUD page where the user can add, delete and edit text, but I have an issue in updating the text after I select it for edit.
In editText function when I click the edit button the text that was added will pop up inside the input field. When I click on the update button (triggering the updateText function), I can see the text in console log but the corresponding html is not updated.
HTML
<div class="main">
<form>
<input type="text" placeholder="search">
</form>
<ul></ul>
<div>
<input class="add-text" type="text" placeholder="Add Text">
<button id="add">Add</button>
<button id="update">update</button>
</div>
</div>
Javascript
const inputsearch = document.querySelector('form input');
const addInputBtn = document.querySelector('#add');
const update = document.querySelector('#update');
addInputBtn.addEventListener('click', addtext);
function addtext(){
let li = document.createElement('li');
let inputadd = document.querySelector('.add-text');
let addedtext = inputadd.value;
let h1Tag = '<h1 id="text">'+addedtext+'</h1>';
let tags = h1Tag + '<button id="delete">Delete</button><button id="edit">Edit</button>';
if(addedtext == ''){
alert('please add some text');
return;
}else{
li.innerHTML = tags;
document.querySelector('ul').appendChild(li);
}
li.querySelectorAll('#delete')[0].addEventListener('click', deleteText);
li.querySelectorAll('#edit')[0].addEventListener('click', editText);
getlist(li, h1Tag);
inputadd.value = '';
}
function deleteText(e) {
e.target.parentNode.remove();
document.querySelector('.add-text').value = '';
}
function editText(e) {
let currentText = e.target.parentNode.firstChild.textContent;
let currentValue = document.querySelector('.add-text');
currentValue.value = currentText;
getupdate(currentText, currentValue);
}
function getupdate(currentText, currentValue) {
update.addEventListener('click', updateText);
function updateText() {
currentText = currentValue.value
console.log(currentText = currentValue.value);
}
}
function getlist(li, h1Tag) {
inputsearch.addEventListener('keyup', serchText);
function serchText(e) {
let typetext = e.target.value.toLowerCase();
if(h1Tag.toLowerCase().indexOf(typetext) != -1){
li.style.display = 'block';
}else{
li.style.display = 'none';
}
}
}
To solve the issue without changing your overall approach, your edit button click needs to get the corresponding element (not just its textContent) and pass it to your getupdate() function to be updated when your update button is clicked. Relatively minor changes to your current functions:
function editText(e) {
const currentText = e.target.parentNode.firstChild;
const currentValue = document.querySelector('.add-text');
currentValue.value = currentText.textContent;
getupdate(currentText, currentValue);
}
function getupdate(currentText, currentValue) {
update.addEventListener('click', updateText);
function updateText() {
currentText.textContent = currentValue.value;
}
}
There are some other issues with your code, particularly the creation of multiple elements with the same id (which is malformed and will likely become problematic as you add additional features). Following is a snippet that addresses that issue as well as simplifying some of your functions and fixing the search.
const search = document.querySelector('form input');
const input = document.querySelector('.add-text');
const container = document.querySelector('ul');
let items = null;
let currentItem = null;
const searchItems = (event) => {
if (items) {
const s = event.currentTarget.value.toLowerCase();
for (const item of items) {
if (item.firstChild.textContent.toLowerCase().indexOf(s) !== -1) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
}
}
};
const deleteItem = (event) => {
currentItem = null;
event.currentTarget.parentNode.remove();
};
const editItem = (event) => {
currentItem = event.currentTarget.parentNode.firstChild;
input.value = currentItem.textContent;
};
const updateItem = () => {
if (currentItem) {
currentItem.textContent = input.value;
}
};
const addItem = () => {
let val = input.value
if (val) {
const li = document.createElement('li');
let inner = '<h1 class="text">' + val + '</h1>';
inner += '<button class="delete">Delete</button>';
inner += '<button class="edit">Edit</button>';
li.innerHTML = inner;
container.appendChild(li);
val = '';
currentItem = li.firstChild;
items = document.querySelectorAll('li');
for (let del of document.querySelectorAll('.delete')) {
del.addEventListener('click', deleteItem);
}
for (let edit of document.querySelectorAll('.edit')) {
edit.addEventListener('click', editItem);
}
} else {
alert('please add some text');
return;
}
};
search.addEventListener('keyup', searchItems);
document.querySelector('#add').addEventListener('click', addItem);
document.querySelector('#update').addEventListener('click', updateItem);
<div class="main">
<form>
<input type="text" placeholder="Search">
</form>
<ul></ul>
<div>
<input class="add-text" type="text" placeholder="Add Text">
<button id="add">Add</button>
<button id="update">Update</button>
</div>
</div>

Categories