--- 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>
Related
Have multiple buttons and sections associated with those buttons in the Elementor page builder.
What I am trying to achieve is when page loads, we can only see buttons and section will toggle when someone clicks on the button.
I have managed to achieve that, but when clicking on second button, button 1 section should hide and button 2 section should display.
Here is the w3 schools link for my project
jQuery(document).ready(function( $ ){
var hbtn = $(".coursesBtn");
var hcon = $(".coursesSection");
hcon.hide();
hbtn.click(function(e) {
var index = hbtn.index(this)
$(hcon).eq(index).slideToggle("slow");
e.preventDefault();
});
});
jQuery(document).ready(function( $ ){
var hbtn = $(".videosBtn");
var hcon = $(".videosSection");
hcon.hide();
hbtn.click(function(e) {
var index = hbtn.index(this)
$(hcon).eq(index).slideToggle("slow");
e.preventDefault();
});
});
You can use onclick for buttons for example
<button class="btn1" onclick="f1()">BUTTON1</button>
and add the function to toggle in f1()
Here is a quick example, the idea is to hide the other sections first, and show the section that you want to be displayed;
$(document).ready(function($) {
$('.btn1').click(function() {
$('.section').hide();
$('.section1').show();
})
$('.btn2').click(function() {
$('.section').hide();
$('.section2').show();
})
$('.btn3').click(function() {
$('.section').hide();
$('.section3').show();
})
})
.section {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top: 20px;
}
.section2 {
background-color: lightgreen;
}
.section3 {
background-color: orange;
}
<button class="btn1">BUTTON1</button>
<button class="btn2">BUTTON2</button>
<button class="btn3">BUTTON3</button>
<div class="section section1">
This is Section1.
</div>
<div class="section section2">
This is Section2.
</div>
<div class="section section3">
This is Section3.
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
Add a new class for each button (.btn) and section (.section) and use these as in the code below. You can have as many buttons and sections as you want and the code below will work without any modification:
var hbtn = $(".btn");
var hcon = $(".section");
hcon.hide();
hbtn.click(function(e) {
var index = hbtn.index(this);
hcon.hide() //OR hcon.filter(':visible').slideToggle("slow")
.eq(index).slideToggle("slow");
});
DEMO
$(document).ready(function( $ ){
var hbtn = $(".btn");
var hcon = $(".section");
hcon.hide();
hbtn.click(function(e) {
var index = hbtn.index(this);
hcon.hide() //OR hcon.filter(':visible').slideToggle("slow")
.eq(index).slideToggle("slow");
});
});
.section1 {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top: 20px;
}
.section2 {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn1 btn">BUTTON1</button>
<button class="btn2 btn">BUTTON2</button>
<div class="section1 section">
This is Section1.
</div>
<div class="section2 section">
This is Section2.
</div>
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>
I am making a modal, so i made an example to make it simple, Program goes, when i click any button, a modal will show and the page too but it will only show specific page depends on the button, in this case, uno button is for page1, dos for page2 and tres for page 3.
everything goes where i wanted until i clicked all the button, Just to show you my problem, try clicking step by step from uno to tres, then click uno again, and that's it the pages does not change at all.
can you please figure out whats wrong with my code?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.btns {
float: left;
}
.modal {
display: none;
background-color: aqua;
float: right;
width: 400px;
height: 600px;
}
.page1 {
position: absolute;
display: none;
background-color: burlywood;
margin: 20px;
width: 400px;
height: 150px;
}
.p1 {
border: 2px solid red;
}
.p2 {
border: 2px solid blue;
}
.p3 {
border: 2px solid green;
}
</style>
</head>
<body>
<p>Click the button to Show Modal.</p>
<div class="btns">
<button class="myBtn" id="uno">uno</button>
<button class="myBtn " id="dos">dos</button>
<button class="myBtn "id="tres">tres</button>
</div>
<div class="modal">
Modal
<div class="page1 p1">Page1</div>
<div class="page1 p2">Page2</div>
<div class="page1 p3">Page3</div>
</div>
<!--JS-->
<script>
var btn = document.querySelectorAll('.myBtn');
var getModal = document.querySelector('.modal');
var getPages = document.querySelectorAll('.page1');
//console.log(getPages);
for(let i=0; i<btn.length;i++ ){
btn[i].addEventListener('click', () => {showModal(); getId(); displayPage()});
}
function showModal(){
getModal.style.display = "block";
}
function getId(){
//console.log(event.target.id);
}
function displayPage(){
var btnId = event.target.id;
if(btnId == "uno"){
getPages[0].style.display = "block";
}else if(btnId == "dos"){
getPages[1].style.display = "block";
}else if(btnId == "tres"){
getPages[2].style.display = "block";
}
}
</script>
</body>
</html>
<html>
You are not hiding the other modal pages when you trigger the display of one of them, therefore they are all displayed at the same time once you clicked all buttons, and the one with the highest z-index (in this case automatically determined by element order in the markup) overlays all others. Set the display property to block or none depending on whether it's the current modal page or not. You can also pass the index of the modal page to the displayPage() function, so you don't need those if statements to check for the button text.
var btn = document.querySelectorAll('.myBtn');
var getModal = document.querySelector('.modal');
var getPages = document.querySelectorAll('.page1');
//console.log(getPages);
for (let i = 0; i < btn.length; i++) {
btn[i].addEventListener('click', () => {
showModal();
displayPage(i)
});
}
function showModal() {
getModal.style.display = "block";
}
function displayPage(pageIndex) {
var btnId = event.target.id;
getPages.forEach(function(modalPage, index) {
getPages[index].style.display = index === pageIndex ? "block" : "none";
});
}
.btns {
float: left;
}
.modal {
display: none;
background-color: aqua;
float: right;
width: 400px;
height: 600px;
}
.page1 {
position: absolute;
display: none;
background-color: burlywood;
margin: 20px;
width: 400px;
height: 150px;
}
.p1 {
border: 2px solid red;
}
.p2 {
border: 2px solid blue;
}
.p3 {
border: 2px solid green;
}
<p>Click the button to Show Modal.</p>
<div class="btns">
<button class="myBtn" id="uno">uno</button>
<button class="myBtn " id="dos">dos</button>
<button class="myBtn " id="tres">tres</button>
</div>
<div class="modal">
Modal
<div class="page1 p1">Page1</div>
<div class="page1 p2">Page2</div>
<div class="page1 p3">Page3</div>
</div>
The problem is with your display function. You must hide other pages when you want to show your new one. So add this function to your code.
function hideAllPages(){
getPages[0].style.display = "none";
getPages[1].style.display = "none";
getPages[2].style.display = "none"
}
}
then call it the first line of displayPage function.
function
// Hide all pages first
hideAllPages();
var btnId = event.target.
if(btnId == "uno") {
getPages[0].style.display = "block"
} else if (btnId == "dos") {
getPages[1].style.display = "block"
} else if (btnId == "tres") {
getPages[2].style.display = "block"
}
}
Also you can have some base structure for your code like:
save id of pages or (better solution) get id of the page with data-* (Exp. data-page-id="uno") in html structure and retrieve it in js with listen to click event of page button click and use getAttribute function to see which page to show
I hope it helps :)
I want to know how to make it so that when the button is clicked and a new input is added, it does not take the place of the old one, but appears in a new bix leaving the old one.
<!DOCTYPE html>
<html>
<body>
<div id="itemcreator" class="itm">
<form id="form1">
<!--where the user inputs the item-->
Item: <input name="item" type="text" size="20">
</form>
<button onclick="outputname()">Add</button>
</div>
<div class="box" id="duplicater">
<p id="output"></p>
</div>
<script type="text/javascript">
var i = 0;
var original = document.getElementById('duplicater');
duplication function
function duplicate() {
i = i + 1;
var clone = original.cloneNode(true);
clone.id = "duplicetor" + ++i;
original.parentNode.appendChild(clone);
}
function to output the item.
function outputname() {
var x=document.getElementById("form1") ;
item = x.elements.namedItem("item").value;
if (item !== ""){
document.getElementById("output").innerHTML=item;
duplicater.style.display = "block";
document.getElementById("addTrade").style.left = "7px";
itemMkrWindow.style.display = "none";
}
}
</script>
.box {
display: none;
border-radius: 5px;
border-width: 1px;
border-color: black;
border-style: solid;
}
Cant Get What you are trying to do, but maybe this will help:
var i = 0;
var original = document.getElementById('duplicater');
function duplicate() {
i = i + 1;
var clone = original.cloneNode(true);
clone.id = "duplicetor" + ++i;
original.parentNode.appendChild(clone);
}
function outputname() {
var x=document.getElementById("form1") ;
item = x.elements.namedItem("item").value;
if (item !== ""){
var createdItem = document.createElement('P');
createdItem.setAttribute('id', 'output');
var text = document.createTextNode(item);
createdItem.appendChild(text);
var container = document.getElementById("duplicater");
container.appendChild(createdItem);
}
}
this would be CSS:
.box {
border-radius: 5px;
border-width: 1px;
border-color: black;
border-style: solid;
}
#output{
display: block;
background-color: red;
width: 100px;
height: 50px;
}
check this link also
I'm trying to make a Single Page Application with pure JavaScript (no additional frameworks or libraries). The problem is that the values I add to the TODO list are not storing in the localStorage (and are not showing).
I would appreciate any help with that task.
How can I simplify the code? (without using any additional libraries and frameworks (ex.jquery etc.))
Here is my code:
let inputTask = document.getElementById('toDoEl');
let editTask = document.getElementById('editTask');
let checkTask = document.getElementById('list');
let emptyList = document.getElementById('emptyList');
let items = [];
let id = [];
let labelToEdit = null;
const empty = 0;
let pages = ['index', 'add', 'modify'];
load();
function load() {
items = loadFromLocalStorage();
id = getNextId();
items.forEach(item => renderItem(item));
}
function show(shown) {
location.href = '#' + shown;
pages.forEach(function(page) {
document.getElementById(page).style.display = 'none';
});
document.getElementById(shown).style.display = 'block';
return false;
}
function getNextId() {
for (let i = 0; i<items.length; i++) {
let item = items[i];
if (item.id > id) {
id = item.id;
}
}
id++;
return id;
}
function loadFromLocalStorage() {
let localStorageItems = localStorage.getItem('items');
if (localStorageItems === null) {
return [];
}
return JSON.parse(localStorageItems);
}
function saveToLocalStorage() {
localStorage.setItem('items', JSON.stringify(items));
}
function setChecked(checkbox, isDone) {
if (isDone) {
checkbox.classList.add('checked');
checkbox.src = 'https://image.ibb.co/b1WeN9/done_s.png';
let newPosition = checkTask.childElementCount - 1;
let listItem = checkbox.parentNode;
listItem.classList.add('checked');
checkTask.removeChild(listItem);
checkTask.appendChild(listItem);
} else {
checkbox.classList.remove('checked');
checkbox.src = 'https://image.ibb.co/nqRqUp/todo_s.png';
let listItem = checkbox.parentNode;
listItem.classList.remove('checked');
}
}
function renderItem(item) {
let listItem = document.getElementById('item_template').cloneNode(true);
listItem.style.display = 'block';
listItem.setAttribute('data-id', item.id);
let label = listItem.querySelector('label');
label.innerText = item.description;
let checkbox = listItem.querySelector('input');
checkTask.appendChild(listItem);
setChecked(checkbox, item.isDone);
emptyList.style.display = 'none';
return listItem;
}
function createNewElement(task, isDone) {
let item = { isDone, id: id++, description: task };
items.push(item);
saveToLocalStorage();
renderItem(item);
}
function addTask() {
if (inputTask.value) {
createNewElement(inputTask.value, false);
inputTask.value = '';
show('index');
}
}
function modifyTask() {
if (editTask.value) {
let item = findItem(labelToEdit);
item.description = editTask.value;
labelToEdit.innerText = editTask.value;
saveToLocalStorage();
show('index');
}
}
function findItem(child) {
let listItem = child.parentNode;
let id = listItem.getAttribute('data-id');
id = parseInt(id);
let item = items.find(item => item.id === id);
return item;
}
// Chanhe img to checked
function modifyItem(label) {
labelToEdit = label;
editTask.value = label.innerText;
show('modify');
editTask.focus();
editTask.select();
}
function checkItem(checkbox) {
let item = findItem(checkbox);
if (item === null) {
return;
}
item.isDone = !item.isDone;
saveToLocalStorage();
setChecked(checkbox, item.isDone);
}
function deleteItem(input) {
let listItem = input.parentNode;
let id = listItem.getAttribute('data-id');
id= parseInt(id);
for (let i in items) {
if (items[i].id === id) {
items.splice(i, 1);
break;
}
}
if (items.length === empty) {
emptyList.style.display = 'block';
}
saveToLocalStorage();
listItem.parentNode.removeChild(listItem);
}
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
h2, li, #notification {
text-align: center;
}
h2 {
font-weight: normal;
margin: 0 auto;
padding-top: 20px;
padding-bottom: 20px;
}
#root {
width: 400px;
height: 550px;
margin: 0 auto;
position: relative;
}
#root>ul {
display: block;
}
#addButton {
display: block;
margin: 0 auto;
}
.checkbox, .delete {
height: 24px;
bottom: 0;
}
.checkbox {
float: left;
}
.delete {
float: right;
}
ul {
margin: 20px 30px 0 30px;
padding-top: 20px;
padding-left: 20px;
text-align: center;
}
#toDoEl {
width: 50%;
}
li {
width: 100%;
list-style: none;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
margin: 15px auto;
}
label {
margin: 0 auto;
text-align: justify;
text-justify: inter-word;
}
label:hover {
cursor: auto;
}
li.checked {
background-color: gray;
}
span.button {
cursor: pointer;
}
#add, #modify {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Homework 12 - Simple TODO List</title>
<link rel="stylesheet" href="./assets/styles.css">
</head>
<body>
<div id="root">
<!--Main page-->
<div id="index">
<h2>Simple TODO Application</h2>
<button class="button" id="addButton" onclick="show('add')">Add New Task</button>
<p id="emptyList">TODO is empty</p>
<ul id="list">
<li id="item_template" style="display: none">
<input class="checkbox" type="image" alt="checkbox" src="https://image.ibb.co/nqRqUp/todo_s.png" onclick="checkItem(this)">
<label onclick="modifyItem(this)"></label>
<input id="delete" class="delete" type="image" alt="remove" src="https://image.ibb.co/dpmqUp/remove_s.jpg" onclick="deleteItem(this)">
</li>
</ul>
</div>
<!--Add page-->
<div id="add">
<h2>Add Task</h2>
<input type="text" id="toDoEl">
<button class="button cancel" onclick="show('index')">Cancel</button>
<button class="button save" onclick="addTask()">Save changes</button>
</div>
<!--Modify page-->
<div id="modify">
<h2>Modify item</h2>
<input type="text" id="editTask">
<button class="button cancel" onclick="show('index')">Cancel</button>
<button class="button save" onclick="modifyTask()">Save changes</button>
</div>
</div>
<script src="./src/app.js"></script>
</body>
</html>
Your code does appear to work. If you console.log(JSON.parse(localStorageItems)) right above line 49 in the loadFromLocalStorage function, it shows as expected in the console. Also, upon refreshing the items persist.
If what you mean is that you're checking localStorage and you don't see the items, it might be that you're looking at the preview version of localStorage. (I'm assuming you're using Chrome.) Hover over the top of the empty section and pull down, this should reveal the values stored. If you click on one, it should show in the preview section. I think this was a Chrome dev tools UI change recently implemented.
I checked your code in Codepen and it works.