'Accessing Element previously appended to the DOM?

I have the following HTML structure in two modals on my website - one for adding new datasets and one for editing existing datasets:

HTML (add) is added to the DOM via TWIG Syntax

<div class="mb-3" id="bar_area-add">
    <div class="card">
        <div class="card-body">
            <h3 class="float-start">Thekendienst</h3>
            <div class="float-end">
                <button class="btn btn-sm btn-primary" type="button" id="bar_plus-add">
                    <i class="bi-plus-lg"></i>
                </button>
                <button class="btn btn-sm btn-danger" type="button" id="bar_minus-add">
                    <i class="bi-dash-lg"></i>
                </button>
            </div>
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>Zeitfenster</th>
                        <th>MAs</th>
                    </tr>
                </thead>
                <tbody id="bar_multiple-add">
                    <tr id="bar_placeholder-add" style="display: none;">
                        <td colspan="2">aktuell keine Position(en) verfügbar</td>
                    </tr>
                    <tr id="bar_shift_1-add">
                        <td><input type="text" name="bar_timewindow_1" value="21:00-24:00" required=""></td>
                        <td><input type="number" min="0" name="bar_amountma_1" value="2" required=""></td>
                        <input type="hidden" name="bar_id_1" value="3" required="">
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

HTML (edit) is appended to the DOM via JQuery.append() function

<div class="mb-3" id="bar_area-edit" style="">
    <div class="card">
        <div class="card-body">
            <h3 class="float-start">Thekendienst</h3>
            <div class="float-end">
            <button class="btn btn-sm btn-primary" type="button" id="bar_plus-edit">
                <i class="bi-plus-lg"></i>
            </button>
            <button class="btn btn-sm btn-danger" type="button" id="bar_minus-edit">
                <i class="bi-dash-lg"></i>
            </button>
            </div>
            <table class="table table-striped">
            <thead>
                <tr>
                    <th>Zeitfenster</th>
                    <th>MAs</th>
                </tr>
            </thead>
            <tbody id="bar_multiple-edit">
                <tr id="bar_placeholder-edit" style="display: none;">
                    <td colspan="2">aktuell keine Position(en) verfügbar</td>
                </tr>
                <tr id="bar_shift_1-edit">
                    <td><input type="text" name="bar_timewindow_1" value="21:00-24:00" required=""></td>
                    <td><input type="number" min="0" name="bar_amountma_1" value="2" required=""></td>
                    <input type="hidden" name="bar_id_1" value="3" required="">
                </tr>
            </tbody>
        </table>
        </div>
    </div>
</div>

As you can see, I also have 2 Buttons in both structures to add oder remove lines - it´s a kind of dynamic formfield. For this purpose I have written the following JQuery-Function:

var tasks = ['add', 'edit'];
var services = {{ services | json_encode | raw }};
    
tasks.forEach(task => {
    services.forEach(service => {
        $("#" + service.shortname + "_plus-" + task).click(function () {
            $("#" + service.shortname + "_multiple-" + task).each(function () {
                var i = $(this).find("tr").length;
                var n = (i - 1);
                $(this).append('<tr id="' + service.shortname + '_shift_' + (n + 1) + '-' + task + '">\n' +
                    '<td><input type="text" name="' + service.shortname + '_timewindow_' + (n + 1) + '" value="00:00-00:00" required></td>\n' +
                    '<td><input type="number" min="0" name="' + service.shortname + '_amountma_' + (n + 1) + '" value="0" required></td>\n' +
                    '</tr><input type="hidden" name="' + service.shortname + '_id_' + (n + 1) + '" value="' + service.id + '" required>');
                if (n === 0) {
                    $("#" + service.shortname + "_placeholder-" + task).hide();
                }
            });
        });

        $("#" + service.shortname + "_minus-" + task).click(function () {
            $("#" + service.shortname + "_multiple-" + task).each(function () {
                var i = $(this).find("tr").length;
                var n = i;
                if (n !== 0) {
                    $("#" + service.shortname + '_shift_' + (n - 1) + '-' + task).remove();
                    if (n === 2) {
                        $("#" + service.shortname + "_placeholder-" + task).show();
                    }
                }
            });
        });
    });
});

Unfortunately this only works for the add-task, when clicking on add/remove button in the edit modal nothing happens. There´s no error message. I think this could be a result of adding edit-structure with Jquery.append() to the DOM like this.

$.ajax({
    url: '/getJobs/' + eventClickEvent.event.id,
    type: 'get',
    success: function (jobData) {
        var jobs = JSON.parse(jobData);
        var services = {{ services | json_encode | raw }};
        services.forEach(service => {
            $('#areas-edit').append(`<div class="mb-3" id="` + service.shortname + `_area-edit" style="display: none;">
                        <div class="card">
                            <div class="card-body">
                                <h3 class="float-start">` + service.name + `</h3>
                                <div class="float-end">
                                <button class="btn btn-sm btn-primary" type="button"
                                    id="` + service.shortname + `_plus-edit">
                                    <i class="bi-plus-lg"></i>
                                </button>
                                <button class="btn btn-sm btn-danger" type="button"
                                    id="` + service.shortname + `_minus-edit">
                                    <i class="bi-dash-lg"></i>
                                </button>
                                </div>
                                <table class="table table-striped">
                                <thead>
                                    <tr>
                                        <th>Zeitfenster</th>
                                        <th>MAs</th>
                                    </tr>
                                </thead>
                                <tbody id="` + service.shortname + `_multiple-edit">
                                    <tr id="` + service.shortname + `_placeholder-edit">
                                        <td colspan="2">aktuell keine Position(en) verfügbar</td>
                                    </tr>
                                </tbody>
                            </table>
                                </div>
                            </div>
                        </div>`);
            var i = 1;
            jobs.forEach(job => {
                if (service.id === job.serviceId) {
                    $('#' + service.shortname + '-editPill').addClass('bg-primary');
                    $('#' + service.shortname + '-editPill').removeClass('bg-secondary');
                    $('#' + service.shortname + '_area-edit').show();
                    $('#' + service.shortname + '_placeholder-edit').hide();
                    $('#' + service.shortname + '_multiple-edit').append(`
                                    <tr id="` + service.shortname + `_shift_` + i + `-edit">
                                        <td><input type="text"
                                                name="` + service.shortname + `_timewindow_` + i + `"
                                                value="` + job.timewindow + `" required></td>
                                        <td><input type="number" min="0"
                                                name="` + service.shortname + `_amountma_` + i + `"
                                                value="` + job.mas + `" required></td>
                                        <input type="hidden" name="` + service.shortname + `_id_` + i + `"
                                            value="` + service.id + `" required>
                                    </tr>
                                `);
                    i++;
                }
            });
        });
}
});


Solution 1:[1]

You have jQuery, use it. Delegate or something like this

$(".service").on("click", function() {
  $(".task", this).each(function() {
      if (this.id.includes("plus")) {
        var len = $(this).find("tr").length;
        ...
      }
      if (n === 0) {
        $(this).find("[id*='_placeholder-']).hide();
        }

      })
  }
  else if (this.id.includes("_multiple") {
      ...
    }
  });
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mplungjan