onclick function doesn't execute - javascript

I'm trying to update the number of participants by increasing it by one every time the submit button gets clicked, and by doing so I added an add() inside my script tag and increased the participant number every time it gets clicked. But the number of participants doesn't get changed for some reason.
Btw I'm new to DOM and JS
let Agenda_style = document.querySelector('.agenda'); //to add style you must acess the class name/ID using querySelector
Agenda_style.style.color = "red "; // set color to red to change the color of the class agenda
let NewElement = document.createElement("li "); //create new element of type <li>
NewElement.innerText = "Here "; // add a text inside the <li> element
Agenda_style.append(NewElement); // append a tet to the agendaa class
let participant = 0;
function add() {
participant++;
document.getElementById("submit").innerText = participant;
};
<h5>Number of participant:<span id="submit">0</span></h5>
<button type="button" onclick="add()">Submit</button>
</div>

It fails for me, as I have now .agenda element.. do you have that in your HTML?
If I put a null check around that section of the script, the remaining piece works.
<h5>Number of participants: <span id="submit">0</span></h5>
<button type="button" onclick="add()">Submit</button>
</div>
<script>
let Agenda_style = document.querySelector('.agenda'); // to add style you must access the class name/ID using querySelector
if(Agenda_style != null) { // only proceed if Agenda_style exists
Agenda_style.style.color = "red "; // set color to red to change the color of the class agenda
let NewElement = document.createElement("li "); // create new element of type <li>
NewElement.innerText = "Here "; // add a text inside the <li> element
Agenda_style.append(NewElement); // append a tet to the agendaa class
}
let participant = 0;
function add() {
participant++;
document.getElementById("submit").innerText = participant;
}
</script>

These days we tend to not use inline JavaScript, so it would be best to grab your button with querySelector, and then use addEventListener to call your function when it's clicked. This way there's a "separation of concerns" between your mark-up, your CSS, and your code.
const number = document.querySelector('#number');
const button = document.querySelector('button');
button.addEventListener('click', add, false);
let participant = 0;
function add() {
number.textContent = ++participant;
}
<h5>Number of participant:
<span id="number">0</span>
</h5>
<button type="button">Submit</button>

This should be working
function add() {
let val = document.querySelector('#submit').innerText;
val = parseInt(val)+1;
}

Related

How to select span within a dynamically generated button?

Problem:
How to update the innerHtml of a span within a dynamically generated button using only JavaScript?
I'm building a 'like' feature (think social media) where users can like/unlike posts, but I can't figure out how to select the value of the specific span the user clicks on. I've been only able to find jQuery solutions using .find('span')
const htmlBtn = `<button class="count"><span>0</span></button>`;
const create = document.getElementById("create");
create.addEventListener("click", (e) => {
const container = document.createElement("div");
container.className = "container";
container.innerHTML = htmlBtn;
document.getElementById("app").append(container);
});
const app = document.getElementById("app");
app.addEventListener("click", (e) => {
const btn = e.target;
/*
each time someone click nth button, span within nth button increments by 1
let count = document.querySelector("span").innerHTML;
count++;
document.querySelector("span").innerHTML = count;
*/
});
<button id="create">Create</button>
<div id="app"></div>
Expected outcome:
User clicks the button to increment the span of only that button by 1.
e.target.children will give you an array of all the children of button and the 0th index of the array should be your span element which you can then edit normally using the innerHTML method.
In your case,
let count = parseInt(e.target.children[0].innerHTML);
e.target.children[0].innerHTML = count + 1;
create.addEventListener("click", (e) => {
const container = document.createElement("div");
container.className = "container";
container.innerHTML = htmlBtn;
document.getElementById("app").append(container);
container.addEventListener("click", (e) => {
const value = +e.target.innerHTML;
e.target.innerHTML = (value + 1).toString();
});
});
The methods querySelector() and querySelectorAll() can be called on a specific parent element, similar to find() in jQuery.
Make sure to use e.currentTarget and not e.target in the event listener, in order to refer to the element that handles the event and not to any child element.
Example - click any of numbers to increment.
function clickToIncrement(e) {
const innerSpan = e.currentTarget.querySelector('span');
if (innerSpan) {
innerSpan.textContent++;
}
}
document.getElementById('div1').addEventListener('click', clickToIncrement);
document.getElementById('div2').addEventListener('click', clickToIncrement);
<div id="div1">
<span>0</span>
</div>
<div id="div2">
<span>0</span>
</div>

Delete element in JS

I was trying to prototype a site for a To-Do List to experiment with something new using JavaScript.
function task() {
//Create checkbox
var x = document.createElement("INPUT");
x.setAttribute("type", "checkbox");
//Create <br>
lineBreak = document.createElement("br");
//Create <p> element
var todo = document.createElement("p");
//Insert in <p> the text in the input box
todo.innerText = document.getElementById("task").value;
//Create the <p>checkbox+text</p><br> on every botton click
return document.body.appendChild(x) + document.body.appendChild(todo) + document.body.appendChild(lineBreak);
document.querySelector('#reset').addEventListener('click', () => {
document.getElementById('reset').clicked
});
}
//Show Reset button on task generated
document.querySelector('#go').addEventListener('click', () => {
document.getElementById("reset").style.visibility = "visible";
});
p {
display: inline;
}
img {
width: 30px;
display: inline;
}
#reset {
visibility: hidden;
}
<h1>To-Do List</h1>
<input type="text" placeholder="Write a Task" id="task"><button id="go" onclick="task()">GO</button>
<hr>
<body>
<section>
<button id="reset">RESET</button>
</section>
</body>
As you can see from the code and the indicated if statement I was able to generate for each click on the go button (defined in HTML) new <p></p>.
It successfully generates a checkbox, next to a text typed in a text box and then wraps with the <br>.
I was trying to eliminate the elements generated by pressing the reset button, but despite having tried several solutions the only one that seems to work is the one that deletes all the contents of the body.
Could you suggest a solution to allow it to work?
Just make the adjustments to your javascript code with the following steps and it should work as your expectation:
Steps to fix the code:
Step 1: AddEventListener should be called before return so it would be called whenever the task() is executed with the click of the Go button.
Step 2: Firstly, remove the className "go-element" from the previously added elements if they exist.
Step 3: Add the class "go-element" to newly added elements so they can be identified easily while resetting them.
Step 4: on reset click, it should remove all the elements with the class "go-element"
Note: If you just want to remove all the elements which are added through the Go button, just skip step 2. Also, to simplify you can wrap your all elements in a div element and just follow all the steps as shown above with the div instead of elements.
function task() {
// Step 2: removing go-element class from previously added elements
const elements = document.getElementsByClassName("go-element");
while(elements.length > 0) {
elements[0].classList.remove("go-element");
}
// Step 3: add the class name to new elements
//Create checkbox
var x = document.createElement("INPUT");
x.setAttribute("type", "checkbox");
x.classList.add("go-element"); // step 3
//Create <br>
lineBreak = document.createElement("br");
lineBreak.classList.add("go-element"); // step 3
//Create <p> element
var todo = document.createElement("p");
todo.classList.add("go-element"); // step 3
//Insert in <p> the text in the input box
todo.innerText = document.getElementById("task").value;
// Step 1: moved this code before return so it will execute
document.querySelector('#reset').addEventListener('click', () => {
// Step 4: removing elements with class name "go-element"
const elements = document.getElementsByClassName("go-element");
while (elements.length > 0) {
elements[0].parentNode.removeChild(elements[0]);
}
});
//Create the <p>checkbox+text</p><br> on every botton click
return document.body.appendChild(x) + document.body.appendChild(todo) + document.body.appendChild(lineBreak);
}
//Show Reset button on task generated
document.querySelector('#go').addEventListener('click', () => {
document.getElementById("reset").style.visibility = "visible";
});

How to delete text box along with button in JavaScript

I have a button when user clicks the button it create the text box along with remove button
but all the text boxes created with same id how we can delete the text box when clicks respective remove button
here My Code:
<body>
<button type="button" id="URLbtn" onclick="Createinput()"> + Add URL</button>
<div id="TextAreaBtn"></div>
<script>
function Createinput() {
var newdiv=document.createElement("div");
newdiv.id="test"
var Inputele=document.createElement("input");
Inputele.type="text";
Inputele.id="URLtxt"
newdiv.appendChild(btnele);
var btnele=document.createElement("button");
btnele.id="rmvbtn"
btnele.type="button"
btnele.innerHTML="-"
btnele.onclick=RemoveUrlBox()
newdiv.appendChild(btnele);
var element = document.getElementById("TextAreaBtn");
element.appendChild(newdiv);
}
function RemoveUrlBox() {}
</script>
</body>
i am getting following output
if user click 2 remove button only remove the second textbox and button
You need to select the wrapping div. Easiest way is to use remove() and use closest. No need to use the id..... You also need to remember ids need to be unique.
function createInput() {
var newDiv = document.createElement("div");
newDiv.className = 'group';
var inputElem = document.createElement("input");
inputElem.type = "text";
newDiv.appendChild(inputElem);
var btnElem = document.createElement("button");
btnElem.type = "button";
btnElem.textContent = "-";
btnElem.addEventListener("click", removeUrlBox);
newDiv.appendChild(btnElem);
var element = document.getElementById("TextAreaBtn");
element.appendChild(newDiv);
}
function removeUrlBox() {
this.closest('.group').remove();
}
<button type="button" id="URLbtn" onclick="createInput()"> + Add URL</button>
<div id="TextAreaBtn"></div>
This should do the trick:
const txtarea=document.getElementById('TextAreaBtn');
document.getElementById('URLbtn').onclick=()=>txtarea.innerHTML+=
'<div><input type="text" class="URLtxt"><button class="rmvbtn">-</button></div>';
txtarea.onclick=ev=>ev.target.className==="rmvbtn"&&ev.target.parentNode.remove()
<button type="button" id="URLbtn"> + Add URL</button>
<div id="TextAreaBtn"></div>
I replaced your id attributes with class attributes, as these don't need to be unique.
I reduced your script by using innerHTML instead of laboriously putting elements together with createElement(). This is a matter of opinion as both methods have their advantages.
I also used delegated event listener attachment for the removal buttons. This way you can get away with a single event listener on div.TextAreaBtn. The attached funcion will only trigger any action if the clicked element has class "rmvbtn".
Change
btnele.onclick=RemoveUrlBox()
to
btnele.addEventListener('click', function (e) {
// `this` is the button that was clicked no matter about the id
// `this.parentNode` is the div you want to remove
const nodeToRemove = this.parentNode;
nodeToRemove.parentNode.removeChild(nodeToRemove);
});

can javascript version of print be inserted inside the code of a Div?

I have a form that adds and subtracts a smaller form when user clicks on add or subtract users button.
what I want to do is add a +1 every time the user hits the add button to a ID tag inside the div tag.. confusing yes I know
say this is the original tag:
<div id="formwrap" class="test" name="test">im a form in this formwrap</div>
now say the user clicks on a add button and a new form will pop up below the current form and using a print or echo version of javascript this would be the new code created for the div using .append(html) or something along those lines too this:
<div id="formwrap" class="test" name="test">im a form in this formwrap</div>
<div id="formwrap" class="test2" name="test2">im a form in this formwrap</div>
and so on as u can see next the 2 would change to a 3 if someone where to click the add button
<div id="formwrap" class="test(+1 code would go here)" name="test(+1 code would go here)">im a form in this formwrap</div>
So before I code is this even possible? I want to be able to style the smaller form differently and I want the phpmailer to be able get retrieve all the data depending on how many clicks they do. and adding a +1 too each of the tags would do both goals.
It is possible using data attributes.
See: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
You would do something like this
var count = 0
var formwrap = document.getElementById('formwrap');
formwrap.dataset.name = "aName" + count
// increment count on click
You can use jquery for this when user click on add button you have to increment the value of count like this ...
var count = 0;
$("button").on("click", function () {
var html = '<div id="formwrap'+count+'" class="test'+count+'"
name="test'+count+'">im a form in this formwrap</div>';
count++;
$(div).append(html);
});
this way you can do this.
//Create a private counter var
const counter = (function() {
var formCount = 0;
return {
value: () => formCount,
increment: () => ++formCount
}
})();
//A function that will generate a "form" element
const ID_PREFIX = 'formwrap_';
const generateFormEl = () => {
let el = document.createElement('div');
el.setAttribute('id', `${ID_PREFIX}${counter.increment()}`);
el.setAttribute('class', 'test');
el.setAttribute('name', 'test');
el.appendChild(document.createTextNode(`ID: ${el.getAttribute('id')}`));
return el;
};
//Store your DOM elements in some vars
const forms = document.querySelector('#forms');
const btn = document.querySelector('[type="button"]');
//Add a form element to the DOM on click
btn.addEventListener('click', () => {
const form = generateFormEl();
forms.appendChild(form);
});
<div id="container">
<input type="button" value="Add a form" />
<div id="forms"></div>
</div>

Javascript- Creating To Do list not working

I deleted the button part in my script but not even the first part of my function is working where I type in input box and suppose to be added to the ...I don't understand why. When I run the code without the buttons code which is titled " //BUTTON creation " I get no error but no item is being added to the list. So I have two problems Items aren't being added to my list and aren't displaying and also if I include the button part its saying an error "list.appendChild is not a function"
<input type="text" placeholder="Enter an Activity" id="textItem">
<img src="images/add-button.png" id="addButton">
<div id="container">
<ul class="ToDo">
<!--
<li>
This is an item
<div id="buttons">
<button ></button>
<img src="images/remove-icon.png"id="remove">
<button id="complete"></button>
<img src="images/complete-icon.jpg" id="complete">
</div>
</li>
!-->
</ul>
</div>
<script type="text/javascript">
//Remove and complete icons
var remove = document.createElement('img').src =
"images/remove-icon.png";
var complete = document.createElement('img').src = "images/complete-icon.jpg";
//user clicks add button
//if there is text in the item field we grab the item into var text
document.getElementById("addButton").onclick = function()
{
//value item is the text entered by user
var value = document.getElementById("textItem").value;
//checks if there is a value typed
if(value)
{
addItem(value);
}
//adds a new item to the ToDo list
function addItem(text)
{
var list = document.getElementsByClassName("ToDo");
//created a varibale called item that will create a list item everytime this function is called
var item = document.createElement("li");
//this will add to the innerText of the <li> text
item.innerText = text;
//BUTTON creation
var buttons = document.createElement('div');
buttons.classList.add('buttons');
var remove = document.createElement('buttons');
buttons.classList.add('remove');
remove.innerHTML = remove;
var complete = document.createElement('buttons');
buttons.classList.add('complete');
complete.innerHTML = complete;
buttons.appendChild(remove);
buttons.appendChild(complete);
list.appendChild(buttons);
list.appendChild(item);
}
}
</script>
The problem is in the line:
var list = document.getElementsByClassName("ToDo");
list.appendChild(item);
The line var list = document.getElementsByClassName("ToDo"); will provide a collection, notice the plural name in the api.
You need to access it using :
list[0].appendChild(item);
There are other problems too in the code but hopefully this gets you going!
There are a couple of issues in your code that need to be addressed to get it to work properly.
1) You are creating your image elements and then setting the variables to the src name of that image and not the image object itself. When you use that reference later on, you are only getting the image url and not the element itself. Change var remove = document.createElement('img').src = "images/remove-icon.png" to this:
var removeImg = document.createElement('img')
removeImg.src = "images/remove-icon.png";
2) As #Pankaj Shukla noted, inside the onclick function, getElementsByClassName returns an array, you will need to address the first item of this array to add your elements. Change var list = document.getElementsByClassName("ToDo") to this:
var list = document.getElementsByClassName("ToDo")[0];
3) For your buttons, you are trying to creating them using: var remove = document.createElement('buttons'). This is invalid, buttons is an not the correct element name, its button. Additionally, you are re-declaring the variables remove and complete as button objects, so within the onclick function it reference these buttons, not the images you defined earlier. So when you assign the innerHTML to remove and complete, you are assigning the buttons innerHTML to itself. The solution is to change the image variables to something different.
4) Finally, also relating to the buttons, you are assigning the innnerHTML to an image object, that's incorrect. You can either insert the html text of the img directly, or append the image object as a child of the button, similar to how the button is a child of the div.
The updated code with all these changes looks like this:
//Remove and complete icons
var removeImg = document.createElement('img');
removeImg.src = "images/remove-icon.png";
var completeImg = document.createElement('img');
completeImg.src = "images/complete-icon.jpg";
//user clicks add button
//if there is text in the item field we grab the item into var text
document.getElementById("addButton").onclick = function() {
//value item is the text entered by user
var value = document.getElementById("textItem").value;
//checks if there is a value typed
if (value) {
addItem(value);
}
//adds a new item to the ToDo list
function addItem(text) {
var list = document.getElementsByClassName("ToDo")[0];
//created a varibale called item that will create a list item everytime this function is called
var item = document.createElement("li");
//this will add to the innerText of the <li> text
item.innerText = text;
//BUTTON creation
var buttons = document.createElement('div');
buttons.classList.add('buttons');
var remove = document.createElement('button');
remove.classList.add('remove');
remove.appendChild(removeImg);
var complete = document.createElement('button');
complete.classList.add('complete');
complete.appendChild(completeImg);
buttons.appendChild(remove);
buttons.appendChild(complete);
list.appendChild(buttons);
list.appendChild(item);
}
}

Categories

Resources