I am learning javaScript. I have created a simple app, that when I click the button every time I want to increase the value.
let btn = document.querySelector(".btn");
btn.addEventListener("click", () => {
addCart();
});
function addCart() {
let btnn = (document.querySelector(".cart span").textContent = 1);
}
<ul class="cart">
cart
<span>(0)</span>
</ul>
<input type="button" value="click" class="btn" />
Add a count variable and increment it by one on every click:
let btn = document.querySelector(".btn");
let count = 0;
btn.addEventListener("click", () => {
addCart();
});
function addCart() {
count++;
document.querySelector(".cart span").textContent = `(${count})`;
}
<ul class="cart">
cart
<span>(0)</span>
</ul>
<input type="button" value="click" class="btn" />
Related
I am trying to add the elements of a list called "taskList" made up of values I get from the input elements.
Can anyone please help me, I don't understand why the elements from the list are not showing.
var taskList = [];
var input = document.getElementById('takeInput');
var button = document.getElementById('addInput');
button.onclick = function(){
var nHTML = '';
var userEnteredText = input.value;
taskList.push(userEnteredText);
taskList.forEach(function(task){
nHTML += '<li>'+task+'</li>';
});
document.getElementsByClassName('taskLists').innerHTML = '<ul>' + nHTML + '</ul>';
}
<div class="wrapper">
<header>To-Do List</header>
<div class="taskAdder">
<input id="takeInput" type="text" placeholder="Add your new To-Do">
<button id="addInput" class="button" type="button" >➕</button>
</div>
<div class="taskLists">
</div>
<div class="footer">
<span> You have <span class="pendingTasks"></span> tasks left </span>
<button type="button" class="button">Clear All</button>
</div>
</div>
I tried checking several times but nothing is updating in the HTML document
You shouldn't append to innerHTML, instead, use createElement to make the li, then set innerHTML of that new element to input.value and use appendChild to append it to the list
var input = document.getElementById('takeInput');
var button = document.getElementById('addInput');
var tlist = document.getElementsByClassName('taskLists')[0];
button.onclick = function(){
let e = document.createElement('li');
e.innerHTML = input.value
tlist.appendChild(e)
// Optionally, clear the input field to prevent double adding the same task
input.value = '';
}
<div class="wrapper">
<header>To-Do List</header>
<div class="taskAdder">
<input id="takeInput" type="text" placeholder="Add your new To-Do">
<button id="addInput" class="button" type="button" >➕</button>
</div>
<div class="taskLists">
</div>
<div class="footer">
<span> You have <span class="pendingTasks"></span> tasks left </span>
<button type="button" class="button">Clear All</button>
</div>
</div>
The main mistake was using .getElementsByClassName like it was one element only and not a list (don't ignore the s in elements!).
Anyway I slightly refactored your code to have better strategies for each of its goals and implemented also the logic for clearing the tasks list.
var taskList = [];
var input = document.getElementById('takeInput');
var buttonAdd = document.getElementById('addInput');
var buttonClear = document.getElementById('clearInput');
var tasksList = document.getElementById('tasksList');
buttonAdd.addEventListener('click', (event)=>{
addTask(input.value);
});
buttonClear.addEventListener('click', (event)=>{
tasksList = [];
document.querySelector('#tasksList ul').remove();
});
function addTask(value){
if(taskList.length == 0){
document.getElementById('tasksList').append( document.createElement('ul') );
}
taskList.push(value);
const newLI = document.createElement('li');
newLI.innerText = value;
document.querySelector('#tasksList ul').append(newLI);
}
<body>
<div class="wrapper">
<header>To-Do List</header>
<div class="taskAdder">
<input id="takeInput" type="text" placeholder="Add your new To-Do">
<button id="addInput" class="button" type="button">➕</button>
</div>
<div id="tasksList">
</div>
<div class="footer">
<span> You have <span class="pendingTasks"></span> tasks left </span>
<button id="clearInput" type="button" class="button">Clear All</button>
</div>
</div>
</body>
you just needed to use an ID on the tasklist.
getElementsByClassName needs an index, making your question a dupe of What do querySelectorAll and getElementsBy* methods return?:
document.getElementsByClassName('taskLists')[0].innerHTML
That said, here is a full version using recommended eventListener and IDs where relevant.
let tasks = [];
const taskList = document.getElementById('taskLists')
const input = document.getElementById('takeInput');
const add = document.getElementById('addInput');
const pendingTasks = document.getElementById('pendingTasks');
const clear = document.getElementById('clear');
const showTasks = () => {
taskList.innerHTML = `<ul>${tasks.map(task => `<li>${task}</li>`).join('')}</ul>`;
pendingTasks.textContent = `${tasks.length} task${tasks.length != 1 ? "s" : ""}`;
};
add.addEventListener('click', () => {
var userEnteredText = input.value;
tasks.push(userEnteredText);
showTasks();
});
clear.addEventListener('click', () => {
tasks = [];
showTasks();
});
taskList.addEventListener('click', (e) => {
const tgt = e.target.closest('li');
if (!tgt) return; // not a task
const task = tgt.textContent;
tgt.remove()
tasks = tasks.filter(currentTask => currentTask != task); // remove from list
showTasks()
});
showTasks(); //init
<div class="wrapper">
<header>To-Do List</header>
<div class="taskAdder">
<input id="takeInput" type="text" placeholder="Add your new To-Do">
<button id="addInput" class="button" type="button">➕</button>
</div>
<div id="taskLists"></div>
<div class="footer">
<span> You have <span id="pendingTasks"></span> left </span>
<button type="button" id="clear">Clear All</button>
</div>
</div>
I found this snippet to add additional fields to a form. Works great. If you may, please let me know how I can have the added fields start at 2 while also maintaining the option to remove it. While i = 2 does work, I have not figured out what's needed for the option to add/remove said fields accordingly. Thank you for your time.
$(document).ready(function() {
var i = 1;
$('#add').click(function() {
if (i <= 7) {
$('#dynamic_field').append('<div class="add-row" id="row' + i + '"><label" for="number_' + i + '">Number ' + i + '</label><input type="text" name="number_' + i + '" value=""></div>')
i++;
$('.btn-remove').removeClass('hidden');
}
});
$(document).on('click', '.btn-remove', function() {
var button_id = $(this).attr("id");
i--;
$('#row' + $('#dynamic_field div').length).remove();
if (i<=1) {
$('.btn-remove').addClass('hidden');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="add" class="btn-add">Add Another Number</button> <button type="button" class="btn-remove hidden">Remove last</button>
<div id="dynamic_field"></div>
Your code is being made unnecessarily complicated by the use of id attributes which you generate at runtime.
You can completely avoid the need to do this by using the same content in each row, which you can store in a template element. Note that this template content uses no id, but the same class instead, and also that the label wraps the input so no for attribute is required.
You can then simply get the number of existing rows in the DOM to calculate the next number to display. Also, as the 'remove' button only targets the last row you can select it directly with .row:last.
Here's a working example with all these changes implemented:
jQuery($ => {
let maxRows = 7;
let rowTemplate = $('#row-template').html();
let $container = $('#dynamic_field');
$('#add').on('click', () => {
let rowCount = $('.row').length;
if (rowCount >= maxRows)
return;
let $row = $(rowTemplate).appendTo($container);
$row.find('span').text(rowCount += 2);
$('.btn-remove').removeClass('hidden');
});
$(document).on('click', '.btn-remove', () => $('.row:last').remove());
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="add" class="btn-add">Add Another Number</button>
<button type="button" class="btn-remove hidden">Remove last</button>
<div id="dynamic_field"></div>
<template id="row-template">
<div class="row">
<label>
Number <span></span>
<input type="text" name="number[]" value="" />
</label>
</div>
</template>
You do not need to keep a count yourself
$(function() {
const $container = $("#dynamic_field");
let count = $container.children().length;
$('.btn-remove').toggle(count > 1);
$('#add').click(function() {
let count = $container.children().length;
if (count < 7) {
$('#dynamic_field').append(`<div class="add-row" id="row$(count)"><label" for="number_${count}">Number ${count+1}</label><input type="text" name="number_${count}" value=""></div>`);
count++;
}
$('.btn-remove').toggle(count > 0);
});
$(document).on('click', '.btn-remove', function() {
const $children = $container.children();
$children.last().remove();
let count = $children.length;
console.log(count)
$(this).toggle(count > 1);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="add" class="btn-add">Add Another Number</button> <button type="button" class="btn-remove hidden">Remove last</button>
<div id="dynamic_field"></div>
Also You could CLONE an existing row
$(function() {
const $container = $("#dynamic_field");
const getCount = () => $container.find(".add-row").length;
$('.btn-remove').toggle(getCount() > 1);
$('#add').click(function() {
let count = getCount();
if (count < 7) {
const $cloneDiv = $container.children().first().clone().appendTo($container);
$cloneDiv.find("input").val("").attr("name",`number${count+1}`);
$cloneDiv.find("label").text(`Number ${count+1}`);
}
$('.btn-remove').toggle(count > 0);
});
$(document).on('click', '.btn-remove', function() {
$container.find(".add-row").last().remove();
let count = getCount()
console.log(count)
$(this).toggle(count > 1);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="add" class="btn-add">Add Another Number</button> <button type="button" class="btn-remove hidden">Remove last</button>
<div id="dynamic_field">
<div class="add-row" id="1">
<label for="number_1">Number 1</label><input type="text " name="number_1 " value="" />
</div>
</div>
So I have 30 buttons (id="button1" to "button30"):
<button type="button" class="buttons" id="button1">1</button>
and I set up some JS so that the button changes colors on every click:
let index = 0;
const colors = ['green', 'red', '#405cf5'];
let btn = document.querySelector('#button1');
document.querySelector('#button1').addEventListener('click', function(){
btn.style.backgroundColor = colors[index];
index = index >= colors.length - 1 ? 0 : index + 1;
})
I'm not sure how to set this up so that all my buttons do this without copy and pasting and manually typing out the ID each time.
Delegate, please.
Here I find the closest static container of the buttons (if no container use document) and any click inside the container is checked against the thing we want clicked - you can test against any valid selector.
let index = 0;
const colors = ['green', 'red', '#405cf5'];
document.getElementById("buttonContainer").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.matches("button.buttons")) {
tgt.style.backgroundColor = colors[index++ % colors.length];
}
})
<div id="buttonContainer">
<button type="button" class="buttons" id="button1">1</button>
<button type="button" class="buttons" id="button2">2</button>
<button type="button" class="buttons" id="button3">3</button>
</div>
If there are other buttons not to be affected we can use a class
let index = 0;
const colors = ['green', 'red', '#405cf5'];
document.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.matches("button.buttons")) {
tgt.style.backgroundColor = colors[index++ % colors.length];
}
})
<button type="button" class="buttons" id="button1">1</button>
<button type="button" class="buttons" id="button2">2</button>
<button type="button" class="buttons" id="button3">3</button>
<button class="otherbutton">Dont color me</button>
I want the cart to add the item that the Add to cart button relates to. Can you also please explain the reason behind it not working. Currently it is only adding the first product.
Here is the HTML:
<p class="name">Playstation 4 console (Black)</p>
<p class="pricetitle">Price: <span id="price">1899</span> AED</p>
<form>
<button type="button" onclick="addToCart()">Add to cart</button>
</form>
<p class="name">Xbox one console (Black)</p>
<p class="pricetitle">Price: <span id="price">1800</span> AED</p>
<form>
<button type="button" onclick="addToCart()">Add to cart</button>
</form>
and here is the JavaScript:
const name = document.querySelectorAll(".name");
const price = document.querySelectorAll("#price");
const button = document.querySelectorAll("button");
const cart = []
const addToCart = () => {
for (var i = 0; i < 1; i++) {
cart.push(name[i].innerText)
cart.push(parseInt(price[i].innerText))
}
console.log(cart)
}
Thank you
Here is an example, where we use data- attributes in the html. To help us when we load the cart.
let buttons = document.getElementsByTagName("button");
const cart = [];
for(var i=0; i<buttons.length; i++) {
let button = buttons[i];
console.log(button);
button.addEventListener('click', function(event){
console.clear();
console.log(event.target);
console.log(event.target.dataset.productSku);
cart.push( event.target.dataset.productSku );
console.log(cart)
});
}
<p class="name">Playstation 4 console (Black)</p>
<p class="pricetitle">Price: <span id="price">1899</span> AED</p>
<button data-product-sku="ps4black">Add to cart</button>
<p class="name">Xbox one console (Black)</p>
<p class="pricetitle">Price: <span id="price">1800</span> AED</p>
<button data-product-sku="xboxoneblack">Add to cart</button>
<div id="cart"></div>
function todoList() {
var item = document.getElementById('todoInput').value
var text = document.createTextNode(item)
var newItem = document.createElement("li")
newItem.appendChild(text)
var completed_button = document.createElement('input');
completed_button.type = "button";
completed_button.value = "Completed";
newItem.appendChild(completed_button);
document.getElementById("todoList").appendChild(newItem)
}
<h1>My To Do list</h1>
<form id="todoForm">
<input id="todoInput">
<button type="button" onclick="todoList()">Add Item</button>
</form>
<ul id="todoList">
<h3>My Tasks</h3>
</ul>
<ul>
<h3>Completed</h3>
</ul>
When I click on the completed button, I want to delete it from My Tasks and add it to the Completed ones. Can you help?
I played a little with your code and ended up with that snippet:
(I left comments in the code)
function todoList() {
var item = document.getElementById('todoInput').value
var text = document.createTextNode(item)
var newItem = document.createElement("li")
newItem.appendChild(text)
var completed_button = document.createElement('input');
completed_button.type = "button";
completed_button.value = "Completed";
completed_button.onclick = function() { // Added the onclick function
clickComplete(this);
};
newItem.appendChild(completed_button);
document.getElementById("todoList").appendChild(newItem);
}
// Added this function
function clickComplete(item) {
document.getElementById("completed").appendChild(item.parentNode);
item.remove(); // Removes the "completed" button
}
<h1>My To Do list</h1>
<form id="todoForm">
<input id="todoInput">
<button type="button" onclick="todoList()">Add Item</button>
</form>
<ul id="todoList">
<h3>My Tasks</h3>
</ul>
<ul id="completed">
<h3>Completed</h3>
</ul>
Feel free to comment me if any modification is to be made in that snippet.
Hope it helps.