I have a table made with js based on data from 2 arrays of objects that I have.
One of the arrays contains all the subzones
and the second array contains microzones
, microzones
can be children of the same subzone
.
I made a function that builds a table so that the data will be placed like this in the table(take into consideration that the row-span in this example for SI-N1
is 3 while microzone column has 3 rows for microzone 1,2 and 3 since they are children of subzone SI-N1
)
Sub-zone | Micro-Zone |
---|---|
SI-N4 | CONCEPCION |
SI-N1 | microzone 1 |
microzone 2 | |
microzone 3 |
My code works when I’m just displaying the data like this
const subZones = [
{
"creationUserId": 1913,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "SI-N4",
"id": 65,
"creationDate": "2022-12-08 13:04:23"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateDate": "2019-12-18 10:39:27",
"lastUpdateUserId": 2,
"active": true,
"description": "SI-N1",
"id": 1,
"controlId": "9",
"creationDate": "2019-11-15 15:03:09"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "OF-N3",
"id": 49,
"creationDate": "2020-11-26 16:44:41"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "PU-N2",
"id": 28,
"controlId": "18",
"creationDate": "2019-12-18 11:39:44"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "PU-N1",
"id": 29,
"controlId": "19",
"creationDate": "2019-12-18 11:39:44"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "PU-N4",
"id": 39,
"controlId": "20",
"creationDate": "2020-11-24 16:24:21"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "OF-N2",
"id": 48,
"controlId": "22",
"creationDate": "2020-11-26 16:44:41"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "OF-N1",
"id": 47,
"controlId": "23",
"creationDate": "2020-11-26 16:44:41"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateDate": "2019-12-18 10:39:19",
"lastUpdateUserId": 2,
"active": true,
"description": "SI-N2",
"id": 2,
"creationDate": "2019-11-15 15:03:09"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateDate": "2023-12-15 16:26:38",
"lastUpdateUserId": 2,
"active": false,
"description": "SI-N3",
"id": 3,
"creationDate": "2019-11-15 15:03:09"
}
];
const microZones = [
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "COLONIA NUEVA DURANGO",
"id": 37,
"creationDate": "2022-12-08 00:58:56"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "GUAJAYVI",
"id": 39,
"creationDate": "2022-12-08 00:59:48"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "NUEVA CONQUISTA",
"id": 40,
"creationDate": "2022-12-08 00:59:54"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "SANTANI",
"id": 41,
"creationDate": "2022-12-08 13:00:00"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "VILLA DEL ROSARIO",
"id": 42,
"creationDate": "2022-12-08 13:00:06"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "VILLA YGATIMI",
"id": 43,
"creationDate": "2022-12-08 13:00:38"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "ANTEQUERA",
"id": 44,
"creationDate": "2022-12-08 13:01:05"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "LIBERACION",
"id": 45,
"creationDate": "2022-12-08 13:01:11"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "SANTA ROSA DEL AGUARAY",
"id": 46,
"creationDate": "2022-12-08 13:01:48"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "TACUATI",
"id": 47,
"creationDate": "2022-12-08 13:01:55"
},
{
"creationUserId": 1913,
"locationSubZoneId": 3,
"lastUpdateUserId": 0,
"active": true,
"description": "CAPITAN BADO",
"id": 48,
"creationDate": "2022-12-08 13:02:59"
},
{
"creationUserId": 1913,
"locationSubZoneId": 3,
"lastUpdateUserId": 0,
"active": true,
"description": "PEDRO JUAN CABALLERO",
"id": 49,
"creationDate": "2022-12-08 13:03:06"
},
{
"creationUserId": 1913,
"locationSubZoneId": 65,
"lastUpdateUserId": 0,
"active": true,
"description": "CONCEPCION",
"id": 50,
"creationDate": "2022-12-08 13:04:39"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateDate": "2023-01-25 11:55:19",
"lastUpdateUserId": 1913,
"active": true,
"description": "CURUGUATY",
"id": 38,
"creationDate": "2022-12-08 00:59:03"
}
];
function generateZoneTable(subzones, microzones, isEdition) {
const tableBody = document.getElementById('tBodyContainerLocationSubZone');
subzones.forEach((subzone) => {
const subzoneMicrozones = microzones.filter((microzone) => microzone.locationSubZoneId === subzone.id);
const subzoneRowCount = subzoneMicrozones.length;
subzoneMicrozones.forEach((microzone, index) => {
const subzoneRow = document.createElement('tr');
if (isEdition){
if (index === 0) {
//columna para desasociar
const unBind = document.createElement('td');
unBind.innerHTML = '<i class="mdi mdi-link-off"></i>'; // Insert icon or content
unBind.setAttribute('rowspan', subzoneRowCount);
subzoneRow.appendChild(unBind);
}
//columna para subzona
const subzoneCell = document.createElement('td');
subzoneCell.textContent = subzone.description;
subzoneCell.setAttribute('rowspan', subzoneRowCount);
//icono de ojo para la subzona
const subzoneIcon = document.createElement('i');
subzoneIcon.classList.add('mdi', 'mdi-eye', 'ml-1');
subzoneIcon.style.cursor = 'pointer';
subzoneIcon.addEventListener('click', () => {
showLocationSubZone(subzone.id, "zoneView", false);
});
subzoneCell.appendChild(subzoneIcon);
subzoneRow.appendChild(subzoneCell);
} else {
if (index === 0) {
//columna para subzona
const subzoneCell = document.createElement('td');
subzoneCell.textContent = subzone.description;
subzoneCell.setAttribute('rowspan', subzoneRowCount);
//icono de ojo para la subzona
const subzoneIcon = document.createElement('i');
subzoneIcon.classList.add('mdi', 'mdi-eye', 'ml-1');
subzoneIcon.style.cursor = 'pointer';
subzoneIcon.addEventListener('click', () => {
showLocationSubZone(subzone.id, "zoneView", false);
});
subzoneCell.appendChild(subzoneIcon);
subzoneRow.appendChild(subzoneCell);
}
}
//columna para microzona
const microzoneCell = document.createElement('td');
microzoneCell.textContent = microzone.description;
// icono de ojo para la microzona
const microzoneIcon = document.createElement('i');
microzoneIcon.classList.add('mdi', 'mdi-eye', 'ml-1');
microzoneIcon.style.cursor = 'pointer'; // Cambiar el cursor al puntero
microzoneIcon.addEventListener('click', () => {
showLocationSubZone(microzone.id, "zoneView", true);
});
microzoneCell.appendChild(microzoneIcon);
subzoneRow.appendChild(microzoneCell);
tableBody.appendChild(subzoneRow);
});
});
}
generateZoneTable(subZones, microZones, false);
/* Add border to table and cells */
.table-bordered {
border: 1px solid #dee2e6;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #dee2e6;
}
/* Add padding to table cells */
.table th,
.table td {
padding: 0.75rem;
}
/* Center the content of table cells */
.table td,
.table th {
text-align: center;
}
/* Add margin to the table */
#zoneGeographicAssociation {
margin-top: 10px; /* Adjust as needed */
}
/* Style the button */
.btn-secondary {
color: #fff;
background-color: #6c757d;
border-color: #6c757d;
}
.btn-secondary:hover {
color: #fff;
background-color: #5a6268;
border-color: #545b62;
}
.btn-secondary:focus, .btn-secondary.focus {
box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
}
.btn-secondary.disabled, .btn-secondary:disabled {
color: #fff;
background-color: #6c757d;
border-color: #6c757d;
}
/* Adjust spacing between elements */
.input-group {
margin-bottom: 10px;
}
/* Optional: Add hover effect to table rows */
.table-hover tbody tr:hover {
background-color: #f8f9fa;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font/css/materialdesignicons.min.css">
<div class="col-md-12 col-sm-12 mt-3">
<div class="row">
<div class="input-group">
<h4>Asociación Geográfica</h4>
<button type="button" class="btn btn-secondary btn-sm ml-1 " onclick="createLocationSubZone(true)">Agregar</button>
</div>
<table class="table table-bordered table-centered mb-0 mt-3" id="zoneGeographicAssociation" style="width:100%;">
<thead>
<tr>
<th class="w-50">Sub-Zonas</th>
<th class="w-50">Micro-Zonas</th>
</tr>
</thead>
<tbody id="tBodyContainerLocationSubZone">
</tbody>
</table>
</div>
</div>
However whenever I need to edit the data then my HTML transforms to add an extra column before subzone with the header "desasociar" and the value of the isEdition
parameter becomes true
and that’s when my table gets all messed up and it looks like this
const subZones = [
{
"creationUserId": 1913,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "SI-N4",
"id": 65,
"creationDate": "2022-12-08 13:04:23"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateDate": "2019-12-18 10:39:27",
"lastUpdateUserId": 2,
"active": true,
"description": "SI-N1",
"id": 1,
"controlId": "9",
"creationDate": "2019-11-15 15:03:09"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "OF-N3",
"id": 49,
"creationDate": "2020-11-26 16:44:41"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "PU-N2",
"id": 28,
"controlId": "18",
"creationDate": "2019-12-18 11:39:44"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "PU-N1",
"id": 29,
"controlId": "19",
"creationDate": "2019-12-18 11:39:44"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "PU-N4",
"id": 39,
"controlId": "20",
"creationDate": "2020-11-24 16:24:21"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "OF-N2",
"id": 48,
"controlId": "22",
"creationDate": "2020-11-26 16:44:41"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "OF-N1",
"id": 47,
"controlId": "23",
"creationDate": "2020-11-26 16:44:41"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateDate": "2019-12-18 10:39:19",
"lastUpdateUserId": 2,
"active": true,
"description": "SI-N2",
"id": 2,
"creationDate": "2019-11-15 15:03:09"
},
{
"creationUserId": 2,
"locationZoneId": 1,
"lastUpdateDate": "2023-12-15 16:26:38",
"lastUpdateUserId": 2,
"active": false,
"description": "SI-N3",
"id": 3,
"creationDate": "2019-11-15 15:03:09"
}
];
const microZones = [
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "COLONIA NUEVA DURANGO",
"id": 37,
"creationDate": "2022-12-08 00:58:56"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "GUAJAYVI",
"id": 39,
"creationDate": "2022-12-08 00:59:48"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "NUEVA CONQUISTA",
"id": 40,
"creationDate": "2022-12-08 00:59:54"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "SANTANI",
"id": 41,
"creationDate": "2022-12-08 13:00:00"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "VILLA DEL ROSARIO",
"id": 42,
"creationDate": "2022-12-08 13:00:06"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateUserId": 0,
"active": true,
"description": "VILLA YGATIMI",
"id": 43,
"creationDate": "2022-12-08 13:00:38"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "ANTEQUERA",
"id": 44,
"creationDate": "2022-12-08 13:01:05"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "LIBERACION",
"id": 45,
"creationDate": "2022-12-08 13:01:11"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "SANTA ROSA DEL AGUARAY",
"id": 46,
"creationDate": "2022-12-08 13:01:48"
},
{
"creationUserId": 1913,
"locationSubZoneId": 2,
"lastUpdateUserId": 0,
"active": true,
"description": "TACUATI",
"id": 47,
"creationDate": "2022-12-08 13:01:55"
},
{
"creationUserId": 1913,
"locationSubZoneId": 3,
"lastUpdateUserId": 0,
"active": true,
"description": "CAPITAN BADO",
"id": 48,
"creationDate": "2022-12-08 13:02:59"
},
{
"creationUserId": 1913,
"locationSubZoneId": 3,
"lastUpdateUserId": 0,
"active": true,
"description": "PEDRO JUAN CABALLERO",
"id": 49,
"creationDate": "2022-12-08 13:03:06"
},
{
"creationUserId": 1913,
"locationSubZoneId": 65,
"lastUpdateUserId": 0,
"active": true,
"description": "CONCEPCION",
"id": 50,
"creationDate": "2022-12-08 13:04:39"
},
{
"creationUserId": 1913,
"locationSubZoneId": 1,
"lastUpdateDate": "2023-01-25 11:55:19",
"lastUpdateUserId": 1913,
"active": true,
"description": "CURUGUATY",
"id": 38,
"creationDate": "2022-12-08 00:59:03"
}
];
function generateZoneTable(subzones, microzones, isEdition) {
const tableBody = document.getElementById('tBodyContainerLocationSubZone');
subzones.forEach((subzone) => {
const subzoneMicrozones = microzones.filter((microzone) => microzone.locationSubZoneId === subzone.id);
const subzoneRowCount = subzoneMicrozones.length;
subzoneMicrozones.forEach((microzone, index) => {
const subzoneRow = document.createElement('tr');
if (isEdition){
if (index === 0) {
//columna para desasociar
const unBind = document.createElement('td');
unBind.innerHTML = '<i class="mdi mdi-link-off"></i>'; // Insert icon or content
unBind.setAttribute('rowspan', subzoneRowCount);
subzoneRow.appendChild(unBind);
}
//columna para subzona
const subzoneCell = document.createElement('td');
subzoneCell.textContent = subzone.description;
subzoneCell.setAttribute('rowspan', subzoneRowCount);
//icono de ojo para la subzona
const subzoneIcon = document.createElement('i');
subzoneIcon.classList.add('mdi', 'mdi-eye', 'ml-1');
subzoneIcon.style.cursor = 'pointer';
subzoneIcon.addEventListener('click', () => {
showLocationSubZone(subzone.id, "zoneView", false);
});
subzoneCell.appendChild(subzoneIcon);
subzoneRow.appendChild(subzoneCell);
} else {
if (index === 0) {
//columna para subzona
const subzoneCell = document.createElement('td');
subzoneCell.textContent = subzone.description;
subzoneCell.setAttribute('rowspan', subzoneRowCount);
//icono de ojo para la subzona
const subzoneIcon = document.createElement('i');
subzoneIcon.classList.add('mdi', 'mdi-eye', 'ml-1');
subzoneIcon.style.cursor = 'pointer';
subzoneIcon.addEventListener('click', () => {
showLocationSubZone(subzone.id, "zoneView", false);
});
subzoneCell.appendChild(subzoneIcon);
subzoneRow.appendChild(subzoneCell);
}
}
//columna para microzona
const microzoneCell = document.createElement('td');
microzoneCell.textContent = microzone.description;
// icono de ojo para la microzona
const microzoneIcon = document.createElement('i');
microzoneIcon.classList.add('mdi', 'mdi-eye', 'ml-1');
microzoneIcon.style.cursor = 'pointer'; // Cambiar el cursor al puntero
microzoneIcon.addEventListener('click', () => {
showLocationSubZone(microzone.id, "zoneView", true);
});
microzoneCell.appendChild(microzoneIcon);
subzoneRow.appendChild(microzoneCell);
tableBody.appendChild(subzoneRow);
});
});
}
generateZoneTable(subZones, microZones, true);
/* Add border to table and cells */
.table-bordered {
border: 1px solid #dee2e6;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #dee2e6;
}
/* Add padding to table cells */
.table th,
.table td {
padding: 0.75rem;
}
/* Center the content of table cells */
.table td,
.table th {
text-align: center;
}
/* Add margin to the table */
#zoneGeographicAssociation {
margin-top: 10px; /* Adjust as needed */
}
/* Style the button */
.btn-secondary {
color: #fff;
background-color: #6c757d;
border-color: #6c757d;
}
.btn-secondary:hover {
color: #fff;
background-color: #5a6268;
border-color: #545b62;
}
.btn-secondary:focus, .btn-secondary.focus {
box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);
}
.btn-secondary.disabled, .btn-secondary:disabled {
color: #fff;
background-color: #6c757d;
border-color: #6c757d;
}
/* Adjust spacing between elements */
.input-group {
margin-bottom: 10px;
}
/* Optional: Add hover effect to table rows */
.table-hover tbody tr:hover {
background-color: #f8f9fa;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font/css/materialdesignicons.min.css">
<div class="col-md-12 col-sm-12 mt-3">
<div class="row">
<div class="input-group">
<h4>Asociación Geográfica</h4>
<button type="button" class="btn btn-secondary btn-sm ml-1 " onclick="createLocationSubZone(true)">Agregar</button>
</div>
<table class="table table-bordered table-centered mb-0 mt-3" id="zoneGeographicAssociation" style="width:100%;">
<thead>
<tr>
<th class="w-10">Desasociar</th>
<th class="w-40">Sub-Zonas</th>
<th class="w-50">Micro-Zonas</th>
</tr>
</thead>
<tbody id="tBodyContainerLocationSubZone">
</tbody>
</table>
</div>
</div>
The behaviour I’m expecting to get is just an extra column at the beggining of the table with an icon that will have a function later(this part not important now) the extra column with the icon is supposed to share the same rowspan as the subzone, the rest needs to look the same but my table is all messed up.
Any help is appreciated
2
Answers
Just updated closing of index 0, in the isEditable block.
Please note this will help you to fix the current problem, if you are editing only subZone lineItem, To add icon against every microZone item, you need to update your code.
You will simply need to make sure that you write your aggregate values exactly once, as you did for the first columns of yours: