Abdulkhay Khabibulin
Abdulkhay Khabibulin

Reputation: 15

Reuse function to delete an item

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

Answers (4)

Daniel Lopez
Daniel Lopez

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

Nicole M
Nicole M

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

  • Now usesinnerHTML to textContent where possible for security
  • Button classes are updated using button.classList.add and button.classList.remove
  • The button is found using an ID instead of an unreliable classname
  • The button is held in a variable instead of continuing the look for it
  • Removed the button_change function because it was difficult to refactor

https://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

Dale Harris
Dale Harris

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

Karmakip
Karmakip

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

Related Questions