Button Loosing Reference after .appendChild - javascript

I want to make recursive Modals with vanilla JS, i.e there's a button in each modal that opens another Modal inside the current Modal.
So, I've a button that appends a div in a main parent div.
The problem is that the button loses it's onClick Property.
Can somebody please explain, why's this happening.
var modal = document.getElementById('myModal');
console.log("InitButton",modal);
var modalParent = document.querySelector('.modalParent');
console.log("ModalParent",modalParent);
var initBtn = document.getElementById("initialModal");
console.log("InitButton",initBtn);
var btn = document.getElementById("modalButton");
console.log("InitButton",btn);
modalParent.addEventListener('click',clickHandler)
initBtn.onclick = function() {
modal.style.display = "block";
}
var i = 0
function clickHandler(e){
if(e.target.matches('.modalButton')){
clone = modal.cloneNode(true);
clone.id = "new_Clone_" + i;
console.log("ClassName", clone.id);
modalParent.appendChild(clone);
i++;
}
}
This is the JS file
The HTML file is
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>
<div class="Head">
<button id = "initialModal">Open Modal</button>
<div class="modalParent" id = "modalParent">
<div class="modal" id = "myModal">
<div class="modal-content">
<p>Some Text in Modal</p>
<button id = "modalButton">Open Modal</button>
</div>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>

Your issue was basically this line (matches is used wrongly)
if(e.target.matches('.modalButton')){ //you are matching a class while the modalButton has an id
Also as per same doc (link shared above) this is a non-standard API, so replace it with simple match
if (e.target.id.match('modalButton'))
var modal = document.getElementById('myModal');
console.log("InitButton", modal);
var modalParent = document.querySelector('.modalParent');
console.log("ModalParent", modalParent);
var initBtn = document.getElementById("initialModal");
console.log("InitButton", initBtn);
var btn = document.getElementById("modalButton");
console.log("InitButton", btn);
modalParent.addEventListener('click', clickHandler);
initBtn.onclick = function() {
modal.style.display = "block";
};
var i = 0;
function clickHandler(e)
{
if (e.target.id.match('modalButton'))
{
clone = modal.cloneNode(true);
clone.id = "new_Clone_" + i;
console.log("ClassName", clone.id);
modalParent.appendChild(clone);
i++;
}
}
<div class="Head">
<button id="initialModal">Open Modal</button>
<div class="modalParent" id="modalParent">
<div class="modal" id="myModal">
<div class="modal-content">
<p>Some Text in Modal</p>
<button id="modalButton">Open Modal</button>
</div>
</div>
</div>
</div>

Related

How to get elements from a cloned div

I have a div I have cloned that has elements inside it. I want to get the heading (h2) value out of the second child in the div
How do I go about this? I want to get the "bent over row" value from <div class="heading_add"><h2>Bent over row</h2>
// Make heading and button
let headingDiv = document.createElement('div');
headingDiv.classList = "heading_add"
let newh2 = document.createElement('h2');
newh2.innerHTML = itemRef.name;
headingDiv.appendChild(newh2)
videoCard.appendChild(headingDiv)
// Clones the div with video
newBtn.addEventListener('click', () =>{
const exercises = document.querySelector('.exercises');
let clone = videoCard.cloneNode(true); //Clones the div tags I'm trying to get
clone.defaultMuted = true;
let firstKid = clone.firstChild;
let secondChild = firstKid.firstChild.muted = true;
let meTest = firstKid.firstChild;
clone.classList.add('newVid');
console.log(meTest)
exercises.appendChild(clone)
});
<div class="videoCard newVid">
<div class="vid">
<video src="videostoredinfirebase" width="300" class="videoAdded" autoplay="" loop=""></video>
</div>
<div class="heading_add"><h2>Bent over row</h2>
<button class="add_video_btn">+</button></div>
</div>
Quick and dirty fix
function add() {
var myDiv = document.getElementById("test");
var divClone = myDiv.cloneNode(true);
document.body.appendChild(divClone);
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<script src="script.js" charset="utf-8"></script>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="test">
<h2>
This is a div
</h2>
</div>
<button onclick="add()">+</button>
</body>
</html>

Adding an 'active-class' to a list which is inputted by user

Hello im new to Javascript and trying out some different things.
I have a ul which the user can input some li:s.
My goal is to set a li class of active and then removing it by referencing it to the active class. Like a To-Do list but light.
I've tried alot of different approaches and the code below is what I got right now which isn't working properly... The first function just adds things to the list and the second should give a li element the class of active.
The removing part I'm hoping to solve by myself..
Im very thankful for any input. Thanks!
function addElementLast (){
let textValue = document.getElementById('candidate').value;
if(textValue == ''){
alert('Type something')
}else{
let newLi = document.createElement('li')
newLi.setAttribute('class', 'toggle');
let get = document.getElementsByTagName('ul')[0];
let textNode = document.createTextNode(textValue);
newLi.appendChild(textNode);
get.appendChild(newLi);
}}
var parent = document.getElementById("dynamic-list");
var child = parent.getElementsByClassName("toggle");
for (var i = 0; i < child.length; i++) {
child[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
if (current.length > 0) {
current[0].className = current[0].className.replace(" active", "");
}
this.className += " active";
});
}
document.getElementById('btn').addEventListener('click', addElementLast)
<!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>Adding to ul</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2 id="heading" class="text-center">Adding to UL</h2>
<ul id="dynamic-list">
</ul>
<input type="text" id="candidate" placeholder="Write here">
<button type="button" id="btn" class="btn btn-success">Add item</button>
<button type="button" id="btn1" class="btn btn-danger">Remove item</button>
</div>
<script src="script.js"></script>
</body>
</html>
I think you'd be better off if you manipulated a list in JS and just rendered an HTML "template" to the UI.
It's faster, easier to keep track of items and much easier to change the algorithms.
let todoList = []
// adding to the todo list
function addTodo(s, arr) {
if (s) {
arr.push({
text: s,
active: false
})
}
return arr
}
// creating the html that should be rendered
function createTodoListHTML(arr) {
let html = ''
arr.forEach(e => {
const active = e.active ? ' active' : ''
html += `<li class="item${active}">${e.text}</li>`
})
return html
}
// rendering the list
function displayTodoList(html) {
document.getElementById('dynamic-list').innerHTML = html
activate(todoList)
}
// handling add item btn click
document.getElementById('btn').addEventListener('click', function(e) {
let input = document.getElementById('candidate')
addTodo(input.value, todoList)
displayTodoList(createTodoListHTML(todoList))
input.value = ''
})
// adding event listener to li items
function activate(list) {
const children = document.querySelectorAll('#dynamic-list .item')
children.forEach((e, i) => {
e.addEventListener('click', function(el) {
todoList[i].active = !todoList[i].active
displayTodoList(createTodoListHTML(todoList))
})
})
}
// removing items from the list and the UI
const btnRemove = document.getElementById('btn1')
btnRemove.addEventListener('click', function(e) {
todoList = removeItems(todoList)
displayTodoList(createTodoListHTML(todoList))
})
function removeItems(arr) {
return arr.filter(e => !e.active)
}
.active {
font-weight: 700;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container">
<h2 id="heading" class="text-center">Adding to UL</h2>
<ul id="dynamic-list">
</ul>
<input type="text" id="candidate" placeholder="Write here">
<button type="button" id="btn" class="btn btn-success">Add item</button>
<button type="button" id="btn1" class="btn btn-danger">Remove item</button>
</div>
<script src="script.js"></script>

Count key presses and display them in HTML

I made a simple "spacebar simulator" game with HTML and JavaScript. Every time the user presses spacebar an image is replaced with another one, and when the key is released it is reset to the original image.
I would like to add a counter to the page, which counts the number of times the user has pressed spacebar. The source code is below:
var myRealUrl = "./assets/spacebar.png";
$("body").on("keydown", function (e) {
if(e.which == 32){
$("#spacebar").attr("src", "./assets/spacebar_pressed.png")
}
});
$("body").keyup(function (e) {
$("#spacebar").attr("src", myRealUrl)
});
var button = document.getElementById('counter'),
count = 0;
button.onclick = function() {
count += 1;
button.innerHTML = "Click me: " + count;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="utf-8">
<title></title>
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400" rel="stylesheet">
<link rel="stylesheet" href="css/stylesheet.css">
<script src="js/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="container">
<div class="title">
<h1>Spacebar Simulator 2018</h1>
<span id="counter"><p></p></span>
</div>
<img src="assets/spacebar.png" id="spacebar">
<p>Pressed</p><p id="counter">0</p><p> times.</p>
<footer>
<p>© 2018</p>
</footer>
</div>
<script src="js/spacebar.js"></script>
</body>
</html>
So set up a page level variable and increment it in the keydown event handler.
Your attempt at the "button" click code didn't work because the p element that needed to be clicked had no content inside of it, so it wasn't rendering on the screen and therefore there was nothing to click on.
Also, you can't have more than one element with the same id and it's invalid to put a p inside of a span.
var counter = 0; // Variable to hold the count
var myRealUrl = "./assets/spacebar.png";
var count = document.getElementById('counter');
$("body").on("keydown", function (e) {
if(e.which == 32){
counter++; // Increment the counter
$("#spacebar").attr("src", "./assets/spacebar_pressed.png");
count.textContent = counter; // Log the count
}
});
$("body").keyup(function (e) {
$("#spacebar").attr("src", myRealUrl)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="utf-8">
<title></title>
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400" rel="stylesheet">
<link rel="stylesheet" href="css/stylesheet.css">
<script src="js/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="container">
<div class="title">
<h1>Spacebar Simulator 2018</h1>
</div>
<img src="assets/spacebar.png" id="spacebar">
<p>Pressed <span id="counter">0</span> times.</p>
<footer>
<p>© 2018</p>
</footer>
</div>
<script src="js/spacebar.js"></script>
</body>
</html>

I want to display the badge number dynamically using javascript for bootstrap button

In CSS though I have given the badge number as 0, dynamically it should be changed by jQuery/JavaScript. Following code I tried but that didn't work:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body onload='preventDefault()'>
<div class="container">
<button class="btn btn-sm btn-default like-btn active" type="button" id="10">
<span class="text">Alert</span>
<span class="badge like-badge">0</span>
</button>
</div>
<script>
preventDefault = function(){
var btnText = $(this).find(".btn-text")
var badge = $(this).find(".like-badge")
var count = parseInt(badge.text());
if ($(this).hasClass('active')) {
btnText.text("Like");
badge.text(2);
$(this).removeClass('active');
}
else {
btnCaption.text("Liked");
badge.text(count + 1);
$(this).addClass('active');
}
}
</script>
</body>
</html>
I have correct some code snippet..
<button class="btn btn-sm btn-default like-btn active" onclick="preventDefault()" type="button" id="10">
<span class="btn-text">Alert</span>
<span class="badge like-badge">0</span>
</button>
added btn-text for button text.
javascript corrections:
preventDefault = function(){
var btn = $('.btn');
var btnText = $(this).find(".btn-text")
var badge = $(".like-badge");
var count = parseInt(badge.text());
console.log(count);
if (btn.hasClass('active')) {
btnText.text("Like");
badge.text(2);
btn.removeClass('active');
}else {
btnText.text("Liked");
badge.text(count + 1);
btn.addClass('active');
}
}
added var btn = $('.btn'); for selecting button element.
called btn instead $(this) in if condition.
Hurray!! code works for me.
Please check if it satisfy you.

Resize an image from data entered in a textbox

ive a form with a image , button and textbox. ive to resize the images height and width to what ever is entered in the textbox, when the button is clicked. My image just disappears when the button is clicked.
heres my code
<!DOCTYPE HTML>
<html>
<head>
<title>Resize Image</title>
</head>
<body>
<script>
function resizeimage()
{
var theImg = document.getElementById('image');
theImg.height = size;
theImg.width = size;
}
var size=parseInt(document.getElementById('txtbox'));
</script>
<form name ="ResizeImage">
<img src = "cookie.jpg" id="image">
</br>
<input type=button value="Resize" onclick="resizeimage()">
</br>
<input type=text id="txtbox"
</form>
</body>
</html>
Apart from the HTML problems (please run it through the validator), the main problem is that the part of code that reads the size of the image is outside of the function. On page load, this is what happens.
The function resizeimage() is defined
The var size is set to whatever is in the input at that point
The contents of the page are loaded.
At 2. the input doesn't even exist yet because 3. isn't done yet, so var size is set to undefined. It never changes after that, because the function resizeimage() does not try to read the size of the image again.
Also, document.getElementById returns an element. You will have to read what the user put into it by using it's .value property
Try this:
function resizeimage()
{
var size=parseInt(document.getElementById('txtbox').value);
var theImg = document.getElementById('image');
theImg.height = size;
theImg.width = size;
}
Working example: http://jsfiddle.net/KZH5p/
I would cache the ids first:
var input = document.getElementById('txtbox');
var theImg = document.getElementById('image');
function resizeimage() {
var size = input.value;
theImg.height = size;
theImg.width = size;
}
function changeDogsSize() {
var dogSize = parseInt((id_input).value);
id_dog.width = dogSize;
}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container bg-light mt-3"></div>
<!--changing dogs image-->
<div class="container">
<img id="id_dog" src="https://i.pinimg.com/originals/e4/9d/75/e49d755afcd02cdbf39d374b42a10ecd.jpg" alt="dog">
<input id="id_input" type="text" class="form-control mt-4" id="exampleInputAmount" placeholder="enter img width">
<button id="id_changeBtn" onclick="changeDogsSize()" type="button" class="btn btn-secondary btn-lg mt-3 text-dark">Change</button>
</div>
</body>
</html>

Categories