Javascript createelement button not clickable - javascript

Hello I'm building a todo app with javascript. and i started to make divs and buttons from creating with document.createElement but when i create buttons to remove lists only one button which is written in html is clickable and remove div ,other buttons that created with javascript not clickable,please can anyone tell me how to fix
let menu = document.querySelector(".bs");
let btn1 = document.querySelector(".btn");
let btn2 = document.querySelector(".btn3");
let inp = document.querySelector(".input");
let bsd = document.querySelector(".sss");
let brs = document.querySelector(".marker");
btn1.addEventListener("click", function(){
let br = document.createElement("DIV");
br.className = "red";
br.innerHTML = inp.value;
menu.appendChild(br);
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
});
brs.addEventListener("click", function(){
let bred = document.querySelector(".but");
let drp = document.querySelector(".red");
bred.removeChild(drp);
});
.red {
background-color: dodgerblue;
width: 100%;
min-height: 50px;
display: flex;
align-items: center;
justify-content: space-around;
color: white;
margin: 30px 0;
}
.marker {
background-color:white;
border:none;
padding:10px 20px;
}
<body>
<div class="but">
<div class="red">
<button class="marker">Remove</button>
</div>
<div class="bs"></div>
</div>
<input type="text" class="input">
<button class="btn">Add</button>
<button class="btn3">Remove</button>
</body>
that

You need to add the click listener to "remove" buttons when you create them.
The following does this:
let menu = document.querySelector(".bs");
let btn1 = document.querySelector(".btn");
let btn2 = document.querySelector(".btn3");
let inp = document.querySelector(".input");
let bsd = document.querySelector(".sss");
let brs = document.querySelector(".marker");
let addBr = () => {
let br = document.createElement("DIV");
br.className = "red";
br.innerHTML = inp.value;
menu.appendChild(br);
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
btn1.addEventListener("click", addBr);
// Call `addBr` once to add the initial element
addBr();
.red {
background-color: dodgerblue;
width: 100%;
min-height: 50px;
display: flex;
align-items: center;
justify-content: space-around;
color: white;
margin: 30px 0;
}
.marker {
background-color:white;
border:none;
padding:10px 20px;
}
<body>
<div class="but">
<div class="bs"></div>
</div>
<input type="text" class="input">
<button class="btn">Add</button>
<button class="btn3">Remove</button>
</body>

Related

Can't create several divs inside another div

I'm trying to create several divs inside the div which has the id "second".
<div>
<div class="content" id="first" hidden></div>
<div class="content" id="second" hidden></div>
<div class="content" id="third" hidden></div>
</div>
I've tried the following function but it does not work.
function createboard(){
for(let i=0;i<10;i++){
let newDiv = document.createElement("div");
newDiv.className="column";
newDiv.id="column";
document.getElementById("second").appendChild(newDiv);
}
}
The function that removes the hidden attribute from the div
function hide_div(){
if(document.getElementById("cavidades").value == "" || document.getElementById("sementes").value==""){
alert("Preencha todos os dados de jogo antes de começar");
}
else{
var start_div = document.getElementById("start_div");
start_div.hidden=true;
var login=document.getElementById("login");
login.hidden=true;
var first = document.getElementById("first");
var second = document.getElementById("second");
var third = document.getElementById("third");
var inside=document.getElementById("inside");
first.hidden=false;
second.hidden=false;
third.hidden=false;
inside.hidden=false;
}
Both are supposed to run when this button is clicked
<button hidden type="submit" id="start" onclick="hide_div() ; createboard()">Começar</button>
CSS of both divs
div#second{
float: left;
background-color: lightgray;
height: 500px;
width: 500px;
border: 5px solid black;
}
div#column{
float: left;
background-color: green;
height: 50px;
width: 50px;
border: 5px solid yellow;
}
It doesn't work because your divs are hidden, try this:
function createboard(){
for(let i=0;i<10;i++){
let newDiv = document.createElement("div");
newDiv.className="column";
document.getElementById("second").appendChild(newDiv);
//just add this line
document.getElementById("second").hidden = false // to show the div
}
}

click a button to delete itself and its parent div

--- UPDATED QUESTION ---
Thanks for all the answers. I wrote the JS code to delete the parent div when clicking its corresponding button in my JS PRACTICE!!!
However, the same JS code does not work in my real JS project where all the parent div are created dynamically. The complete code can be found below.
There is no error but the JS code just does not work. Any ideas?
BELOW IS THE SIMPLIFIED **REAL JS PROJECT ** COMPLETE CODE
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Imgs</title>
<style type="text/css">
.container {
width: 100%;
}
.display-area {
width: 100%;
height: auto;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
img {
max-width: 100%;
}
.image-preview {
width: 80%;
min-height: 300px;
border: 2px dashed #dddddd;
display: block;
/*default text*/
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: #cccccc;
}
.newbtns {
border: 0;
background: lightgrey;
text-shadow: 1px 1px 1px white;
border: 1px solid #999;
position: absolute;
display: block;
}
</style>
</head>
<body>
<div class="container">
<div id='inputFiles'><input type="file" class="file" name="image_uploads" accept="image/png, image/jpeg, image/jpg"
multiple></div>
<div class="display-area" id='imgDisplay'>
</div>
<div id="defaultContent">
<p>No images</p>
</div>
<button type="button" value="Reload page" onclick="window.location.reload()">Reload Page</button>
</div>
</div>
</body>
<script>
var input = document.querySelector('input');
var uploadBox = document.getElementById('uploadBox');
var defaultContent = document.getElementById('defaultContent');
var imgDisplay = document.getElementById('imgDisplay')
//upload & preview
input.addEventListener('change', function () {
var imgFiles = input.files;
defaultContent.style.display = 'none';
for (var i = 0; i < imgFiles.length; i++) {
var imgDiv = document.createElement('div');
imgDiv.className = 'imgBox';
imgDiv.id = 'box' + i;
imgDiv.style.width = "20%";
var images = document.createElement('img');
images.src = URL.createObjectURL(imgFiles[i]);
var newbtn = document.createElement("button");
newbtn.type = "button";
newbtn.className = "newbtns";
newbtn.innerHTML = "X";
newbtn.style.color = "orange";
newbtn.style.background = 'red';
newbtn.id = 'newbtn' + i;
imgDiv.appendChild(newbtn);
imgDiv.appendChild(images);
imgDisplay.appendChild(imgDiv);
}
});
allButtons = document.getElementsByTagName('button');
for (var n = 0; n < allButtons.length; n++) {
if (allButtons[n].getAttribute('id') === 'newbtn' + n) {
allButtons[n].onclick = function () {
this.parentNode.parentNode.removeChild(this.parentNode);
}
} else { };
}
</script>
</html>
you can do something like this:
const buttonOne = document.getElementById('btn1');
const buttonTwo = document.getElementById('btn2');
buttonOne.addEventListener("click", () => deleteElementAndThisChildNodes('box1'))
buttonTwo.addEventListener("click", () => deleteElementAndThisChildNodes('box2'))
function deleteElementAndThisChildNodes(parentId) {
document.getElementById(parentId).remove()
}
To each of your button elements add onclick="DeleteParent(this)" then outside of your dynamic divs include the following:
<script type="text/javascript">
function DeleteParent(button){
button.parentElement.remove();
}
</script>
You can do this:
const display = document.getElementById("imgdisplayarea");
display.addEventListener("click", e => {
if(e.target.tagName === 'BUTTON'){
//if an element within a display div for a button, remove your father
e.target.parentNode.remove();
}
});
Here is a very simple example that works exactly how you want it (based on your question):
function disable() {
document.getElementById("demo").style.display = "none";
}
<div id="demo">
<button onclick="disable()">
Click Me
</button>
<h3>
This is part of the div
</h3>
</div>

Create text element inline with input checkbox list elements using javascript

I am trying to dynamically add a checklist to my page that will look something like this, where [ ] represents a checkbox
[ ] something
[ ] something
[ ] something
The following code snippet shows what I have so far. As seen, the "somethings" are below the checkboxes, I would like for them to be on the same line.
list = ["something1", "something2", "something3"];
document.addEventListener('DOMContentLoaded', function () {
for (var i = 0; i < list.length; i++) {
var container = document.getElementById("checklist");
var li = document.createElement("li");
var input = document.createElement("input");
var text = document.createTextNode(list[i]);
container.appendChild(li).appendChild(input)
container.appendChild(text)
input.type = "checkbox"
li.style.listStyle = "none"
}
})
#container {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
top: 100px;
}
#directions{
color: green;
}
<body>
<div id="container">
<div id="directions">
Check off list items!
</div>
<div id="checklist"></div>
</div>
</body>
Fix your javascript:
//container.appendChild(text);
li.appendChild(text);
list = ["something1", "something2", "something3"];
document.addEventListener('DOMContentLoaded', function () {
for (var i = 0; i < list.length; i++) {
var container = document.getElementById("checklist");
var li = document.createElement("li");
var input = document.createElement("input");
var text = document.createTextNode(list[i]);
container.appendChild(li).appendChild(input);
li.appendChild(text);
input.type = "checkbox";
li.style.listStyle = "none";
}
})
#container {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
top: 100px;
}
#directions{
color: green;
}
<body>
<div id="container">
<div id="directions">
Check off list items!
</div>
<div id="checklist"></div>
</div>
</body>
I would recommend you using div and label elements instead of li elements here.
You might also move list from being an array of strings to be an array of objects where each object has an identifier and a label string.
Let me know if you have any questions.
list = ["something1", "something2", "something3"];
document.addEventListener('DOMContentLoaded', function () {
for (var i = 0; i < list.length; i++) {
var container = document.getElementById("checklist");
var formGroup = document.createElement("div");
var input = document.createElement("input");
var label = document.createElement("label");
formGroup.appendChild(input);
formGroup.appendChild(label);
container.appendChild(formGroup);
input.type = "checkbox"
input.id = list[i];
label.setAttribute("for", list[i]);
label.innerText = list[i];
}
})
#container {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
top: 100px;
}
#directions{
color: green;
}
<body>
<div id="container">
<div id="directions">
Check off list items!
</div>
<div id="checklist"></div>
</div>
</body>
If the question is just how to get the checkbox and text on the same line, set your lis to display: inline or display: inline-block. That said, you probably shouldn't be using list items in the first place, especially when the parent isn't a list.

deleting an element onClick from an array of objects

i am doing the library project from "odin project" website and i am having trouble completing it. my idea is to access the cards particular index in the "library" array of objects, but i am having trouble doing so. my idea is to have a function that creates some type of id from its place in the array ( such as its index ) and use that as access for my delete button. any suggestions? i appreciate your time here is my codepen link
//constructor to add a book to
function Book(title, author, pages) {
this.title = title;
this.author = author;
this.pages = pages;
}
//array of books
const library = [];
//hides and unhides forms
const hide = () => {
var form = document.querySelector("#hide");
if (form.style.display === "none") {
form.style.cssText =
"display: block; display: flex; justify-content: center; margin-bottom: 150px";
} else {
form.style.display = "none";
}
};
//creates form, takes input,creates card, resets and runs hide function when done
const addBookCard = () => {
const bookName = document.querySelector('input[name="bookName"]').value;
const authorName = document.querySelector('input[name="authorName"]').value;
const numPages = document.querySelector('input[name="numPages"]').value;
library.push(new Book(bookName, authorName, numPages));
//just stating variables used within my function
const container = document.querySelector(".flex-row");
const createCard = document.createElement("div");
const divTitle = document.createElement("p");
const divAuthor = document.createElement("p");
const divPages = document.createElement("p");
const deleteBtn = document.createElement("button");
//using a class from my css file
createCard.classList.add("card");
createCard.setAttribute("id","id_num")
deleteBtn.setAttribute("onclick", "remove()")
deleteBtn.setAttribute('id','delBtn')
//geting all info from library
divTitle.textContent = "Title: " + bookName
divAuthor.textContent = "Author: " + authorName
divPages.textContent = "Number of Pages: " + numPages
deleteBtn.textContent = "Delete This Book";
//adding it all to my html
container.appendChild(createCard);
createCard.appendChild(divTitle);
createCard.appendChild(divAuthor);
createCard.appendChild(divPages);
createCard.appendChild(deleteBtn);
document.getElementById("formReset").reset();
hide()
return false
};
var btn = document.querySelector('#newCard');
btn.onclick = addBookCard;
You can change library declaration from const to let.
Then you can push books together with their corresponding deleteBtn, that way you will be able to easily remove an entry that corresponds to the clicked deleteBtn
library.push([new Book(bookName, authorName, numPages), deleteBtn]);
And then you can add event listener on deleteBtn like this
deleteBtn.addEventListener('click', event => {
event.target.parentNode.remove();
library = library.filter(v => v[1] !== event.target);
});
Where the first line removes the element from the DOM, and the second line creates new library array without the removed entry.
function Book(title, author, pages) {
this.title = title;
this.author = author;
this.pages = pages;
}
//array of books
let library = [];
//hides and unhides forms
const hide = () => {
var form = document.querySelector("#hide");
if (form.style.display === "none") {
form.style.cssText =
"display: block; display: flex; justify-content: center; margin-bottom: 150px";
} else {
form.style.display = "none";
}
};
//creates form, takes input,creates card, resets and runs hide function when done
const addBookCard = () => {
const bookName = document.querySelector('input[name="bookName"]').value;
const authorName = document.querySelector('input[name="authorName"]').value;
const numPages = document.querySelector('input[name="numPages"]').value;
//just stating variables used within my function
const container = document.querySelector(".flex-row");
const createCard = document.createElement("div");
const divTitle = document.createElement("p");
const divAuthor = document.createElement("p");
const divPages = document.createElement("p");
const deleteBtn = document.createElement("button");
library.push([new Book(bookName, authorName, numPages), deleteBtn]);
deleteBtn.addEventListener('click', event => {
event.target.parentNode.remove();
library = library.filter(v => v[1] !== event.target);
});
//using a class from my css file
createCard.classList.add("card");
createCard.setAttribute("id","id_num")
deleteBtn.setAttribute('id','delBtn')
//geting all info from library
divTitle.textContent = "Title: " + bookName
divAuthor.textContent = "Author: " + authorName
divPages.textContent = "Number of Pages: " + numPages
deleteBtn.textContent = "Delete This Book";
//adding it all to my html
container.appendChild(createCard);
createCard.appendChild(divTitle);
createCard.appendChild(divAuthor);
createCard.appendChild(divPages);
createCard.appendChild(deleteBtn);
document.getElementById("formReset").reset();
hide()
return false
};
var btn = document.querySelector('#newCard');
btn.onclick = addBookCard;
function hello (){
for (var i = 0; i < library.length ;i++) {
console.log(library[i]);
}
}
body {
margin: 0 auto;
width: 960px;
//background: cyan;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-row-form {
display: flex;
justify-content: center;
}
.flex-column-form {
display: flex;
flex-direction: column;
background: purple;
width: 45%;
padding: 20px;
border-radius: 5px;
border: 2px solid black;
color: white;
font-weight: 300;
font-size: 24px;
}
.card {
width: 33.33%;
text-align: center;
height: 200px;
border: 1px solid black;
padding: 20px;
margin: 10px;
border-radius: 10px;
}
.text {
padding-bottom: 20px;
font-weight: 300;
font-size: 20px;
}
p {
font-size: 20px;
font-weight: 400;
}
#newBook {
margin: 30px;
padding: 10px 20px;
cursor: pointer;
font-size: 16px;
color: #dff;
border-radius: 5px;
background: black;
}
#delBtn{
padding:10px;
border-radius:5px;
background:red;
color:white;
font-size:14px;
cursor: pointer;
}
<div id="display"></div>
<button id="newBook" onclick="hide()">New Book</button>
<div class="flex-row-form" id="hide" style= "display:none">
<form class="flex-column-form" id="formReset">
Book Name: <input type="text" name="bookName" value="Book Name" id="title"><br>
Author Name: <input type="text" name="authorName" value="Author Name " id="author"<br>
Number of Pages: <input type="text" name="numPages" value="# of Pages" id="pages" ><br>
<button id="newCard"> Add Book to Library</button>
</form>
</div>
<div class="flex-row">
</div>
And I have removed this line
deleteBtn.setAttribute("onclick", "remove()")
you don't need it anymore since I have added event listener for that button, and it was throwing an error because you didn't define remove function in your code.

Generated button's function only works on second click

I have a function that creates an alert box, fills the title field and message with information (error, success, info...) and then adds a button that gets an onclick function to remove the message alert.
When a message is first generated and you click the button nothing happens, but when you click it a second time it'll close the message and works for all messages created later until the page reloads.
var container = document.getElementById('modal-container');
var page = document.getElementById('html');
var current;
function createBox(msgtype) {
var back = document.createElement('span');
back.className = 'modal-window';
container.appendChild(back);
var box = document.createElement('div');
box.className = 'modal-message-box';
back.appendChild(box);
if (msgtype == 'error') {
var head = document.createElement('span');
head.className = 'errorheader';
} else if (msgtype == 'info') {
var head = document.createElement('span');
head.className = 'infoheader';
} else if (msgtype == 'success') {
var head = document.createElement('span');
head.className = 'successheader';
}
box.appendChild(head);
var title = document.createElement('h2');
title.id = 'alert-title';
title.className = 'alert-title';
head.appendChild(title);
var msg = document.createElement('h4');
msg.id = 'alert-message';
msg.className = 'alert-message';
box.appendChild(msg);
var btn = document.createElement('button');
btn.innerHTML = 'Close';
btn.onclick = closemsg;
box.appendChild(btn);
page.className = 'noscroll';
current = document.getElementById('modal-window');
}
function alertBoxPopup(msgtype, title, msg) {
createBox(msgtype);
document.getElementById('alert-title').innerHTML = title;
document.getElementById('alert-message').innerHTML = msg;
}
function closemsg() {
document.getElementById('html').className = '';
container = document.getElementById('modal-container');
container.removeChild(container.firstChild);
}
.modal-container{
display: flex;
align-content: center;
justify-content: center;
}
.modal-window{
background-color: rgba(0,0,0,.5);
height: 100vh;
width: 100vw;
position: fixed;
margin: 0px;
padding: 0px;
z-index: 5;
display: flex;
justify-content: center;
align-items: center;
}
.modal-message-box{
background: white;
max-height: 400px;
min-height: 300px;
max-width: 700px;
min-width: 500;
border-radius: 10px;
overflow: hidden;
}
<html id='html'>
<body>
<div class="modal-container" id="modal-container"></div>
<div class="row"><button onclick="alertBoxPopup('error', 'Uh-Oh!', 'You have screwed up something!')">Error</button> <button onclick="alertBoxPopup('info', 'Information!', 'Did you know? This box is just a bit of information!')">Info</button> <button onclick="alertBoxPopup('success', 'YES!', 'You did it man! You did something good!')">Success</button>
</div>
</body>
</html>
I was able to actually figure this out on accident.
I realized that I stored the page in a variable, was searching for it and on a whim I decided to put the className change after the removeChild. For whatever reason it works.
var container = document.getElementById('modal-container');
var page = document.getElementById('html');
var current;
function createBox(msgtype, extrabtn, ebname, ebfunc){
var back = document.createElement('span');
back.className = 'modal-window';
container.appendChild(back);
var box = document.createElement('div');
box.className = 'modal-message-box';
back.appendChild(box);
if(msgtype == 'error'){
var head = document.createElement('span');
head.className = 'errorheader';
}else if(msgtype == 'info'){
var head = document.createElement('span');
head.className = 'infoheader';
}else if(msgtype == 'success'){
var head = document.createElement('span');
head.className = 'successheader';
}
box.appendChild(head);
var title = document.createElement('h2');
title.id = 'alert-title';
title.className = 'alert-title';
head.appendChild(title);
var msg = document.createElement('h4');
msg.id = 'alert-message';
msg.className = 'alert-message';
box.appendChild(msg);
if(extrabtn){
var row = document.createElement('div');
row.className = 'row';
var xtrbtn = document.createElement('button');
xtrbtn.innerHTML = ebname;
xtrbtn.onclick = ebfunc;
var btn = document.createElement('button');
btn.innerHTML = 'Close';
btn.onclick = function(){
closemsg();
};
box.appendChild(row);
row.appendChild(xtrbtn);
row.appendChild(btn);
}else{
var btn = document.createElement('button');
btn.innerHTML = 'Close';
btn.onclick = function(){
closemsg();
};
box.appendChild(btn);
}
page.className = 'noscroll';
current = document.getElementById('modal-window');
}
function alertBoxPopup(msgtype, title, msg, extrbtn, ebname, ebfunc){
createBox(msgtype, extrbtn, ebname, ebfunc);
document.getElementById('alert-title').innerHTML = title;
document.getElementById('alert-message').innerHTML = msg;
}
function closemsg(){
container = document.getElementById('modal-container');
container.removeChild(container.firstChild);
page.className = '';
}
.modal-container{
display: flex;
align-content: center;
justify-content: center;
}
.modal-window{
background-color: rgba(0,0,0,.5);
height: 100vh;
width: 100vw;
position: fixed;
margin: 0px;
padding: 0px;
z-index: 5;
display: flex;
justify-content: center;
align-items: center;
}
.modal-message-box{
background: white;
max-height: 400px;
min-height: 300px;
max-width: 700px;
min-width: 500;
border-radius: 10px;
overflow: hidden;
}
<html id="html">
<body>
<div class="modal-container" id="modal-container"></div>
<div class="row">
<button onclick="alertBoxPopup('error', 'Uh-Oh!', 'You have screwed up something!')">Error</button>
<button onclick="alertBoxPopup('info', 'Information!', 'Did you know? this is just information!')">Info</button>
<button onclick="alertBoxPopup('success', 'YES!', 'You did it man! You did something good!')">Success</button>
</div>
<body>
<html>

Categories