I am working on a web application where users can add multiple instances of the same subservice type to a table. Each instance should create a new separator with the subservice name in the table. The problem arises when I add the same subservice type multiple times with different names. Only the last name is displayed in the separator, and the previous instance’s line items are not shown.
I tried to generate unique IDs for each subservice instance and ensure that each separator is associated with the correct instance. I expected that each subservice instance would have its own separator and display all related line items. However, the separator only displays the last added instance’s name, and only its line items are shown in the table.
Current Code:
Here is my code for adding a new subservice and updating the separator name in the LV.
function addNewSubService(service) {
const subserviceContainer = document.getElementById(`${service}-subservices`);
if (!subserviceContainer) {
console.error(`Container für ${service} nicht gefunden`);
return;
}
const index = subserviceContainer.children.length;
const subserviceInstanceId = generateSubserviceInstanceId(service, index); // Eindeutige ID generieren
addSubService(service, index, subserviceInstanceId);
const nameElement = document.getElementById(`${service}-name-${index}`);
if (nameElement) {
nameElement.addEventListener('input', () => updateLvSeparator(service, nameElement.value));
}
// Füge die neue Teilleistung dem Leistungsverzeichnis hinzu
const teilleistungId = getTeilleistungenFromOffer({ subservices: [{ type: service.replace('-', '_'), instance_id: subserviceInstanceId }] });
loadLeistungsverzeichnis(teilleistungId, true); // Wichtig: append = true, damit bestehende Teilleistungen nicht überschrieben werden
}
function updateTeilleistungName(service, index, uniqueId) {
const serviceName = document.getElementById(`${service}-name-${index}-${uniqueId}`).value;
console.log(`Updating teilleistung name: ${serviceName} for service: ${service}, index: ${index}, uniqueId: ${uniqueId}`);
// Finde den richtigen Separator mit der passenden uniqueId
const separatorRow = document.querySelector(`tr.table-secondary[data-subservice-id="${uniqueId}"]`);
if (separatorRow) {
separatorRow.innerHTML = `<td colspan="7">Teilleistung ${serviceName}</td>`;
}
}
function addLvEntry(serviceType, serviceName) {
console.log(`Adding LV entry: ${serviceType}, serviceName: ${serviceName}`);
const lvBody = document.getElementById('lv-body');
const tr = document.createElement('tr');
tr.classList.add('teilleistung-entry');
tr.dataset.serviceType = serviceType;
tr.innerHTML = `
<td colspan="7" class="teilleistung-header">Teilleistung ${serviceName}</td>
`;
lvBody.appendChild(tr);
}
function generateSubserviceInstanceId(service, index) {
return `${service}-${index}-${Date.now()}`;
}
function loadLeistungsverzeichnis(teilleistungen, append = false) {
fetch(`/api/leistungsverzeichnis?teilleistungen=${teilleistungen}`)
.then(response => response.json())
.then(data => {
const lvBody = document.getElementById('lv-body');
// Wenn nicht angehängt wird, clear das LV-Body
if (!append) {
lvBody.innerHTML = '';
}
const existingLvIds = new Set();
lvBody.querySelectorAll('tr').forEach(row => {
existingLvIds.add(row.dataset.lvId);
});
let currentTeilleistung = '';
let currentTeilleistungName = ''; // To store the name of the current subservice
data.forEach(lv => {
if (!existingLvIds.has(lv.id.toString())) {
// Add separator if the teilleistung has changed
if (lv.teilleistung !== currentTeilleistung || lv.teilleistung_name !== currentTeilleistungName) {
currentTeilleistung = lv.teilleistung;
currentTeilleistungName = lv.teilleistung_name;
const separatorRow = document.createElement('tr');
separatorRow.classList.add('table-secondary');
separatorRow.innerHTML = `<td colspan="7">Teilleistung ${currentTeilleistung} - ${currentTeilleistungName}</td>`;
lvBody.appendChild(separatorRow);
}
// Create and append the LV row
const row = createLvRow(lv, false);
lvBody.appendChild(row);
}
});
})
.catch(error => {
console.error('Fehler beim Laden des Leistungsverzeichnisses:', error);
});
}
function createLvRow(lv, isSaved = false) {
const row = document.createElement('tr');
row.dataset.lvId = lv.lv_id ? lv.lv_id : lv.id;
row.dataset.subserviceInstanceId = lv.subservice_instance_id;
row.innerHTML = `
<td>${row.dataset.lvId}</td>
<td class="text-column"><textarea class="form-control dynamic-height" ${isSaved ? 'data-saved="true"' : ''}>${lv.text}</textarea></td>
<td class="turnus-column"></td>
<td class="qm-column"></td>
<td class="ae-column"></td>
<td class="storno-column"></td>
<td>
${isSaved ? `<button class="btn btn-danger" onclick="deleteLvRow('${row.dataset.lvId}', true)">Löschen</button>` : `<button class="btn btn-danger" onclick="deleteLvRow('${row.dataset.lvId}', false)">Löschen</button>`}
</td>
`;
const textArea = row.querySelector('textarea');
if (!isSaved) {
textArea.addEventListener('input', function () {
adjustHeight(this);
markLvRowAsChanged(row); // Zeile als geändert markieren
});
adjustHeight(textArea);
}
const turnusCell = row.querySelector('.turnus-column');
if (lv.show_turnus) {
const turnusDropdown = createTurnusDropdown(lv.turnus);
turnusDropdown.value = lv.turnus || 'w1';
turnusDropdown.addEventListener('change', function () {
markLvRowAsChanged(row); // Zeile als geändert markieren
});
turnusCell.appendChild(turnusDropdown);
}
const qmCell = row.querySelector('.qm-column');
if (lv.show_qm) {
const qmInput = document.createElement('input');
qmInput.type = 'number';
qmInput.className = 'form-control';
qmInput.value = lv.qm || '';
qmInput.addEventListener('change', function () {
markLvRowAsChanged(row); // Zeile als geändert markieren
});
qmCell.appendChild(qmInput);
}
const aeCell = row.querySelector('.ae-column');
if (lv.show_ae) {
const aeCheckbox = document.createElement('input');
aeCheckbox.type = 'checkbox';
aeCheckbox.checked = lv.ae || false;
aeCheckbox.addEventListener('change', function () {
markLvRowAsChanged(row); // Zeile als geändert markieren
});
aeCell.appendChild(aeCheckbox);
}
const stornoCell = row.querySelector('.storno-column');
if (lv.show_storno) {
const stornoCheckbox = document.createElement('input');
stornoCheckbox.type = 'checkbox';
stornoCheckbox.checked = lv.storno || false;
stornoCheckbox.addEventListener('change', function () {
markLvRowAsChanged(row); // Zeile als geändert markieren
});
stornoCell.appendChild(stornoCheckbox);
}
return row;
}
How can I adjust my code to solve this problem?