Ad

Jquery: Append Creates Multiple New Elements In Elements Before When Clicked

- 1 answer

I'm creating a personal use website where I want to add "modules" or groups in which I can add links.

The problem I'm facing is when I add a group and start adding links, it all works fine. However when I add another group, afterwards add a link in the first group, it will add two links instead of one (in the first group) but adding a link in the second group adds one.

This scales up with however many groups I have, the last group always works as intended, but the groups before adds additional links to however many groups are underneath itself.

I'd really appreciate any help to understand the problem as I've been going at this for way too long without any progress.

const moduleHTML =
  '<div class="module"> \
    <div class="module-head"> \
        <img class="module-head-logo" src=""> \
        <h2 class="module-head-name">Group name</h2> \
        <img class="module-head-cancel" src="assets/close_white_24dp.svg"> \
        <img class="module-head-delete" src="assets/delete_white_24dp.svg"> \
        <img class="module-head-save" src="assets/save_white_24dp.svg"> \
    </div> \
    <div class="module-body"> \
        <p class="module-body-container-edit-add">Add new link...</p> \
    </div> \
</div>';

const linkHTML =
  '<div class="module-body-container-outer"> \
    <div class="module-body-container"> \
        <div class="module-body-container-edit-name"> \
            <img class="module-body-container-image" src=""> \
            <input type="text" maxlength="16" placeholder="Name..."> \
            <img class="module-body-container-edit-delete" src="assets/delete_white_24dp.svg"> \
        </div> \
            <div class="module-body-container-edit-link"> \
            <img class="module-body-container-image" src="assets/link_white_24dp.svg"> \
            <input type="url" placeholder="Link..."> \
        </div> \
    </div> \
</div>';


$(document).ready(function() {
  console.log("ready!");

  $('.module-add').on('click', function() {
    console.log('add module');
    $("#module-container").append(moduleHTML);

    $('.module-head-delete').on('click', function() {
      console.log('delete module');
      $(this).closest(".module").remove();
    });

    $(".module-body-container-edit-add").click(function() {
      console.log("add link");
      $(this).closest(".module-body").append(linkHTML);

      $('.module-body-container-edit-delete').on('click', function() {
        console.log('delete link');
        $(this).closest(".module-body-container-outer").remove();
      });
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>

<html>

<head>
  <title>Daily Links</title>
  <link rel="stylesheet" target="_blank" rel="nofollow noreferrer" href="styles.css">
  <script type="text/javascript" src="jquery-3.6.0.js">
  </script>
  <script type="text/javascript" src="scripts.js"></script>
</head>

<body>
  <header class="header-container">
    <h1>Daily Links</h1>
    <input type="submit" class="module-add" value="Add module">
  </header>
  <div id="module-container">
  </div>
</body>

</html>

Ad

Answer

Every time you click on the Add module button you execute

$('.module-body-container-edit-delete').on('click', function...);

This adds another click handler to all the previously created Add new link buttons, so they execute the handler function multiple times, which creates multiple links.

Use event delegation rather than adding a handler every time. See Event binding on dynamically created elements?

$(document).ready(function() {
  console.log("ready!");

  $('.module-add').on('click', function() {
    console.log('add module');
    $("#module-container").append(moduleHTML);

    $('.module-head-delete').on('click', function() {
      console.log('delete module');
      $(this).closest(".module").remove();
    });
  });

  $("#module-container").on("click", ".module-body-container-edit-add", function() {
    console.log("add link");
    $(this).closest(".module-body").append(linkHTML);
  });

  $('#module-container').on('click', '.module-body-container-edit-delete', function() {
    console.log('delete link');
    $(this).closest(".module-body-container-outer").remove();
  });
});

const moduleHTML =
  '<div class="module"> \
    <div class="module-head"> \
        <img class="module-head-logo" src=""> \
        <h2 class="module-head-name">Group name</h2> \
        <img class="module-head-cancel" src="assets/close_white_24dp.svg"> \
        <img class="module-head-delete" src="assets/delete_white_24dp.svg"> \
        <img class="module-head-save" src="assets/save_white_24dp.svg"> \
    </div> \
    <div class="module-body"> \
        <p class="module-body-container-edit-add">Add new link...</p> \
    </div> \
</div>';

const linkHTML =
  '<div class="module-body-container-outer"> \
    <div class="module-body-container"> \
        <div class="module-body-container-edit-name"> \
            <img class="module-body-container-image" src=""> \
            <input type="text" maxlength="16" placeholder="Name..."> \
            <img class="module-body-container-edit-delete" src="assets/delete_white_24dp.svg"> \
        </div> \
            <div class="module-body-container-edit-link"> \
            <img class="module-body-container-image" src="assets/link_white_24dp.svg"> \
            <input type="url" placeholder="Link..."> \
        </div> \
    </div> \
</div>';
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>

<html>

<head>
  <title>Daily Links</title>
  <link rel="stylesheet" target="_blank" rel="nofollow noreferrer" href="styles.css">
  <script type="text/javascript" src="jquery-3.6.0.js">
  </script>
  <script type="text/javascript" src="scripts.js"></script>
</head>

<body>
  <header class="header-container">
    <h1>Daily Links</h1>
    <input type="submit" class="module-add" value="Add module">
  </header>
  <div id="module-container">
  </div>
</body>

</html>

Ad
source: stackoverflow.com
Ad