Reputation: 15
I want to make a button that adds and removes items. The 'Delete form' button changes to 'Add form' after click it. But after I've deleted and added forms, I want to delete forms again, but for reasons I don't understand, it doesn't happen.
I'm using the latest chrome browser version.
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<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">
<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">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<title>Task 1</title>
</head>
<body style="height: 100%">
<div class="container h-100">
<div class="row h-100 justify-content-center align-content-center">
<div class=""><button type="button" class="btn btn-primary">Open Google</button></div>
<div class=""><button type="button" class="btn btn-danger" id="danger">Delete form</button></div>
<div class="breaker w-100" style="height:10%;"></div>
<form id="form">
<div class="form-group">
<label for="formGroupExampleInput">Example label</label>
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Another label</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">
</div>
</form>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
document.getElementsByClassName('btn-primary')[0].addEventListener("click", open_google);
document.getElementsByClassName('btn-danger')[0].addEventListener("click", delete_function);
let inner_form = document.getElementById('form').innerHTML;
function open_google() {
window.open('http://google.com', '_blank');
}
let buttons;
function button_change(button) {
switch(button) {
case "success":
buttons = document.getElementsByClassName('btn');
buttons[1].innerHTML = 'Add form';
buttons[1].className = 'btn btn-success';
document.getElementsByClassName('btn-success')[0].addEventListener("click", add_function);
break;
case "danger":
buttons = document.getElementsByClassName('btn');
buttons[1].innerHTML = 'Delete form';
buttons[1].className = 'btn btn-danger';
break;
default:
break;
}
}
function delete_function() {
let element = document.getElementById('form');
while (element.firstChild) {
element.removeChild(element.firstChild);
}
button_change("success");
}
function add_function() {
document.getElementById('form').innerHTML = inner_form;
button_change("danger");
}
Example code: https://codepen.io/anon/pen/xNjPYj
Upvotes: 0
Views: 87
Reputation: 46
This implementation will do the text and context switching you desire.
function action(mouseevent) {
const button = mouseevent.target;
let element = document.getElementById('form');
if(element.firstChild) {
while (element.firstChild) {
element.removeChild(element.firstChild);
}
button.innerHTML = 'Add form';
button.classList.remove('btn-danger');
button.classList.add('btn-success');
} else {
document.getElementById('form').innerHTML = inner_form;
button.innerHTML = 'Delete Form';
button.classList.add('btn-danger');
button.classList.remove('btn-success');
}
}
Upvotes: 0
Reputation: 222
The main issue with your code was that the event listeners kept getting added but not removed, this caused them to pile up and run unpredictably. I added a function that determines what state the button is in and performs the correct function add_function
or remove_function
.
I also changed a few minor things
innerHTML
to textContent
where possible for securitybutton.classList.add
and button.classList.remove
button_change
function because it was difficult to refactorhttps://codepen.io/anon/pen/BexJZW
JavaScript:
document.getElementsByClassName('btn-primary')[0].addEventListener("click", open_google);
let inner_form = document.getElementById('form').innerHTML;
let add_delete_button = document.querySelector('#add-delete-button');
add_delete_button.addEventListener("click", on_add_delete_clicked);
function open_google() {
window.open('http://google.com', '_blank');
}
function on_add_delete_clicked() {
let is_adding = add_delete_button.classList.contains("btn-success");
if (is_adding) {
add_function();
} else {
delete_function();
}
}
function add_function() {
const button = add_delete_button;
document.getElementById('form').innerHTML = inner_form;
// Update button
button.textContent = 'Delete form';
button.classList.remove("btn-success");
button.classList.add("btn-danger");
}
function delete_function() {
let element = document.getElementById('form');
while (element.firstChild) {
element.removeChild(element.firstChild);
}
// Update button
const button = add_delete_button;
button.textContent = 'Add form';
button.classList.remove("btn-danger");
button.classList.add("btn-success");
}
HTML:
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<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">
<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">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<title>Task 1</title>
</head>
<body style="height: 100%">
<div class="container h-100">
<div class="row h-100 justify-content-center align-content-center">
<div class=""><button type="button" class="btn btn-primary">Open Google</button></div>
<div class=""><button type="button" class="btn btn-danger" id="add-delete-button">Delete form</button></div>
<div class="breaker w-100" style="height:10%;"></div>
<form id="form">
<div class="form-group">
<label for="formGroupExampleInput">Example label</label>
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Another label</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">
</div>
</form>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
Upvotes: 0
Reputation: 597
The event listeners aren't being removed, so both functions are being called (potentially multiple times) depending on how many times the buttons are clicked.
Personally, I think it would be easier to create two buttons, each with independent click handlers, and hide/show them according to which one was clicked.
However, to resolve the current issue in your code, you'll need to remove the previous event listener using removeEventListener() before attaching the new one.
Upvotes: 2
Reputation: 98
Why don't you just hide it? This is much easier
function toggle() {
var element = document.getElementById("form");
if (element.style.display === "none") {
element.style.display = "block";
}
else {
element.style.display = "none";
}
}
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<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">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<title>Task 1</title>
</head>
<body style="height: 100%">
<div class="container h-100">
<div class="row h-100 justify-content-center align-content-center">
<div class=""><button type="button" class="btn btn-primary">Open Google</button></div>
<div class=""><button onclick="toggle()" type="button" class="btn btn-danger" id="danger">Delete form</button></div>
<div class="breaker w-100" style="height:10%;"></div>
<form id="form">
<div class="form-group">
<label for="formGroupExampleInput">Example label</label>
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">
</div>
<div class="form-group">
<label for="formGroupExampleInput2">Another label</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">
</div>
</form>
</div>
</div>
</body>
</html>
Upvotes: 0