File "table_0016_debug0012.php"
Full Path: /home/analogde/www/Diabete/Provisoire/table_0016_debug0012.php
File size: 190.69 KB
MIME-type: text/x-php
Charset: utf-8
<?php
function getWorkingDays($startDate, $endDate, $holidays = []) {
$start = strtotime($startDate);
$end = strtotime($endDate);
$workingDays = [];
setlocale(LC_TIME, 'fr_FR.UTF-8');
for ($currentDate = $start; $currentDate <= $end; $currentDate = strtotime("+1 day", $currentDate)) {
$dayOfWeek = date("N", $currentDate);
if ($dayOfWeek < 6 && !in_array(date("Y-m-d", $currentDate), $holidays)) {
$workingDays[] = [
'day' => date("d", $currentDate),
'day_of_week_initial' => strtoupper(strftime("%A", $currentDate)[0]),
'week_number' => date("W", $currentDate),
'full_date' => date("Y-m-d", $currentDate) // Ajout de la date complète
];
}
}
return $workingDays;
}
function getFrenchHolidays($year) {
$easterDate = easter_date($year);
$holidays = [];
// Jours fériés fixes
$holidays[] = "$year-01-01"; // Jour de l'An
$holidays[] = "$year-05-01"; // Fête du Travail
$holidays[] = "$year-05-08"; // Victoire 1945
$holidays[] = "$year-07-14"; // Fête Nationale
$holidays[] = "$year-08-15"; // Assomption
$holidays[] = "$year-11-01"; // Toussaint
$holidays[] = "$year-11-11"; // Armistice
$holidays[] = "$year-12-25"; // Noël
// Jours fériés variables (calculés à partir de Pâques)
$easter = new DateTime("@$easterDate");
$easter->setTimezone(new DateTimeZone(date_default_timezone_get()));
$holidays[] = $easter->format("Y-m-d"); // Pâques (non férié officiellement mais utile)
$holidays[] = $easter->modify('+1 day')->format("Y-m-d"); // Lundi de Pâques
$holidays[] = $easter->modify('+38 days')->format("Y-m-d"); // Ascension
$holidays[] = $easter->modify('+11 days')->format("Y-m-d"); // Lundi de Pentecôte
return $holidays;
}
$year = 2025;
$holidays = [];
$holidays = getFrenchHolidays($year);
// Liste des jours fériés et fêtes religieuses à exclure (exemple pour la France, à compléter avec d'autres fêtes)
$old_holidays = [
"2025-01-01", // Jour de l'An
"2025-04-14", // Lundi de Pâques
"2025-05-01", // Fête du Travail
"2025-05-08", // Victoire 1945
"2025-07-14", // Bastille
"2025-08-15", // Assomption
"2025-11-01", // Toussaint
"2025-12-25", // Noël
"2026-01-01", // Jour de l'An
"2026-04-06", // Lundi de Pâques
// Ajouter d'autres jours fériés ici...
];
// Définir la période de début et de fin
$startDate = "2025-01-10";
$endDate = "2026-02-14";
// Appeler la fonction pour obtenir les jours ouvrés entre les deux dates
$workingDays = getWorkingDays($startDate, $endDate, $holidays);
// Convertir le tableau en JSON
$workingDaysJson = json_encode($workingDays);
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tableau Sticky - 3 Lignes Fixes</title>
<style>
.table-wrapper {
width: 100%;
height: calc(100vh - 100px);
overflow: auto;
border: 1px solid #ccc;
position: relative;
}
table {
border-collapse: collapse;
width: max-content;
table-layout: fixed;
}
th, td {
padding: 3px;
text-align: center;
height: 40px;
border: 1px solid #ccc;
white-space: nowrap;
min-width: 120px;
position: relative;
background-color: white;
box-sizing: border-box;
}
th {
background-color: #f2f2f2;
position: sticky;
top: 0;
z-index: 100;
}
th:first-child, td:first-child {
position: sticky;
left: 0;
z-index: 101;
background-color: white;
}
th:nth-child(2), td:nth-child(2) {
position: sticky;
left: 120px;
z-index: 100;
background-color: white;
}
th:nth-child(3), td:nth-child(3) {
position: sticky;
left: 240px;
z-index: 99;
background-color: white;
}
th:first-child::after, td:first-child::after,
th:nth-child(2)::after, td:nth-child(2)::after,
th:nth-child(3)::after, td:nth-child(3)::after {
content: "";
position: absolute;
right: 0;
top: 0;
width: 2px;
height: 100%;
background-color: #ccc;
z-index: 102;
}
tbody tr:nth-child(odd) {
background-color: #f9f9f9;
}
th:nth-child(n+4), td:nth-child(n+4) {
min-width: 40px;
max-width: 40px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.second-header th {
background-color: #f2f2f2;
position: sticky;
top: 40px;
z-index: 99;
}
.third-header th {
background-color: #f2f2f2;
position: sticky;
top: 80px;
z-index: 98;
}
.second-header th:first-child, .third-header th:first-child {
left: 0;
z-index: 101;
background-color: white;
}
.second-header th:nth-child(2), .third-header th:nth-child(2) {
left: 120px;
z-index: 100;
background-color: white;
}
.second-header th:nth-child(3), .third-header th:nth-child(3) {
left: 240px;
z-index: 99;
background-color: white;
}
thead tr:first-child th:first-child,
thead tr:first-child th:nth-child(2),
thead tr:first-child th:nth-child(3) {
z-index: 105;
background-color: #ddd;
}
.second-header th:first-child,
.second-header th:nth-child(2),
.second-header th:nth-child(3) {
z-index: 104;
}
.third-header th:first-child,
.third-header th:nth-child(2),
.third-header th:nth-child(3) {
z-index: 103;
}
thead tr:first-child th,
.second-header th,
.third-header th {
box-shadow: inset 0 -2px #aaa;
background-clip: padding-box;
padding-bottom: 2px;
margin-bottom: -2px;
z-index: 100;
}
.second-header th {
top: calc(40px + 2px);
margin-top: 2px;
}
.third-header th {
top: calc(80px + 2px);
margin-top: 2px;
}
.even-week {
background-color: #ffcc99 !important;
}
.odd-week {
background-color: #e6b3ff !important;
}
.fourth-header th {
background-color: #f2f2f2;
position: sticky;
top: 120px;
z-index: 97;
}
.fourth-header th:first-child {
left: 0;
z-index: 101;
background-color: white;
}
.fourth-header th:nth-child(2) {
left: 120px;
z-index: 100;
background-color: white;
}
.fourth-header th:nth-child(3) {
left: 240px;
z-index: 99;
background-color: white;
}
.fourth-header th:first-child,
.fourth-header th:nth-child(2),
.fourth-header th:nth-child(3) {
z-index: 102;
}
.fourth-header th {
top: calc(120px + 2px);
margin-top: 2px;
}
.fourth-header th {
box-shadow: inset 0 -2px #aaa;
background-clip: padding-box;
padding-bottom: 2px;
margin-bottom: -2px;
z-index: 97;
}
.month-even {
background-color: #99ccff !important;
}
.month-odd {
background-color: #ff9999 !important;
}
.btn {
margin-bottom: 20px;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
font-size: 16px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.btn:hover {
background-color: #45a049;
}
.btn-special {
background-color: #2196F3;
}
.btn-special:hover {
background-color: #1e88e5;
}
.btn-special:hover {
background-color: #1e88e5;
}
#contextMenu {
position: absolute;
display: none;
flex-direction: column;
background: white;
border: 1px solid #ccc;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 5px;
z-index: 1000;
min-width: 180px;
}
#contextMenu .dropdown-item {
display: block;
width: 100%;
padding: 8px 12px;
text-align: left;
color: #333;
cursor: pointer;
}
#contextMenu .dropdown-item:hover {
background: #f8f9fa;
}
#specialContextMenu {
position: absolute;
display: none;
flex-direction: column;
background: white;
border: 1px solid #ccc;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 5px;
z-index: 1000;
min-width: 180px;
}
#specialContextMenu .dropdown-item {
display: block;
width: 100%;
padding: 8px 12px;
text-align: left;
color: #333;
cursor: pointer;
}
#specialContextMenu .dropdown-item:hover {
background: #f8f9fa;
}
#colorContextMenu {
position: absolute;
display: none;
flex-direction: column;
background: white;
border: 1px solid #ccc;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 5px;
z-index: 1000;
min-width: 180px;
}
#colorContextMenu .dropdown-item {
display: block;
width: 100%;
padding: 8px 12px;
text-align: left;
color: #333;
cursor: pointer;
}
#colorContextMenu .dropdown-item:hover {
background: #f8f9fa;
}
.add-button {
background-color: orange;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
margin-left: 5px;
}
.editable-input {
width: 65px;
box-sizing: border-box;
}
.collapsed {
display: none;
}
#jsonOutput {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f9f9f9;
white-space: pre-wrap;
word-wrap: break-word;
}
#logOutput {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f9f9f9;
white-space: pre-wrap;
word-wrap: break-word;
}
.no-click {
pointer-events: none;
}
#debugOutput {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f9f9f9;
white-space: pre-wrap;
word-wrap: break-word;
}
.dropdown-item.disabled {
pointer-events: none;
color: #6c757d;
font-style: italic;
}
.no-select {
pointer-events: none;
}
</style>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<input type="file" id="fileInput" accept=".json" style="display: none;">
<div class="modal fade" id="confirmationModal" tabindex="-1" aria-labelledby="confirmationModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmationModalLabel">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Voulez-vous vraiment supprimer cette ligne ?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="cancelDelete">Annuler</button>
<button type="button" class="btn btn-danger" id="confirmDelete">OK</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="successModal" tabindex="-1" aria-labelledby="successModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="successModalLabel">Succès</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Données sauvegardées avec succès !
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="closeSuccessModal">OK</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="messageModalLabel">Message</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="messageModalBody">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<!-- Modal de confirmation de sauvegarde -->
<div class="modal fade" id="confirmSaveModal" tabindex="-1" aria-labelledby="confirmSaveModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmSaveModalLabel">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Voulez-vous vraiment sauvegarder les données ?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="cancelSave">Annuler</button>
<button type="button" class="btn btn-primary" id="confirmSave">OK</button>
</div>
</div>
</div>
</div>
<!-- Modal pour saisir le nom du fichier -->
<div class="modal fade" id="singlefileNameModal" tabindex="-1" aria-labelledby="fileNameModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="fileNameModalLabel">AAAAAA Nom du fichier</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="fileName">Sauvegarde des data </label>
<input type="text" class="form-control" id="fileName" placeholder="Entrez le nom du fichier">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" id="saveFileName">Enregistrer</button>
</div>
</div>
</div>
</div>
<!-- Modal pour saisir le nom du fichier -->
<div class="modal fade" id="fileNameModal" tabindex="-1" aria-labelledby="fileNameModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="fileNameModalLabel">Nom du fichier</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="fileName">Sauvegarde des data</label>
<input type="text" class="form-control" id="fileName" placeholder="Entrez le nom du fichier">
</div>
<div class="form-group">
<label for="fileList">Sélectionnez un fichier</label>
<select class="form-control" id="fileList" size="10" style="height: auto; max-height: 200px; overflow-y: auto;">
</select>
</div>
<div id="fileExistsMessage" style="display: none; color: red; margin-top: 10px;">
Attention : Le fichier existe déjà. Enregistrer écrasera les données précédentes.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" id="saveFileName">Enregistrer</button>
<button type="button" class="btn btn-danger" id="confirmOverwrite" style="display: none;">Confirmer l'écrasement</button>
</div>
</div>
</div>
</div>
<!-- Modal pour saisir le nom du fichier -->
<div class="modal fade" id="saveFileNameModal" tabindex="-1" aria-labelledby="saveFileNameModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="saveFileNameModalLabel">Nom du fichier</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="saveFileName">Nom du fichier</label>
<input type="text" class="form-control" id="saveFileName" placeholder="Entrez le nom du fichier">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" id="confirmSaveFileName">OK</button>
</div>
</div>
</div>
</div>
<!-- Modal pour saisir le nom du fichier à lire -->
<div class="modal fade" id="readFileNameModal" tabindex="-1" aria-labelledby="readFileNameModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="readFileNameModalLabel">Import des data</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="readFileName">Nom du fichier</label>
<input type="text" class="form-control" id="readFileName" placeholder="Entrez le nom du fichier">
</div>
<div class="form-group">
<label for="fileList_read">Sélectionnez un fichier</label>
<select class="form-control" id="fileList_read" size="10" style="height: auto; max-height: 200px; overflow-y: auto;">
<!-- Les options seront ajoutées dynamiquement -->
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" id="readFile">Lire</button>
</div>
</div>
</div>
</div>
<!-- Modal de confirmation d'écrasement -->
<div class="modal fade" id="confirmOverwriteModal" tabindex="-1" aria-labelledby="confirmOverwriteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmOverwriteModalLabel">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Le fichier existe déjà. Voulez-vous vraiment l'écraser ?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="cancelOverwrite">Annuler</button>
<button type="button" class="btn btn-danger" id="confirmOverwrite">OK</button>
</div>
</div>
</div>
</div>
<div id="colorContextMenu" class="dropdown-menu" style="display: none;">
<button class="dropdown-item" style="background-color: green;" data-color="green">Vert</button>
<button class="dropdown-item" style="background-color: blue;" data-color="blue">Bleu</button>
<button class="dropdown-item" style="background-color: red;" data-color="red">Rouge</button>
<button class="dropdown-item" style="background-color: yellow;" data-color="yellow">Jaune</button>
<button class="dropdown-item" style="background-color: orange;" data-color="orange">Orange</button>
<button class="dropdown-item" style="background-color: purple;" data-color="purple">Violet</button>
<button class="dropdown-item" style="background-color: pink;" data-color="pink">Rose</button>
<button class="dropdown-item" style="background-color: brown;" data-color="brown">Marron</button>
<button class="dropdown-item" style="background-color: cyan;" data-color="cyan">Cyan</button>
<button class="dropdown-item" style="background-color: gray;" data-color="gray">Gris</button>
</div>
<div class="modal fade" id="rangeSelectionModal" tabindex="-1" aria-labelledby="rangeSelectionModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="rangeSelectionModalLabel">Sélection de Plage</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="startCellId">Cellule de Départ</label>
<input type="text" class="form-control" id="startCellId" disabled>
</div>
<div class="form-group">
<label for="endCellId">Cellule de Fin</label>
<input type="text" class="form-control" id="endCellId">
</div>
<div class="form-group">
<label for="rangeComboBox">Sélectionnez une valeur</label>
<select class="form-control" id="rangeComboBox">
</select>
</div>
<div id="rangeResult" class="form-group">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="cancelRangeSelection">Annuler</button>
<button type="button" class="btn btn-primary" id="confirmRangeSelection">Valider</button>
</div>
</div>
</div>
</div>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th></th>
<th>plouf</th>
<th>cretin</th>
<?php foreach ($workingDays as $dateData): ?>
<th>
<?php echo $dateData['day']; ?> <br>
</th>
<?php endforeach; ?>
</tr>
<tr class="second-header">
<th></th>
<th>Valeur 1</th>
<th>Valeur 2</th>
<?php
$currentWeek = null;
$weekClass = "";
foreach ($workingDays as $dateData):
if ($currentWeek !== $dateData['week_number']) {
$currentWeek = $dateData['week_number'];
$weekClass = ($currentWeek % 2 === 0) ? 'even-week' : 'odd-week';
}
?>
<th class="<?= $weekClass; ?>"><?php echo $dateData['day_of_week_initial']; ?></th>
<?php endforeach; ?>
</tr>
<tr class="third-header">
<th></th>
<th>Info 1</th>
<th>Info 2</th>
<?php
$currentWeek = null;
$colspan = 0;
foreach ($workingDays as $index => $dateData):
if ($currentWeek !== $dateData['week_number']) {
if ($currentWeek !== null) {
$weekClass = $currentWeek % 2 === 0 ? 'even-week' : 'odd-week';
echo '<th class="' . $weekClass . '" colspan="' . $colspan . '">' . $currentWeek . '</th>';
}
$currentWeek = $dateData['week_number'];
$colspan = 1;
} else {
$colspan++;
}
endforeach;
if ($currentWeek !== null) {
$weekClass = $currentWeek % 2 === 0 ? 'even-week' : 'odd-week';
echo '<th class="' . $weekClass . '" colspan="' . $colspan . '">' . $currentWeek . '</th>';
}
?>
</tr>
<tr class="fourth-header">
<th></th>
<th>Label 1</th>
<th>Label 2</th>
<?php
$currentMonthYear = null;
$colspan = 0;
$monthClass = "";
$colorIndex = 0;
$colors = ['month-even', 'month-odd'];
foreach ($workingDays as $index => $dateData):
$monthYear = ucfirst(strftime("%B %Y", strtotime($dateData['full_date'])));
if ($currentMonthYear !== $monthYear) {
if ($currentMonthYear !== null) {
echo '<th class="' . $monthClass . '" colspan="' . $colspan . '">' . $currentMonthYear . '</th>';
}
$currentMonthYear = $monthYear;
$colspan = 1;
$monthClass = $colors[$colorIndex % 2];
$colorIndex++;
} else {
$colspan++;
}
endforeach;
if ($currentMonthYear !== null) {
echo '<th class="' . $monthClass . '" colspan="' . $colspan . '">' . $currentMonthYear . '</th>';
}
?>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<button id="addRowButton" class="btn">Ajouter une ligne</button>
<button id="addSpecialRowButton" class="btn btn-special">Ajouter une ligne spéciale</button>
<button id="SauveButton" class="btn">Sauver</button>
<button id="ChargeButton" class="btn">Charger</button>
<button id="GraphiqueButton" class="btn">Graphique</button>
<!--
<button id="logButton" class="btn">Log</button>
-->
<button id="queryButton" class="btn">Query</button>
<!-- Deuxième ligne de boutons -->
<div style="margin-top: 10px;">
<button id="writeButton" class="btn">Write</button>
<button id="readButton" class="btn">Read</button>
</div>
<!-- Troisiéme ligne de boutons -->
<div style="margin-top: 10px;">
<button id="EnregistrerButton" class="btn">Enregistrer</button>
<button id="LectureButton" class="btn">Lecture</button>
</div>
<!--
<div id="jsonOutput"></div>
-->
<!--
<div id="debugOutput"></div>
-->
<script>
// Intégrer le JSON PHP dans une variable JavaScript
const workingDays = <?php echo $workingDaysJson; ?>;
// Fonction pour afficher les données dans la console
function displayWorkingDays() {
console.log(workingDays);
}
// Appeler la fonction pour afficher les données
displayWorkingDays();
const value = workingDays[27].full_date;
console.log(value);
// Déclarez le tableau list_lignes en dehors des fonctions pour qu'il soit accessible globalement
let list_lignes = [];
document.addEventListener("DOMContentLoaded", function () {
const tableBody = document.querySelector("tbody");
let specialRowCounter = 1;
let rowCounter = 1;
let linkageCounter = 1;
let standardRowsData = [];
let estimationRowsData = [];
let specialRowsData = []; // Tableau dédié pour stocker les objets des lignes spéciales
let linkages = [];
const specialRowStates = {};
const associations = {};
let currentCell = null;
let keydownHandled = false;
let alertShown = false;
let selectedRow = null; // Variable to keep track of the selected row
const contextMenu = document.createElement("div");
contextMenu.id = "contextMenu";
contextMenu.classList.add("dropdown-menu");
contextMenu.style.display = "none";
document.body.appendChild(contextMenu);
const specialContextMenu = document.createElement("div");
specialContextMenu.id = "specialContextMenu";
specialContextMenu.classList.add("dropdown-menu");
specialContextMenu.style.display = "none";
document.body.appendChild(specialContextMenu);
const colorContextMenu = document.getElementById("colorContextMenu");
const colorButtons = colorContextMenu.querySelectorAll(".dropdown-item");
colorButtons.forEach(button => {
button.addEventListener("click", function () {
const color = this.getAttribute("data-color");
const cell = document.querySelector(".selected-cell");
if (cell) {
cell.style.backgroundColor = color;
cell.dataset.cellColor = color;
hideColorContextMenu();
updateRowData(cell);
}
});
});
/**********************************************************************************************/
function generateRandomId(length = 8) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
/**********************************************************************************************/
function addRow(afterRow = null) {
const rowNumber = tableBody.rows.length + 1;
const newRow = document.createElement("tr");
newRow.setAttribute("draggable", "true");
newRow.dataset.rowId = `standard-${generateRandomId()}`;
newRow.title = newRow.dataset.rowId; // Ajoutez cette ligne
const rowData = {
id: newRow.dataset.rowId,
name: `Row ${rowNumber}`,
selectValue: "1",
count: "0",
cells: [],
selection: "OFF" // TAG : SELECTION
};
// Ajoutez l'identifiant de la ligne dans le tableau list_lignes
list_lignes.push(newRow.dataset.rowId);
const firstCells = [`Row ${rowNumber}`, "", "0"];
firstCells.forEach((text, index) => {
const td = document.createElement("td");
td.dataset.cellId = `cell-${rowData.id}-${index}`;
if (index === 0) {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = rowData.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
});
input.addEventListener("blur", function () {
if (!keydownHandled && !alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
keydownHandled = false;
alertShown = false;
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
keydownHandled = true;
if (!alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
}
});
td.appendChild(input);
} else if (index === 1) {
const select = document.createElement("select");
for (let i = 1; i <= 10; i++) {
const option = document.createElement("option");
option.value = i;
option.textContent = `Option ${i}`;
select.appendChild(option);
}
select.value = rowData.selectValue;
select.addEventListener("change", function () {
updateRowData(select);
});
td.appendChild(select);
} else {
td.textContent = text;
}
if (index === 0) {
td.classList.add("row-header");
td.addEventListener("click", function () {
handleRowClick(newRow, td); // TAG : SELECTION
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, newRow);
});
}
newRow.appendChild(td);
});
const headerCells = document.querySelectorAll("thead tr:nth-child(2) th:not(.weekend):not(.holiday)");
const workingDaysCount = headerCells.length;
for (let i = 0; i < workingDaysCount - 3; i++) {
const td = document.createElement("td");
td.dataset.cellId = `cell-${rowData.id}-${i}`;
td.dataset.cellValue = "0";
td.dataset.cellColor = "white";
td.textContent = "0";
td.style.backgroundColor = "white";
td.addEventListener("click", function () {
const newValue = td.dataset.cellValue === "0" ? "1" : "0";
td.dataset.cellValue = newValue;
td.textContent = newValue;
td.style.backgroundColor = newValue === "1" ? "green" : "white";
td.dataset.cellColor = newValue === "1" ? "green" : "white";
updateCountCell(newRow);
updateRowData(td);
});
td.addEventListener("click", function (event)
{
const fullDate = event.target.dataset.fullDate;
console.log("Date complète :", fullDate);
//alert(fullDate);
// maintenant utiliser fullDate pour d'autres opérations
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
if (td.dataset.cellValue === "1") {
showColorContextMenu(event, td);
}
});
td.title = `ID: ${td.dataset.cellId}`;
newRow.appendChild(td);
// $workingDays 555
const value = workingDays[i].full_date;
// Ajouter la clé full_date
td.dataset.fullDate = workingDays[i].full_date;
rowData.cells.push({
value: "0",
color: "white",
full_date: workingDays[i].full_date // Ajouter la clé full_date
});
}
if (afterRow) {
tableBody.insertBefore(newRow, afterRow.nextSibling);
} else {
tableBody.appendChild(newRow);
}
newRow.addEventListener("dragstart", dragStart);
newRow.addEventListener("dragover", dragOver);
newRow.addEventListener("drop", drop);
rowCounter++;
standardRowsData.push(rowData);
const estimationRow = document.createElement("tr");
estimationRow.setAttribute("draggable", "true");
estimationRow.dataset.rowId = `estimation-${generateRandomId()}`;
estimationRow.classList.add("estimation-row");
estimationRow.title = estimationRow.dataset.rowId; // Ajoutez cette ligne
const estimationRowData = {
id: estimationRow.dataset.rowId,
name: `Estimation ${rowNumber}`,
selectValue: "1",
estimationValue: "0",
selection: "OFF" // TAG : SELECTION
};
// Ajoutez l'identifiant de la ligne d'estimation dans le tableau list_lignes
list_lignes.push(estimationRow.dataset.rowId);
const estimationFirstCells = [`Estimation ${rowNumber}`, "", "0"];
estimationFirstCells.forEach((text, index) => {
const td = document.createElement("td");
td.dataset.cellId = `cell-${estimationRowData.id}-${index}`;
if (index === 0) {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = estimationRowData.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
});
input.addEventListener("blur", function () {
if (!keydownHandled && !alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
keydownHandled = false;
alertShown = false;
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
keydownHandled = true;
if (!alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
}
});
td.appendChild(input);
} else if (index === 1) {
const select = document.createElement("select");
for (let i = 1; i <= 10; i++) {
const option = document.createElement("option");
option.value = i;
option.textContent = `Option ${i}`;
select.appendChild(option);
}
select.value = estimationRowData.selectValue;
select.addEventListener("change", function () {
updateRowData(select);
});
td.appendChild(select);
} else {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = "1";
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
});
input.addEventListener("blur", function () {
if (!keydownHandled && !alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
const value = parseInt(input.value, 10);
if (isNaN(value) || value < 1 || value > 365) {
input.value = "1";
showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
} else {
updateRowData(input);
}
}
keydownHandled = false;
alertShown = false;
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
keydownHandled = true;
if (!alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
const value = parseInt(input.value, 10);
if (isNaN(value) || value < 1 || value > 365) {
input.value = "1";
showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
} else {
updateRowData(input);
}
}
}
});
td.appendChild(input);
}
if (index === 0) {
td.classList.add("row-header");
td.addEventListener("click", function () {
handleRowClick(estimationRow, td); // TAG : SELECTION
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, estimationRow);
});
}
estimationRow.appendChild(td);
});
const mergedCell = document.createElement("td");
mergedCell.colSpan = workingDaysCount - 3;
mergedCell.textContent = "";
mergedCell.classList.add("no-click");
estimationRow.appendChild(mergedCell);
if (afterRow) {
tableBody.insertBefore(estimationRow, newRow.nextSibling);
} else {
tableBody.appendChild(estimationRow);
}
estimationRow.addEventListener("dragstart", dragStart);
estimationRow.addEventListener("dragover", dragOver);
estimationRow.addEventListener("drop", drop);
const linkage = {
id: `linkage-${generateRandomId()}`, // Remplacez linkageId par id
standardRowId: newRow.dataset.rowId,
estimationRowId: estimationRow.dataset.rowId
};
linkages.push(linkage);
//displayLinkages();
rowCounter++;
estimationRowsData.push(estimationRowData);
}
/*************************************************************************/
/// 555
// Déclarez la variable selection_origine en dehors de la fonction pour qu'elle soit accessible globalement
let selection_origine = null;
// Déclarez l'objet objet_up en dehors de la fonction pour qu'il soit accessible globalement
let objet_up = []; // Changez objet_up pour qu'il soit un tableau
// Déclarez le tableau objet_selection en dehors de la fonction pour qu'il soit accessible globalement
let objet_selection = [];
/**********************************************************************************************/
function handleRowClick(row, td) {
const rowId = row.dataset.rowId;
selection_origine = rowId; // Mémorisez l'ID de la ligne cliquée
console.log("Selection_origine :", selection_origine); // Affichez la valeur de selection_origine dans la console
const tableBody = document.querySelector("tbody");
const rowIds = [];
/*if (objet_selection.length > 0 )
{
// Afficher une fenêtre modale indiquant qu'une seule sélection est possible à la fois
showMessageModal("Une seule sélection est possible à la fois.");
return; // Empêcher la couleur de fond de changer
}*/
// Parcourir chaque ligne du tableau
tableBody.querySelectorAll("tr").forEach(row => {
const rowId = row.dataset.rowId;
if (rowId) {
rowIds.push(rowId);
}
});
console.log(rowIds);
let linkedRowId = null;
let linkedRow = null;
if (rowId.startsWith("standard-")) {
const linkage = linkages.find(link => link.standardRowId === rowId);
if (linkage) {
linkedRowId = linkage.estimationRowId;
linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
}
} else if (rowId.startsWith("estimation-")) {
const linkage = linkages.find(link => link.estimationRowId === rowId);
if (linkage) {
linkedRowId = linkage.standardRowId;
linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
}
}
// Vérifiez si l'identifiant de la ligne cliquée fait déjà partie de objet_selection
if (objet_selection.includes(rowId)) {
const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);
if (standardRowData && estimationRowData) {
standardRowData.selection = "OFF";
estimationRowData.selection = "OFF";
td.style.backgroundColor = "white";
linkedRow.cells[0].style.backgroundColor = "white";
// Supprimez les identifiants du tableau objet_selection
objet_selection = objet_selection.filter(id => id !== standardRowData.id && id !== estimationRowData.id);
// Réinitialisez les variables
selection_origine = null;
selectedRow = null;
console.log(" UNSELECT ");
}
return; // Empêcher la couleur de fond de changer
}
// Vérifiez si objet_selection contient déjà les identifiants d'une ligne standard et d'une ligne d'estimation
if (objet_selection.length > 0)
//if (objet_selection.length === 2)
{
showMessageModal("Une seule sélection est possible.");
return; // Empêcher la couleur de fond de changer
}
if (linkedRow) {
const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);
if (standardRowData.selection === "OFF" && estimationRowData.selection === "OFF") {
console.log(`ID standard : ${standardRowData.id}`);
console.log(`ID estimation : ${estimationRowData.id}`);
standardRowData.selection = "ON";
estimationRowData.selection = "ON";
td.style.backgroundColor = "red";
linkedRow.cells[0].style.backgroundColor = "red";
// Ajoutez les identifiants dans le tableau objet_selection
objet_selection.push(standardRowData.id, estimationRowData.id);
selectedRow = row; // Mettez à jour la ligne sélectionnée
console.log(`SELECT ${standardRowData.id} ${estimationRowData.id}`);
console.log(" ---- " + objet_selection);
}
}
}
/**********************************************************************************************/
function moveRowsUp()
{
console.log(" Move UP ");
// Vider le tableau
list_lignes.length = 0;
const allRows = Array.from(tableBody.querySelectorAll("tr"));
allRows.forEach(row => {
list_lignes.push(row.dataset.rowId);
});
displayListLignes();
const id_ligne_standard = objet_selection[0];
const id_ligne_estimation = objet_selection[1];
/*list_lignes.forEach((id, index) =>
{
if (id === id_ligne_standard)
{
console.log(`L'ID "${id}" a été trouvé à l'index ${index}.`);
}
if (id === id_ligne_estimation)
{
console.log(`L'ID "${id}" a été trouvé à l'index ${index}.`);
}
});
*/
let position_ligne_standard = list_lignes.indexOf(id_ligne_standard);
let position_ligne_estimation = list_lignes.indexOf(id_ligne_estimation);
console.log(" ------ position_ligne_standard " + position_ligne_standard);
console.log(" ------ position_ligne_estimation" + position_ligne_estimation);
// Vérifiez si la ligne au-dessus de la ligne standard est une ligne spéciale
// let isSpecialAboveStandard = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("special-");
// Vérifiez si la ligne au-dessus de la ligne d'estimation est une ligne spéciale
// let isSpecialAboveEstimation = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation - 1].startsWith("special-");
// Vérifiez si la ligne au-dessus de la ligne standard est une ligne spéciale
let is_speciale = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("special-");
// Vérifiez si la ligne au-dessus de la ligne standard est une ligne esitmation
let is_standard = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("estimation-");
//if( isSpecialAboveStandard === true && isSpecialAboveEstimation === false )
if( is_speciale === true )
{
console.log("Saut speciale " );
let save_identifiant_speciale = list_lignes[position_ligne_standard - 1];
console.log(" TRACE identifiant " + save_identifiant_speciale);
let index = list_lignes.indexOf(save_identifiant_speciale);
list_lignes.splice(index, 1); // Supprime élément à cet index
console.log(" TRACE suppimer " + list_lignes);
// recherche l'index de
let new_position_speciale= list_lignes.indexOf(id_ligne_estimation);
// on l'insére juste aprés
list_lignes.splice( new_position_speciale + 1, 0, save_identifiant_speciale);
console.log(" TRACE " + new_position_speciale + list_lignes);
// saut : standard <-> standard-1
/*if (position_ligne_standard - 1 >= 0)
{
let temp = list_lignes[position_ligne_standard];
list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard - 1];
list_lignes[position_ligne_standard - 1] = temp;
}
// saut : estimation <-> estimation -1
if (position_ligne_estimation - 1 >= 0)
{
let temp = list_lignes[position_ligne_estimation];
list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation - 1];
list_lignes[position_ligne_estimation - 1] = temp;
}
*/
console.log("<<<<<<< Nouvel ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
}
//if( isSpecialAboveStandard === false && isSpecialAboveEstimation === false)
if( is_standard === true )
{
console.log(" Saut de la liaison " );
// saut : standard <-> standard-2
if (position_ligne_standard - 2 >= 0)
{
let temp = list_lignes[position_ligne_standard];
list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard - 2];
list_lignes[position_ligne_standard - 2] = temp;
}
// saut : estimation <-> estimation-2
if (position_ligne_estimation - 2 >= 0)
{
let temp = list_lignes[position_ligne_estimation];
list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation - 2];
list_lignes[position_ligne_estimation - 2] = temp;
}
console.log("<<<<<<< Nouvel ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
}
}
/**************************************************************************/
function moveRowsDown()
{
console.log(" Move Down ");
// Vider le tableau
list_lignes.length = 0;
const allRows = Array.from(tableBody.querySelectorAll("tr"));
allRows.forEach(row =>
{
list_lignes.push(row.dataset.rowId);
});
displayListLignes();
const id_ligne_standard = objet_selection[0];
const id_ligne_estimation = objet_selection[1];
/*list_lignes.forEach((id, index) =>
{
if (id === id_ligne_standard)
{
console.log(`L'ID "${id}" a été trouvé à l'index ${index}.`);
}
if (id === id_ligne_estimation)
{
console.log(`L'ID "${id}" a été trouvé à l'index ${index}.`);
}
});
*/
let position_ligne_standard = list_lignes.indexOf(id_ligne_standard);
let position_ligne_estimation = list_lignes.indexOf(id_ligne_estimation);
console.log(" ------ position_ligne_standard " + position_ligne_standard);
console.log(" ------ position_ligne_estimation" + position_ligne_estimation);
// Vérifiez si une ligne existe sous la ligne estimation
if (position_ligne_estimation + 1 < list_lignes.length)
{
console.log("yes");
}
// Arrêtez la fonction si aucune ligne n'existe sous position_ligne_estimation
else
{
console.log("stop");
return;
}
// Vérifiez si la ligne en dessous de la ligne estimation est une ligne spéciale
let is_speciale = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation + 1].startsWith("special-");
// Vérifiez si la ligne en dessous de la ligne d'estimation est une ligne standard
let is_estimation = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation + 1].startsWith("standard-");
//console.log(is_speciale + " " + is_estimation + " " + list_lignes[position_ligne_estimation + 1]);
if( is_speciale === true )
{
// cette ligne speciale se trouve aprés la ligne estimation , c'est à dire +1
console.log("Saut speciale " + list_lignes[position_ligne_estimation + 1]);
// Étape 2 : Vérifier que e1 est juste avant v
if (list_lignes[position_ligne_estimation + 1].startsWith("special-") )
{
let save_identifiant_speciale = list_lignes[position_ligne_estimation + 1];
console.log(" save_identifiant_speciale " + save_identifiant_speciale);
let position_special = list_lignes.indexOf(save_identifiant_speciale);
console.log(" position_special " + position_special);
// supprime l'élément qui se trouve à cette position
//list_lignes.splice(position_special, 1);
// autre formulation : supprime l'index dont on donne l'identifiant
list_lignes.splice(list_lignes.indexOf(save_identifiant_speciale), 1);
// retourne l'index qui correspond à la valeur de l'id
let new_position_speciale = list_lignes.indexOf(id_ligne_standard);
console.log(" new_position_speciale " + new_position_speciale);
// Insérer save_identifiant_speciale à l’indice new_position_speciale
list_lignes.splice( new_position_speciale, 0, save_identifiant_speciale);
console.log("<<<<<<< Nouvel ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
}
}
if( is_estimation === true )
{
console.log(" Saut de la liaison " );
// saut : standard <-> standard+2
if (position_ligne_standard + 2 >= 0)
{
let temp = list_lignes[position_ligne_standard];
list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard + 2];
list_lignes[position_ligne_standard + 2] = temp;
}
// saut estimation <-> estimation+2
if (position_ligne_estimation + 2 >= 0)
{
let temp = list_lignes[position_ligne_estimation];
list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation + 2];
list_lignes[position_ligne_estimation + 2] = temp;
}
console.log("<<<<<<< Nouvel ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
}
}
/**************************************************************************/
function moveSpecialRowUp(row)
{
console.log("UP special");
const rowId = row.dataset.rowId;
const currentIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(row);
if (currentIndex > 0)
{
const previousRow = tableBody.querySelectorAll("tr")[currentIndex - 1];
const previousRowId = previousRow.dataset.rowId;
if (previousRowId.startsWith("special-"))
{
console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
let position_ligne_speciale = list_lignes.indexOf(previousRowId);
console.log(" TRACE position speciale " + position_ligne_speciale);
console.log(" TRACE identifiant speciale " + previousRowId);
// element à déplacer
console.log(" TRACE deplacer position current " + currentIndex);
console.log(" TRACE deplaced identifiant current " + rowId);
let save_identifiant_speciale = list_lignes[currentIndex];
console.log(" TRACE save identifiant " + save_identifiant_speciale);
// Supprime élément à cet index
list_lignes.splice(currentIndex, 1);
console.log("<<<<<<< Nouvel ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
list_lignes.splice( position_ligne_speciale , -1, save_identifiant_speciale);
console.log("<<<<<<< Nouvel ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
/* let save_identifiant_speciale = list_lignes.indexOf(currentIndex-1);
let save_position_speciale = list_lignes[save_identifiant_speciale];
console.log(" XXX " + save_position_speciale);
console.log(" YYY " + save_identifiant_speciale);
*/
return;
}
else if (previousRowId.startsWith("estimation-"))
{
console.log(" Saut de la liaison " );
//alert("La ligne au-dessus est une ligne d'estimation.");
console.log(" +++ estimation " + rowId);
console.log(" +++ estimation " + previousRowId);
// Trouver l'objet de liaison qui contient previousRowId
const linkage = linkages.find(link => link.estimationRowId === previousRowId);
if (linkage)
{
// Afficher les valeurs de l'objet de liaison dans la console
console.log("Objet de liaison trouvé :", linkage);
console.log("Identifiant de la ligne standard :", linkage.standardRowId);
console.log("Identifiant de la ligne d'estimation :", linkage.estimationRowId);
let position_ligne_speciale_selection = list_lignes.indexOf(rowId);
console.log("Position selection:", position_ligne_speciale_selection);
//aaa
list_lignes.splice(position_ligne_speciale_selection, 1); // Supprime élément à cet index
console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
let position_ligne_standard = list_lignes.indexOf(linkage.standardRowId);
console.log("Position pour insertion:", position_ligne_standard);
// insérer rowId a
list_lignes.splice( position_ligne_standard , 0, rowId);
console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
} else
{
console.log("Aucun objet de liaison trouvé pour l'identifiant :", previousRowId);
}
// return;
}
// Si la ligne au-dessus n'est ni spéciale ni d'estimation, procédez au déplacement
//tableBody.insertBefore(row, previousRow);
//reorderTableRows(list_lignes);
}
else
{
alert("Aucune ligne au-dessus pour effectuer le déplacement.");
}
}
/**********************************************************************************************/
function moveSpecialRowDown(row)
{
console.log("DOWN");
const rowId = row.dataset.rowId;
const currentIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(row);
if (currentIndex >= 0 && currentIndex < tableBody.querySelectorAll("tr").length - 1)
{
const previousRow = tableBody.querySelectorAll("tr")[currentIndex + 1];
const previousRowId = previousRow.dataset.rowId;
console.log(" ------ " + rowId + " " + previousRowId);
if (previousRowId.startsWith("special-"))
{
console.log("Special detection");
// supprimer l'identifiant
let index_ligne_speciale = list_lignes.indexOf(rowId);
list_lignes.splice(index_ligne_speciale, 1); // Supprime élément à cet index
console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// rechrcher position de previousRowId
let bidule = list_lignes.indexOf(previousRowId);
// insérer rowId aprés le position de previousRowId
list_lignes.splice( bidule + 1 , 0, rowId);
console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
}
else if (previousRowId.startsWith("standard-"))
{
console.log("Saut de la liaison");
// Trouver l'objet de liaison qui contient previousRowId
const linkage = linkages.find(link => link.standardRowId === previousRowId);
if (linkage)
{
// Afficher les valeurs de l'objet de liaison dans la console
console.log("Objet de liaison trouvé :", linkage);
console.log("Identifiant de la ligne standard :", linkage.standardRowId);
console.log("Identifiant de la ligne d'estimation :", linkage.estimationRowId);
// sauvegarder l'identifiant de la ligne speciale
let save_identifiant_speciale = list_lignes[currentIndex];
console.log(" TRACE sauve identifiant speciale " + save_identifiant_speciale);
// supprimer l'identifiant
let index_ligne_speciale = list_lignes.indexOf(save_identifiant_speciale);
list_lignes.splice(index_ligne_speciale, 1); // Supprime élément à cet index
console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// rechercher la position de linkage.estimationRowId
let index_ligne_estimation = list_lignes.indexOf(linkage.estimationRowId);
// insérer sous la ligne estimation
list_lignes.splice( index_ligne_estimation + 1 , 0, save_identifiant_speciale);
console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
console.log(list_lignes);
console.log("<<<<<<<>>>>>>>>");
// Réorganiser les lignes du tableau en fonction de biduleArr
reorderTableRows(list_lignes);
}
}
else
{
console.log("Aucun objet de liaison trouvé pour l'identifiant :", previousRowId);
}
}
}
/**************************************************************************/
function reorderTableRows(biduleArr) {
// Récupérer toutes les lignes du tableau
const allRows = Array.from(tableBody.querySelectorAll("tr"));
// Créer un mapping des lignes par leur identifiant
const rowMap = new Map(allRows.map(row => [row.dataset.rowId, row]));
// Réorganiser les lignes en fonction de biduleArr
const orderedRows = biduleArr.map(id => rowMap.get(id)).filter(row => row !== undefined);
// Vider le tableau actuel
tableBody.innerHTML = "";
// Ajouter les lignes réorganisées au tableau
orderedRows.forEach(row => {
tableBody.appendChild(row);
});
// Réattacher les événements de drag-and-drop aux lignes
orderedRows.forEach(row => {
row.addEventListener("dragstart", dragStart);
row.addEventListener("dragover", dragOver);
row.addEventListener("drop", drop);
});
}
/**************************************************************************/
/*
function moveElementsByOffset(arr, moveList) {
let result = [...arr]; // copie du tableau d’origine
let original = [...arr]; // pour garder les index de référence initiaux
moveList.forEach(move => {
let { value, shift } = move;
let currentIndex = result.indexOf(value);
let originalIndex = original.indexOf(value);
let newIndex = Math.max(originalIndex + shift, 0);
// On retire l’élément de sa position actuelle
result.splice(currentIndex, 1);
// Puis on l’insère à la nouvelle position
result.splice(newIndex, 0, value);
});
return result;
}
*/
/*************************************************************************/
function updateRowData(element) {
const row = element.closest("tr");
const rowId = row.dataset.rowId;
if (rowId.startsWith("standard-")) {
let standardRowData = standardRowsData.find(data => data.id === rowId);
if (!standardRowData) {
standardRowData = {
id: rowId,
name: "",
selectValue: "",
count: "",
cells: [],
selection: "OFF" // TAG : SELECTION
};
standardRowsData.push(standardRowData);
}
const cells = row.querySelectorAll("td");
standardRowData.name = cells[0].querySelector("input").value;
standardRowData.selectValue = cells[1].querySelector("select").value;
standardRowData.count = cells[2].textContent.trim();
standardRowData.cells = [];
cells.forEach((cell, index) => {
if (index > 2) {
standardRowData.cells.push({
value: cell.dataset.cellValue,
color: cell.dataset.cellColor,
full_date: cell.dataset.fullDate // Ajouter la clé full_date
});
}
});
console.log(`Mise à jour de la ligne standard : ${rowId}`);
} else if (rowId.startsWith("estimation-")) {
let estimationRowData = estimationRowsData.find(data => data.id === rowId);
if (!estimationRowData) {
estimationRowData = {
id: rowId,
name: "",
selectValue: "",
estimationValue: "",
selection: "OFF" // TAG : SELECTION
};
estimationRowsData.push(estimationRowData);
}
const cells = row.querySelectorAll("td");
estimationRowData.name = cells[0].querySelector("input").value;
estimationRowData.selectValue = cells[1].querySelector("select").value;
estimationRowData.estimationValue = cells[2].querySelector("input").value;
console.log(`Mise à jour de la ligne d'estimation : ${rowId}`);
} else if (rowId.startsWith("special-")) {
let specialRowData = specialRowsData.find(data => data.id === rowId);
if (!specialRowData) {
specialRowData = {
id: rowId,
name: "",
selection: "OFF" // TAG : SELECTION
};
specialRowsData.push(specialRowData);
}
specialRowData.name = row.querySelector("input").value;
console.log(`Mise à jour de la ligne spéciale : ${rowId}`);
}
}
/*
function displayLinkages() {
const debugOutputElement = document.getElementById("debugOutput");
debugOutputElement.textContent = JSON.stringify(linkages, null, 2);
}
*/
/**********************************************************************************************/
function updateCountCell(row) {
const countCell = row.cells[2];
const count = Array.from(row.cells).slice(3).filter(cell => cell.dataset.cellValue === "1").length;
countCell.textContent = count;
}
/**********************************************************************************************/
function displayListLignes()
{
// Fonction pour afficher le contenu de list_lignes dans la console
console.log("Contenu de list_lignes :", list_lignes);
}
/**********************************************************************************************/
function displaySpecialRowsData() {
console.log("Contenu de specialRowsData :");
specialRowsData.forEach((rowData, index) => {
console.log(`Ligne spéciale ${index + 1} :`, rowData);
});
}
/**********************************************************************************************/
function addSpecialRow(afterRow = null) {
const newRow = document.createElement("tr");
newRow.classList.add("special-row");
newRow.setAttribute("draggable", "true");
newRow.dataset.rowId = `special-${generateRandomId()}`;
newRow.title = newRow.dataset.rowId; // Ajoutez cette ligne
const specialRowData = {
id: newRow.dataset.rowId,
name: `Ligne spéciale ${specialRowCounter}`,
selection: "OFF" // Ajouter la variable selection
};
// Ajoutez l'identifiant de la ligne spéciale dans le tableau list_lignes
list_lignes.push(newRow.dataset.rowId);
const firstCell = document.createElement("td");
firstCell.classList.add("row-header");
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = specialRowData.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
});
input.addEventListener("blur", function () {
input.classList.remove("editing");
input.style.width = "65px";
updateRowData(input);
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
updateRowData(input);
}
});
input.addEventListener("input", function () {
updateRowData(input);
});
const addButton = document.createElement("button");
addButton.classList.add("add-button");
addButton.textContent = "+";
addButton.addEventListener("click", function () {
toggleCollapse(newRow);
});
firstCell.appendChild(input);
firstCell.appendChild(addButton);
firstCell.addEventListener("contextmenu", function (event) {
event.preventDefault();
showSpecialContextMenu(event, newRow);
});
// Ajouter un gestionnaire de clic pour changer la couleur de fond
firstCell.addEventListener("click", function () {
handleSpecialRowClick(newRow, firstCell);
});
newRow.appendChild(firstCell);
const mergedCell = document.createElement("td");
mergedCell.colSpan = 2;
mergedCell.textContent = "";
newRow.appendChild(mergedCell);
const td = document.createElement("td");
td.textContent = `Ligne spéciale ${specialRowCounter} - Détails`;
td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
newRow.appendChild(td);
if (afterRow) {
tableBody.insertBefore(newRow, afterRow.nextSibling);
} else {
tableBody.appendChild(newRow);
}
newRow.addEventListener("dragstart", dragStart);
newRow.addEventListener("dragover", dragOver);
newRow.addEventListener("drop", drop);
specialRowsData.push(specialRowData); // Ajouter l'objet dans le tableau dédié
specialRowCounter++;
// Afficher le contenu du tableau specialRowsData après l'ajout
displaySpecialRowsData();
}
/**********************************************************************************************/
function handleSpecialRowClick(row, td) {
const rowId = row.dataset.rowId;
const specialRowData = specialRowsData.find(data => data.id === rowId);
if (specialRowData) {
// Vérifiez si le clic est sur le bouton "+"
if (event.target.classList.contains('add-button')) {
return; // Ignorer le clic sur le bouton "+"
}
if (objet_selection.length > 0 && !objet_selection.includes(rowId)) {
// Afficher une fenêtre modale indiquant qu'une seule sélection est possible à la fois
showMessageModal("Une seule sélection est possible à la fois.");
return; // Empêcher la couleur de fond de changer
}
if (specialRowData.selection === "OFF") {
specialRowData.selection = "ON";
td.style.backgroundColor = "blue";
// Ajoutez l'identifiant à objet_selection
if (!objet_selection.includes(rowId)) {
objet_selection.push(rowId);
}
} else {
specialRowData.selection = "OFF";
td.style.backgroundColor = "white";
// Supprimer l'identifiant de objet_selection
objet_selection = objet_selection.filter(id => id !== rowId);
}
}
// Afficher les identifiants dans objet_selection pour vérification
console.log("objet_selection:", objet_selection);
}
/**********************************************************************************************/
function toggleCollapse(specialRow) {
const nextSpecialRow = getNextSpecialRow(specialRow);
const rowsToToggle = [];
let currentRow = specialRow.nextElementSibling;
while (currentRow && currentRow !== nextSpecialRow) {
if (!currentRow.classList.contains("special-row")) {
rowsToToggle.push(currentRow);
}
currentRow = currentRow.nextElementSibling;
}
rowsToToggle.forEach(row => {
row.classList.toggle("collapsed");
});
}
/**********************************************************************************************/
function getNextSpecialRow(specialRow) {
let currentRow = specialRow.nextElementSibling;
while (currentRow) {
if (currentRow.classList.contains("special-row")) {
return currentRow;
}
currentRow = currentRow.nextElementSibling;
}
return null;
}
/**********************************************************************************************/
function showContextMenu(event, row) {
// Vérifier si la ligne est une ligne standard ou une ligne d'estimation
const rowId = row.dataset.rowId;
const isEstimationRow = rowId.startsWith("estimation-");
// Construire le menu contextuel en fonction du type de ligne
let contextMenuHTML = `
<button class="dropdown-item" id="delete-row">Supprimer cette ligne</button>
<button class="dropdown-item" id="up-elements">UP</button>
<button class="dropdown-item" id="down-elements">DOWN</button>
`;
// Ajouter l'option "Ajouter une ligne standard" en haut du menu
if (isEstimationRow) {
contextMenuHTML = `<button class="dropdown-item" id="add-row">Ajouter une ligne standard</button>` + contextMenuHTML;
}
// Ajouter l'option "Ajouter une ligne spéciale" en haut du menu
if (isEstimationRow) {
contextMenuHTML = `<button class="dropdown-item" id="add-special-row">Ajouter une ligne spéciale</button>` + contextMenuHTML;
}
contextMenu.innerHTML = contextMenuHTML;
contextMenu.style.top = `${event.clientY}px`;
contextMenu.style.left = `${event.clientX}px`;
contextMenu.style.display = "flex";
contextMenu.style.flexDirection = "column";
// Vérifier si les options UP et DOWN doivent être désactivées
let linkedRowId = null;
let linkedRow = null;
if (rowId.startsWith("standard-")) {
const linkage = linkages.find(link => link.standardRowId === rowId);
if (linkage) {
linkedRowId = linkage.estimationRowId;
linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
}
} else if (rowId.startsWith("estimation-")) {
const linkage = linkages.find(link => link.estimationRowId === rowId);
if (linkage) {
linkedRowId = linkage.standardRowId;
linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
}
}
let disableUpDown = true;
if (linkedRow) {
const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);
if (standardRowData.selection === "ON" && estimationRowData.selection === "ON") {
disableUpDown = false;
}
}
const upButton = document.getElementById("up-elements");
const downButton = document.getElementById("down-elements");
if (disableUpDown) {
upButton.classList.add("disabled");
downButton.classList.add("disabled");
} else {
upButton.classList.remove("disabled");
downButton.classList.remove("disabled");
}
if (isEstimationRow) {
document.getElementById("add-row").addEventListener("click", function () {
addRow(row);
hideContextMenu();
});
}
if (isEstimationRow) {
document.getElementById("add-special-row").addEventListener("click", function () {
addSpecialRow(row);
hideContextMenu();
});
}
document.getElementById("delete-row").addEventListener("click", function () {
showConfirmationModal(row);
hideContextMenu();
});
upButton.addEventListener("click", function () {
if (!disableUpDown) {
moveRowsUp();
hideContextMenu();
}
});
downButton.addEventListener("click", function () {
if (!disableUpDown) {
moveRowsDown();
hideContextMenu();
}
});
// Ajouter une classe CSS pour styliser les options désactivées
/* const style = document.createElement('style');
style.innerHTML = `
.dropdown-item.disabled {
pointer-events: none;
color: #6c757d;
}
`;
document.head.appendChild(style);*/
}
function original_showContextMenu(event, row)
{
contextMenu.innerHTML = `
<button class="dropdown-item" id="add-row">xxxAjouter une ligne standard</button>
<button class="dropdown-item" id="add-special-row">Ajouter une ligne spéciale</button>
<button class="dropdown-item" id="delete-row">Supprimer cette ligne</button>
<!--
<button class="dropdown-item" id="show-linkage">Afficher la liaison</button>
-->
<button class="dropdown-item" id="up-elements">wwwUP</button>
<button class="dropdown-item" id="down-elements">DOWN</button>
`;
//<button class="dropdown-item text-danger" id="delete-row">Supprimer cette ligne</button>
contextMenu.style.top = `${event.clientY}px`;
contextMenu.style.left = `${event.clientX}px`;
contextMenu.style.display = "flex";
contextMenu.style.flexDirection = "column";
// Vérifier si la ligne est une ligne standard ou une ligne d'estimation
const rowId = row.dataset.rowId;
const isEstimationRow = rowId.startsWith("estimation-");
// Afficher ou masquer l'option "Ajouter une ligne" en fonction du type de ligne
const addRowButton = document.getElementById("add-row");
if (isEstimationRow) {
addRowButton.style.display = "block";
} else {
addRowButton.style.display = "none";
}
let linkedRowId = null;
let linkedRow = null;
// Vérifier si les options UP et DOWN doivent être désactivées
if (rowId.startsWith("standard-")) {
const linkage = linkages.find(link => link.standardRowId === rowId);
if (linkage) {
linkedRowId = linkage.estimationRowId;
linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
}
} else if (rowId.startsWith("estimation-")) {
const linkage = linkages.find(link => link.estimationRowId === rowId);
if (linkage) {
linkedRowId = linkage.standardRowId;
linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
}
}
let disableUpDown = true;
if (linkedRow) {
const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);
if (standardRowData.selection === "ON" && estimationRowData.selection === "ON") {
disableUpDown = false;
}
}
const upButton = document.getElementById("up-elements");
const downButton = document.getElementById("down-elements");
if (disableUpDown) {
upButton.classList.add("disabled");
downButton.classList.add("disabled");
} else {
upButton.classList.remove("disabled");
downButton.classList.remove("disabled");
}
//1234 aaa
document.getElementById("add-row").addEventListener("click", function () {
addRow(row);
hideContextMenu();
});
document.getElementById("add-special-row").addEventListener("click", function () {
addSpecialRow(row);
hideContextMenu();
});
document.getElementById("delete-row").addEventListener("click", function () {
showConfirmationModal(row);
hideContextMenu();
});
/* plus actif
document.getElementById("show-linkage").addEventListener("click", function () {
const linkage = linkages.find(link => link.standardRowId === row.dataset.rowId || link.estimationRowId === row.dataset.rowId);
if (linkage) {
alert(`Liaison trouvée :\nID: ${linkage.id}\nLigne standard: ${linkage.standardRowId}\nLigne estimation: ${linkage.estimationRowId}`);
} else {
alert("Aucune liaison trouvée pour cette ligne.");
}
hideContextMenu();
});
*/
upButton.addEventListener("click", function () {
if (!disableUpDown) {
moveRowsUp();
hideContextMenu();
}
});
downButton.addEventListener("click", function () {
if (!disableUpDown) {
moveRowsDown();
hideContextMenu();
}
});
// Ajouter une classe CSS pour styliser les options désactivées
const style = document.createElement('style');
style.innerHTML = `
.dropdown-item.disabled {
pointer-events: none;
color: #6c757d;
}
`;
document.head.appendChild(style);
}
// Ajouter une classe CSS pour styliser les options désactivées
/*
const style = document.createElement('style');
style.innerHTML = `
.dropdown-item.disabled {
pointer-events: none;
color: #6c757d;
}
`;
document.head.appendChild(style);
*/
/**********************************************************************************************/
function insertSpecialRow(direction, row) {
const newSpecialRow = document.createElement("tr");
newSpecialRow.classList.add("special-row");
newSpecialRow.setAttribute("draggable", "true");
newSpecialRow.dataset.rowId = `special-${generateRandomId()}`;
newSpecialRow.title = newSpecialRow.dataset.rowId;
const firstCell = document.createElement("td");
firstCell.classList.add("row-header");
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = `Ligne spéciale`;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
});
input.addEventListener("blur", function () {
input.classList.remove("editing");
input.style.width = "65px";
updateRowData(input);
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
updateRowData(input);
}
});
input.addEventListener("input", function () {
updateRowData(input);
});
const addButton = document.createElement("button");
addButton.classList.add("add-button");
addButton.textContent = "+";
addButton.addEventListener("click", function () {
toggleCollapse(newSpecialRow);
});
firstCell.appendChild(input);
firstCell.appendChild(addButton);
firstCell.addEventListener("contextmenu", function (event) {
event.preventDefault();
showSpecialContextMenu(event, newSpecialRow);
});
newSpecialRow.appendChild(firstCell);
const mergedCell = document.createElement("td");
mergedCell.colSpan = 2;
mergedCell.textContent = "";
newSpecialRow.appendChild(mergedCell);
const td = document.createElement("td");
td.textContent = `Ligne spéciale - Détails`;
td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
newSpecialRow.appendChild(td);
if (direction === "up") {
tableBody.insertBefore(newSpecialRow, row);
} else if (direction === "down") {
tableBody.insertBefore(newSpecialRow, row.nextSibling);
}
newSpecialRow.addEventListener("dragstart", dragStart);
newSpecialRow.addEventListener("dragover", dragOver);
newSpecialRow.addEventListener("drop", drop);
specialRowsData.push({
id: newSpecialRow.dataset.rowId,
name: input.value
});
// Afficher le contenu du tableau specialRowsData après l'ajout
displaySpecialRowsData();
}
/**********************************************************************************************/
function showSpecialContextMenu(event, row) {
specialContextMenu.innerHTML = `
<button class="dropdown-item" id="add-row">Ajouter une ligne standard</button>
<button class="dropdown-item" id="add-special-row">Ajouter une ligne spéciale</button>
<button class="dropdown-item" id="delete-special-row">Supprimer cette ligne</button>
<!--
<button class="dropdown-item text-danger" id="delete-special-row">Supprimer cette ligne</button>
-->
<!-- <label class="dropdown-item">
<input type="checkbox" id="special-checkbox"> Attacher
</label> -->
<button class="dropdown-item" id="up-special-row">UP</button>
<button class="dropdown-item" id="down-special-row">DOWN</button>
`;
specialContextMenu.style.top = `${event.clientY}px`;
specialContextMenu.style.left = `${event.clientX}px`;
specialContextMenu.style.display = "flex";
specialContextMenu.style.flexDirection = "column";
// inactif attacher const checkbox = document.getElementById("special-checkbox");
const rowId = row.dataset.rowId;
// inactif attacher let hasStandardRowsBelow = false;
// inactif attacher let currentRow = row.nextElementSibling;
// inactif attacher const standardRows = [];
// inactif attacher while (currentRow && !currentRow.classList.contains("special-row")) {
// inactif attacher if (!currentRow.classList.contains("special-row")) {
// inactif attacher hasStandardRowsBelow = true;
// inactif attacher standardRows.push(currentRow);
// inactif attacher }
// inactif attacher currentRow = currentRow.nextElementSibling;
// inactif attacher }
// inactif attacher if (hasStandardRowsBelow) {
// inactif attacher checkbox.disabled = false;
// inactif attacher } else {
// inactif attacher checkbox.disabled = true;
// inactif attacher checkbox.checked = false;
// inactif attacher }
// inactif attacher if (specialRowStates[rowId]) {
// inactif attacher checkbox.checked = specialRowStates[rowId].checked;
// inactif attacher }
// inactif attacher checkbox.addEventListener("change", function () {
// inactif attacher specialRowStates[rowId] = {
// inactif attacher checked: checkbox.checked,
// inactif attacher rows: standardRows
// inactif attacher };
// inactif attacher standardRows.forEach(standardRow => {
// inactif attacher const firstCell = standardRow.querySelector("td:first-child");
// inactif attacher if (checkbox.checked) {
// inactif attacher firstCell.style.backgroundColor = "yellow";
// inactif attacher standardRow.classList.add("no-drag");
// inactif attacher } else {
// inactif attacher firstCell.style.backgroundColor = "";
// inactif attacher standardRow.classList.remove("no-drag");
// inactif attacher }
// inactif attacher });
// inactif attacher if (checkbox.checked) {
// inactif attacher associations[rowId] = standardRows.map(row => row.dataset.rowId);
// inactif attacher } else {
// inactif attacher delete associations[rowId];
// inactif attacher }
// inactif attacher console.log(`Lignes standards concernées : ${standardRows.map(row => row.rowIndex).join(", ")}`);
// inactif attacher });
// Vérifier si les options UP et DOWN doivent être désactivées
const specialRowData = specialRowsData.find(data => data.id === rowId);
let disableUpDown = true;
if (specialRowData && specialRowData.selection === "ON") {
disableUpDown = false;
}
const upButton = document.getElementById("up-special-row");
const downButton = document.getElementById("down-special-row");
if (disableUpDown) {
upButton.classList.add("disabled");
downButton.classList.add("disabled");
} else {
upButton.classList.remove("disabled");
downButton.classList.remove("disabled");
}
document.getElementById("add-row").addEventListener("click", function () {
addRow(row);
hideSpecialContextMenu();
});
document.getElementById("add-special-row").addEventListener("click", function () {
addSpecialRow(row);
hideSpecialContextMenu();
});
document.getElementById("delete-special-row").addEventListener("click", function () {
showConfirmationModal(row);
hideSpecialContextMenu();
});
upButton.addEventListener("click", function () {
if (!disableUpDown) {
moveSpecialRowUp(row);
hideSpecialContextMenu();
}
});
downButton.addEventListener("click", function () {
if (!disableUpDown) {
moveSpecialRowDown(row);
hideSpecialContextMenu();
}
});
}
/**********************************************************************************************/
function oooooooshowSpecialContextMenu(event, row) {
specialContextMenu.innerHTML = `
<button class="dropdown-item" id="add-special-row">Ajouter une ligne spéciale</button>
<button class="dropdown-item text-danger" id="delete-special-row">Supprimer cette ligne</button>
<label class="dropdown-item">
<input type="checkbox" id="special-checkbox"> Attacher
</label>
<button class="dropdown-item" id="up-special-row">UP</button>
<button class="dropdown-item" id="down-special-row">DOWN</button>
`;
specialContextMenu.style.top = `${event.clientY}px`;
specialContextMenu.style.left = `${event.clientX}px`;
specialContextMenu.style.display = "flex";
specialContextMenu.style.flexDirection = "column";
const checkbox = document.getElementById("special-checkbox");
const rowId = row.dataset.rowId;
let hasStandardRowsBelow = false;
let currentRow = row.nextElementSibling;
const standardRows = [];
while (currentRow && !currentRow.classList.contains("special-row")) {
if (!currentRow.classList.contains("special-row")) {
hasStandardRowsBelow = true;
standardRows.push(currentRow);
}
currentRow = currentRow.nextElementSibling;
}
if (hasStandardRowsBelow) {
checkbox.disabled = false;
} else {
checkbox.disabled = true;
checkbox.checked = false;
}
if (specialRowStates[rowId]) {
checkbox.checked = specialRowStates[rowId].checked;
}
checkbox.addEventListener("change", function ()
{
specialRowStates[rowId] = {
checked: checkbox.checked,
rows: standardRows
};
standardRows.forEach(standardRow => {
const firstCell = standardRow.querySelector("td:first-child");
if (checkbox.checked) {
firstCell.style.backgroundColor = "yellow";
standardRow.classList.add("no-drag");
} else {
firstCell.style.backgroundColor = "";
standardRow.classList.remove("no-drag");
}
});
if (checkbox.checked) {
associations[rowId] = standardRows.map(row => row.dataset.rowId);
} else {
delete associations[rowId];
}
console.log(`Lignes standards concernées : ${standardRows.map(row => row.rowIndex).join(", ")}`);
});
// Vérifier si les options UP et DOWN doivent être désactivées
const specialRowData = specialRowsData.find(data => data.id === rowId);
let disableUpDown = true;
if (specialRowData && specialRowData.selection === "ON") {
disableUpDown = false;
}
const upButton = document.getElementById("up-special-row");
const downButton = document.getElementById("down-special-row");
if (disableUpDown) {
upButton.classList.add("disabled");
downButton.classList.add("disabled");
} else {
upButton.classList.remove("disabled");
downButton.classList.remove("disabled");
}
document.getElementById("add-special-row").addEventListener("click", function () {
addSpecialRow(row);
hideSpecialContextMenu();
});
document.getElementById("delete-special-row").addEventListener("click", function ()
{
console.log(" ***** " + row)
showConfirmationModal(row);
hideSpecialContextMenu();
});
upButton.addEventListener("click", function () {
if (!disableUpDown) {
moveSpecialRowUp(row);
hideSpecialContextMenu();
}
});
downButton.addEventListener("click", function () {
if (!disableUpDown) {
moveSpecialRowDown(row);
hideSpecialContextMenu();
}
});
}
// Ajouter une classe CSS pour styliser les options désactivées
/*const style = document.createElement('style');
style.innerHTML = `
.dropdown-item.disabled {
pointer-events: none;
color: #6c757d;
}
`;
document.head.appendChild(style);*/
/**********************************************************************************************/
function showColorContextMenu(event, cell) {
colorContextMenu.style.top = `${event.clientY}px`;
colorContextMenu.style.left = `${event.clientX}px`;
colorContextMenu.style.display = "flex";
colorContextMenu.style.flexDirection = "column";
document.querySelectorAll(".selected-cell").forEach(c => c.classList.remove("selected-cell"));
cell.classList.add("selected-cell");
}
/**********************************************************************************************/
/*
function displayStandardRowsData() {
console.log("Contenu de standardRowsData :");
standardRowsData.forEach((rowData, index) => {
console.log(`Ligne ${index + 1} :`, rowData);
});
}
function displayEstimationRowsData() {
console.log("Contenu de estimationRowsData :");
estimationRowsData.forEach((rowData, index) => {
console.log(`Ligne ${index + 1} :`, rowData);
});
}
*/
/**********************************************************************************************/
/*
function displaySpecialRowsData() {
console.log("Contenu de specialRowsData :");
specialRowsData.forEach((rowData, index) => {
console.log(`Ligne ${index + 1} :`, rowData);
});
}
*/
/**********************************************************************************************/
/*
function displayLinkagesData() {
console.log("Contenu de LinkagesData :");
linkages.forEach((rowData, index) => {
console.log(`Ligne ${index + 1} :`, rowData);
});
}
*/
/**********************************************************************************************/
function showMessageModal(message) {
const modal = new bootstrap.Modal(document.getElementById('messageModal'));
const modalBody = document.getElementById('messageModalBody');
modalBody.textContent = message;
modal.show();
}
document.addEventListener("click", function (event) {
if (!contextMenu.contains(event.target)) {
hideContextMenu();
}
if (!specialContextMenu.contains(event.target)) {
hideSpecialContextMenu();
}
if (!colorContextMenu.contains(event.target)) {
hideColorContextMenu();
}
const inputs = document.querySelectorAll(".editable-input");
inputs.forEach(input => {
if (!input.contains(event.target)) {
input.classList.remove("editing");
}
});
});
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") {
hideContextMenu();
hideSpecialContextMenu();
hideColorContextMenu();
}
});
function hideContextMenu() {
contextMenu.style.display = "none";
}
function hideSpecialContextMenu() {
specialContextMenu.style.display = "none";
}
function hideColorContextMenu() {
colorContextMenu.style.display = "none";
}
document.getElementById("addRowButton").addEventListener("click", addRow);
document.getElementById("addSpecialRowButton").addEventListener("click", addSpecialRow);
document.querySelectorAll("tbody tr td:first-child").forEach(td => {
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, td.parentElement);
});
});
/**********************************************************************************************/
let draggedRowId = null;
function zzzzzzdragStart(event) {
const row = event.target.closest("tr");
if (row.classList.contains("no-drag")) {
event.preventDefault();
return;
}
draggedRowId = row.dataset.rowId;
event.dataTransfer.setData("text/plain", row.rowIndex);
row.classList.add("dragging");
}
function dragStart(event) {
const row = event.target.closest("tr");
if (!row) return;
const rowId = row.dataset.rowId;
// Vérifiez si la ligne est une ligne d'estimation
if (rowId.startsWith("standard-") || rowId.startsWith("estimation-"))
{
event.preventDefault();
return;
}
draggedRowId = row.dataset.rowId;
event.dataTransfer.setData("text/plain", row.rowIndex);
row.classList.add("dragging");
}
/**********************************************************************************************/
function dragOver(event)
{
event.preventDefault();
const draggingRow = document.querySelector(".dragging");
const targetRow = event.target.closest("tr");
if (targetRow && draggingRow !== targetRow && !targetRow.classList.contains("no-drag")) {
const rect = targetRow.getBoundingClientRect();
const offset = rect.top + (rect.height / 2);
if (event.clientY - offset > 0) {
tableBody.insertBefore(draggingRow, targetRow.nextSibling);
} else {
tableBody.insertBefore(draggingRow, targetRow);
}
const targetRowId = targetRow.dataset.rowId;
let linkage = null;
if (targetRowId.startsWith("standard-")) {
linkage = linkages.find(link => link.standardRowId === targetRowId);
} else if (targetRowId.startsWith("estimation-")) {
linkage = linkages.find(link => link.estimationRowId === targetRowId);
}
if (linkage) {
const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
console.log("++++ " + linkage.standardRowId + " + " + linkage.estimationRowId + " at index " + draggedRowIndex);
}
}
}
/**********************************************************************************************/
function drop(event)
{
event.preventDefault();
const draggingRow = document.querySelector(".dragging");
draggingRow.classList.remove("dragging");
const draggingRowId = draggingRow.dataset.rowId;
let linkage = null;
console.log(" Element " + draggingRowId);
if (draggingRowId.startsWith("standard-"))
{
linkage = linkages.find(link => link.standardRowId === draggingRowId);
console.log("Standard " + draggingRowId + " " + linkage.estimationRowId + " " + linkage.id );
// sauvegarde l'identifiant qui correspond à la ligne estimation
let save_identifiant_estimation = linkage.estimationRowId;
console.log(" TRACE sauve identifiant estimation " + save_identifiant_estimation);
// Sélectionnez la ligne avec l'identifiant donné
//const row = document.querySelector(`tr[data-row-id="${linkage.estimationRowId}"]`);
//if (row)
//{
// Supprimez la ligne du DOM
// row.remove();
// console.log(`Ligne avec l'identifiant ${linkage.estimationRowId} supprimée.`);
//}
//else
//{
// console.log(`Aucune ligne trouvée avec l'identifiant ${linkage.estimationRowId}.`);
//}
const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
console.log("Position ligne drag standard " + draggedRowIndex);
// Sélectionnez la ligne avec l'identifiant donné
const estimationRow = document.querySelector(`tr[data-row-id="${linkage.estimationRowId}"]`);
if (estimationRow) {
// Obtenez toutes les lignes du tbody
const rows = Array.from(tableBody.querySelectorAll("tr"));
// Trouvez l'index de la ligne estimation
const estimationRowIndex = rows.indexOf(estimationRow);
console.log("Position ligne estimation yes" + estimationRowIndex);
moveEstimationRow(estimationRowIndex, draggedRowIndex + 1);
} else {
console.log(`Aucune ligne trouvée avec l'identifiant ${save_identifiant_estimation}.`);
}
//const position_ligne_estimation = Array.from(tableBody.querySelectorAll("tr")).indexOf(linkage.estimationRowId);
//console.log("Position ligne estimation " + position_ligne_estimation);
/*console.log("Contenu de estimationRowsData :");
estimationRowsData.forEach((rowData, index) => {
console.log(`Ligne d'estimation ${index + 1} :`, rowData);
});*/
// a partir de l'identifiant de la ligne estimation, il faut retrouver les valeurs contenu dans l'objet
//moveEstimationRow(3, draggedRowIndex + 1);
}
else if (draggingRowId.startsWith("estimation-"))
{
linkage = linkages.find(link => link.estimationRowId === draggingRowId);
console.log("Estimation " );
}
if (linkage)
{
const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
console.log("++++ " + linkage.standardRowId + " + " + linkage.estimationRowId + " at index " + draggedRowIndex);
console.log("Linkage " );
}
if (draggingRowId.startsWith("xxxxxxxspecial-"))
{
console.log("Zoulou" );
// donne moi la position de la ligne speciale
const index = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
console.log("Position ligne speciale " + index + " " + draggingRowId);
// donne moi le nom de la ligne placée au dessus
// donne moi le nom de la ligne placée en dessous
// Donne moi le nom de la ligne placée au-dessus
const previousRow = tableBody.querySelectorAll("tr")[index - 1];
const nextRow = tableBody.querySelectorAll("tr")[index + 1];
if (previousRow) {
const previousRowId = previousRow.dataset.rowId;
console.log("Identifiant de la ligne précédente :", previousRowId);
}
if (nextRow) {
const nextRowId = nextRow.dataset.rowId;
console.log("Identifiant de la ligne suivante :", nextRowId);
}
}
//if (draggingRow.classList.contains("special-"))
//if (draggingRow.contains("special-"))
if (draggingRowId.startsWith("special-"))
{
console.log("Speciale ");
const specialRowId = draggingRow.dataset.rowId;
const newIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
// Vérifiez si la nouvelle position est entre une ligne standard et une ligne d'estimation liées
const previousRow = tableBody.querySelectorAll("tr")[newIndex - 1];
const nextRow = tableBody.querySelectorAll("tr")[newIndex + 1];
if (previousRow && nextRow) {
const previousRowId = previousRow.dataset.rowId;
const nextRowId = nextRow.dataset.rowId;
const linkage = linkages.find(link =>
(link.standardRowId === previousRowId && link.estimationRowId === nextRowId) ||
(link.standardRowId === nextRowId && link.estimationRowId === previousRowId)
);
if (linkage) {
// Ajustez la position en fonction de la direction du drag
const direction = draggingRow.rowIndex < newIndex ? 1 : -1;
tableBody.insertBefore(draggingRow, tableBody.querySelectorAll("tr")[newIndex + direction]);
}
}
if (associations[specialRowId]) {
const associatedRowIds = associations[specialRowId];
associatedRowIds.forEach(rowId => {
const associatedRow = document.querySelector(`tr[data-row-id="${rowId}"]`);
if (associatedRow) {
tableBody.insertBefore(associatedRow, draggingRow.nextSibling);
}
});
}
}
/*
let tmp_list_lignes = [];
const allRows = Array.from(tableBody.querySelectorAll("tr"));
allRows.forEach(row => {
tmp_list_lignes.push(row.dataset.rowId);
});
console.log("Contenu de list_lignes :", tmp_list_lignes);
displayListLignes();
*/
}
/**********************************************************************************************/
let deletedEstimationRowData = null;
function deleteRowById(rowId) {
const row = document.querySelector(`tr[data-row-id="${rowId}"]`);
if (row) {
// Conservez les données de la ligne avant de la supprimer
deletedEstimationRowData = {
id: row.dataset.rowId,
name: row.cells[0].querySelector("input").value,
selectValue: row.cells[1].querySelector("select").value,
estimationValue: row.cells[2].querySelector("input").value,
selection: row.cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
};
// Supprimez la ligne du DOM
row.remove();
console.log(`Ligne avec l'identifiant ${rowId} supprimée.`);
} else {
console.log(`Aucune ligne trouvée avec l'identifiant ${rowId}.`);
}
}
/**********************************************************************************************/
function reinsertEstimationRowAtPosition(position)
{
if (deletedEstimationRowData) {
const tableBody = document.querySelector("tbody");
const newRow = document.createElement("tr");
newRow.setAttribute("draggable", "true");
newRow.dataset.rowId = deletedEstimationRowData.id;
newRow.classList.add("estimation-row");
newRow.title = newRow.dataset.rowId;
// Créez les cellules de la nouvelle ligne
const firstCells = [deletedEstimationRowData.name, "", deletedEstimationRowData.estimationValue];
firstCells.forEach((text, index) => {
const td = document.createElement("td");
td.dataset.cellId = `cell-${deletedEstimationRowData.id}-${index}`;
if (index === 0) {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = deletedEstimationRowData.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
});
input.addEventListener("blur", function () {
input.classList.remove("editing");
input.style.width = "65px";
updateRowData(input);
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
updateRowData(input);
}
});
td.appendChild(input);
} else if (index === 1) {
const select = document.createElement("select");
for (let i = 1; i <= 10; i++) {
const option = document.createElement("option");
option.value = i;
option.textContent = `Option ${i}`;
select.appendChild(option);
}
select.value = deletedEstimationRowData.selectValue;
select.addEventListener("change", function () {
updateRowData(select);
});
td.appendChild(select);
} else {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = deletedEstimationRowData.estimationValue;
input.addEventListener("blur", function () {
const value = parseInt(input.value, 10);
if (isNaN(value) || value < 1 || value > 365) {
input.value = "1";
showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
} else {
updateRowData(input);
}
input.classList.remove("editing");
input.style.width = "65px";
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
const value = parseInt(input.value, 10);
if (isNaN(value) || value < 1 || value > 365) {
input.value = "1";
showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
} else {
updateRowData(input);
}
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
}
});
td.appendChild(input);
}
if (index === 0) {
td.classList.add("row-header");
td.addEventListener("click", function (event) {
event.preventDefault();
handleRowClick(newRow, td); // TAG : SELECTION
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, newRow);
});
}
newRow.appendChild(td);
});
// Créez une cellule fusionnée pour les colonnes restantes
const mergedCell = document.createElement("td");
mergedCell.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
mergedCell.textContent = "";
mergedCell.classList.add("no-click");
newRow.appendChild(mergedCell);
// Insérez la nouvelle ligne à la position souhaitée
if (position >= 0 && position <= tableBody.children.length) {
tableBody.insertBefore(newRow, tableBody.children[position]);
} else {
tableBody.appendChild(newRow);
}
// Ajoutez les événements de drag-and-drop à la nouvelle ligne
newRow.addEventListener("dragstart", dragStart);
newRow.addEventListener("dragover", dragOver);
newRow.addEventListener("drop", drop);
// Ajoutez l'objet de la nouvelle ligne dans le tableau estimationRowsData
estimationRowsData.push(deletedEstimationRowData);
// Réinitialisez les données conservées
deletedEstimationRowData = null;
} else {
console.log("Aucune donnée de ligne d'estimation supprimée à réinsérer.");
}
}
// Exemple d'utilisation pour réinsérer la ligne à la position 0
//reinsertEstimationRowAtPosition(0);
/**********************************************************************************************/
function moveEstimationRow(fromPosition, toPosition) {
const tableBody = document.querySelector("tbody");
const rows = tableBody.querySelectorAll("tr");
// Vérifiez si les positions sont valides
/*if (fromPosition < 0 || fromPosition >= rows.length || toPosition < 0 || toPosition >= rows.length) {
console.error("Position invalide");
return;
}*/
// Sélectionnez la ligne à déplacer
const rowToMove = rows[fromPosition];
// Vérifiez si la ligne est une ligne d'estimation
if (rowToMove.dataset.rowId.startsWith("estimation-")) {
// Retirez la ligne de sa position actuelle
tableBody.removeChild(rowToMove);
// Réinsérez la ligne à la nouvelle position
if (toPosition >= rows.length) {
// Si la nouvelle position est à la fin, ajoutez la ligne à la fin
tableBody.appendChild(rowToMove);
} else {
// Sinon, insérez la ligne avant la ligne à la nouvelle position
tableBody.insertBefore(rowToMove, rows[toPosition]);
}
console.log(`Ligne d'estimation déplacée de la position ${fromPosition} à la position ${toPosition}.`);
} else {
console.error("La ligne sélectionnée n'est pas une ligne d'estimation.");
}
}
// Exemple d'utilisation pour déplacer la ligne d'estimation de la position 3 à la position 7
//moveEstimationRow(3, 7);
/**********************************************************************************************/
function getRowPositionById(rowId) {
// Sélectionnez le tbody du tableau
const tableBody = document.querySelector("tbody");
// Sélectionnez la ligne avec l'identifiant donné
const row = tableBody.querySelector(`tr[data-row-id="${rowId}"]`);
// Vérifiez si la ligne existe
if (row) {
// Obtenez toutes les lignes du tbody
const rows = Array.from(tableBody.querySelectorAll("tr"));
// Trouvez l'index de la ligne
const rowIndex = rows.indexOf(row);
// Retournez la position de la ligne
return rowIndex;
} else {
console.log(`Aucune ligne trouvée avec l'identifiant ${rowId}.`);
return -1; // Retournez -1 si la ligne n'est pas trouvée
}
}
// Exemple d'utilisation
//const rowId = "estimation-123"; // Remplacez par l'identifiant de la ligne que vous recherchez
//const position = getRowPositionById(rowId);
//console.log(`La position de la ligne avec l'identifiant ${rowId} est : ${position}`);
/**********************************************************************************************/
function showConfirmationModal(row)
{
const modal = new bootstrap.Modal(document.getElementById('confirmationModal'));
modal.show();
document.getElementById('confirmDelete').addEventListener('click', function ()
{
let linkageIndex = -1;
const rowId = row.dataset.rowId;
const isStandardRow = rowId.startsWith("standard-");
const isEstimationRow = rowId.startsWith("estimation-");
const isSpecialRow = rowId.startsWith("special-");
console.log(" +++++++ " + rowId + " " + isSpecialRow)
if (isStandardRow)
{
linkageIndex = linkages.findIndex(link => link.standardRowId === rowId);
}
else if (isEstimationRow)
{
linkageIndex = linkages.findIndex(link => link.estimationRowId === rowId);
}
else if (isSpecialRow)
{
//linkageIndex = linkages.findIndex(link => link.specialRowId === rowId);
//console.log(" TRACE : " + linkageIndex);
const specialRowIndex = specialRowsData.findIndex(data => data.id === rowId);
console.log(" TRACE : " + specialRowIndex);
///12345
//const tableData = traceTable();
//console.log("Données retournées par traceTable():", JSON.stringify(tableData, null, 2));
if (specialRowIndex !== -1)
{
//console.log(" TRACE : " + linkageIndex);
specialRowsData.splice(specialRowIndex, 1);
}
// Vérifiez si l'identifiant de la ligne spéciale est dans objet_selection
if (objet_selection.includes(rowId))
{
// Purgez objet_selection
objet_selection = objet_selection.filter(id => id !== rowId);
console.log("objet_selection purgé :", objet_selection);
}
row.remove(); // Remove the special row from the DOM
modal.hide();
return;
}
if (linkageIndex !== -1)
{
const linkage = linkages[linkageIndex];
console.log("Liaison trouvée :");
console.log("Index de la liaison :", linkageIndex); // Afficher l'indice de la liaison
console.log("ID de la liaison :", linkage.id);
console.log("ID de la ligne standard :", linkage.standardRowId);
console.log("ID de la ligne d'estimation :", linkage.estimationRowId);
// Vérifiez si les identifiants de la ligne standard et de la ligne d'estimation sont dans objet_selection
if (objet_selection.includes(linkage.standardRowId) && objet_selection.includes(linkage.estimationRowId))
{
// Purgez objet_selection
objet_selection = objet_selection.filter(id => id !== linkage.standardRowId && id !== linkage.estimationRowId);
console.log("objet_selection purgé :", objet_selection);
}
}
let standardRowId = null;
let estimationRowId = null;
let linkageId = null;
if (isStandardRow)
{
standardRowId = rowId;
const linkage = linkages.find(link => link.standardRowId === standardRowId);
if (linkage)
{
estimationRowId = linkage.estimationRowId;
linkageId = linkage.id;
}
}
else if (isEstimationRow)
{
estimationRowId = rowId;
const linkage = linkages.find(link => link.estimationRowId === estimationRowId);
if (linkage)
{
standardRowId = linkage.standardRowId;
linkageId = linkage.id;
}
}
else if (isSpecialRow)
{
// Handle special row deletion if needed
}
if (standardRowId && estimationRowId && linkageId)
{
// Remove the corresponding sub-arrays in tableData
const tableData = traceTable();
const standardIndex = tableData.findIndex(item => item.id === standardRowId);
const estimationIndex = tableData.findIndex(item => item.id === estimationRowId);
const linkageIndex = tableData.findIndex(item => item.id === linkageId);
if (standardIndex !== -1) {
tableData.splice(standardIndex, 1);
}
if (estimationIndex !== -1) {
tableData.splice(estimationIndex, 1);
}
if (linkageIndex !== -1) {
tableData.splice(linkageIndex, 1);
}
// Remove the rows from the DOM
const standardRow = document.querySelector(`tr[data-row-id="${standardRowId}"]`);
const estimationRow = document.querySelector(`tr[data-row-id="${estimationRowId}"]`);
if (standardRow) {
standardRow.remove();
}
if (estimationRow) {
estimationRow.remove();
}
// Update the linkages array
const linkageIndexInLinkages = linkages.findIndex(link => link.id === linkageId);
if (linkageIndexInLinkages !== -1) {
linkages.splice(linkageIndexInLinkages, 1);
}
// Display the updated tableData
//displayJSONData(tableData);
}
modal.hide();
});
document.getElementById('cancelDelete').addEventListener('click', function () {
modal.hide();
});
}
/**********************************************************************************************/
function showMessageModal(message) {
const modal = new bootstrap.Modal(document.getElementById('messageModal'));
const modalBody = document.getElementById('messageModalBody');
modalBody.textContent = message;
modal.show();
}
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") {
hideContextMenu();
hideSpecialContextMenu();
hideColorContextMenu();
}
});
function hideContextMenu() {
contextMenu.style.display = "none";
}
function hideSpecialContextMenu() {
specialContextMenu.style.display = "none";
}
function hideColorContextMenu() {
colorContextMenu.style.display = "none";
}
document.getElementById("addRowButton").addEventListener("click", addRow);
document.getElementById("addSpecialRowButton").addEventListener("click", addSpecialRow);
document.querySelectorAll("tbody tr td:first-child").forEach(td => {
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, td.parentElement);
});
});
/**********************************************************************************************/
function query() {
const tableData = [];
const rows = tableBody.querySelectorAll("tr");
rows.forEach(row => {
const rowData = {};
const cells = row.querySelectorAll("td");
if (row.dataset.rowId.startsWith("special-")) {
const inputCell = cells[0];
const inputValue = inputCell.querySelector("input").value;
rowData.id = row.dataset.rowId;
rowData.name = inputValue;
rowData.selection = inputCell.style.backgroundColor === "blue" ? "ON" : "OFF"; // Ajouter la variable selection
} else if (row.dataset.rowId.startsWith("estimation-")) {
const inputCell = cells[0];
const inputValue = inputCell.querySelector("input").value;
rowData.id = row.dataset.rowId;
rowData.name = inputValue;
rowData.estimationValue = cells[2].querySelector("input").value;
rowData.selectValue = cells[1].querySelector("select").value;
rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION
} else {
rowData.id = row.dataset.rowId;
rowData.name = cells[0].querySelector("input").value;
rowData.selectValue = cells[1].querySelector("select").value;
rowData.count = cells[2].textContent.trim();
rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION
//rowData.cells = [];
cells.forEach((cell, index) => {
if (index > 2) {
if (!rowData.cells) {
rowData.cells = []; // Initialiser rowData.cells comme un tableau vide si ce n'est pas déjà fait
}
rowData.cells.push({
value: cell.dataset.cellValue,
color: cell.dataset.cellColor,
full_date: cell.dataset.fullDate // Ajouter la clé full_date
});
}
});
}
tableData.push(rowData);
});
// Ajouter les objets linkage au tableau de données
linkages.forEach(linkage => {
tableData.push({
id: linkage.id,
standardRowId: linkage.standardRowId,
estimationRowId: linkage.estimationRowId
});
});
//return tableData;
//const tableData = traceTable();
console.log("Données retournées par traceTable():", JSON.stringify(tableData, null, 2));
}
/**********************************************************************************************/
function traceTable() {
const tableData = [];
const rows = tableBody.querySelectorAll("tr");
// Parcourir chaque ligne du tableau et récupérer les données des cellules
rows.forEach(row => {
const rowData = {};
const cells = row.querySelectorAll("td");
if (row.dataset.rowId.startsWith("special-")) {
const inputCell = cells[0];
const inputValue = inputCell.querySelector("input").value;
rowData.id = row.dataset.rowId;
rowData.name = inputValue;
rowData.selection = inputCell.style.backgroundColor === "blue" ? "ON" : "OFF"; // Ajouter la variable selection
} else if (row.dataset.rowId.startsWith("estimation-")) {
const inputCell = cells[0];
const inputValue = inputCell.querySelector("input").value;
rowData.id = row.dataset.rowId;
rowData.name = inputValue;
rowData.estimationValue = cells[2].querySelector("input").value;
rowData.selectValue = cells[1].querySelector("select").value;
rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION
} else {
rowData.id = row.dataset.rowId;
rowData.name = cells[0].querySelector("input").value;
rowData.selectValue = cells[1].querySelector("select").value;
rowData.count = cells[2].textContent.trim();
rowData.cells = [];
rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION
cells.forEach((cell, index) => {
if (index > 2) {
rowData.cells.push({
value: cell.dataset.cellValue,
color: cell.dataset.cellColor,
full_date: cell.dataset.fullDate // Ajouter la clé full_date
});
}
});
}
tableData.push(rowData);
});
// Ajouter les objets linkage au tableau de données
linkages.forEach(linkage => {
tableData.push({
id: linkage.id,
standardRowId: linkage.standardRowId,
estimationRowId: linkage.estimationRowId
});
});
console.log("TRACE");
return tableData;
}
/**********************************************************************************************/
function openRangeSelectionModal(cell) {
const modal = new bootstrap.Modal(document.getElementById('rangeSelectionModal'));
const startCellIdInput = document.getElementById('startCellId');
const endCellIdInput = document.getElementById('endCellId');
const rangeResult = document.getElementById('rangeResult');
const rangeComboBox = document.getElementById('rangeComboBox');
rangeComboBox.innerHTML = "";
for (let i = 1; i <= 50; i++) {
const option = document.createElement("option");
option.value = i;
option.textContent = i;
rangeComboBox.appendChild(option);
}
rangeComboBox.addEventListener("change", function () {
const startCellId = startCellIdInput.value;
const startParts = startCellId.split('-');
const startNumber = parseInt(startParts[2], 10);
const comboValue = parseInt(rangeComboBox.value, 10);
const totalDays = startNumber + comboValue;
const endCellId = `${startParts[0]}-${startParts[1]}-${totalDays}`;
console.log("Valeur sélectionnée :", comboValue);
console.log("Nb jours :", totalDays);
rangeResult.textContent = `Nb jours : ${totalDays}`;
endCellIdInput.value = endCellId;
});
startCellIdInput.value = cell.dataset.cellId;
endCellIdInput.value = "";
rangeResult.textContent = "Nb jours : 0";
modal.show();
document.getElementById('confirmRangeSelection').addEventListener('click', function () {
const startCellId = startCellIdInput.value;
const endCellId = endCellIdInput.value;
const comboValue = rangeComboBox.value;
alert(startCellId + " " + endCellId);
updateCellRange(startCellId, endCellId, comboValue);
modal.hide();
});
document.getElementById('cancelRangeSelection').addEventListener('click', function () {
modal.hide();
});
const modalHeader = modal._dialog.querySelector('.modal-header');
let isDragging = false;
let offsetX, offsetY;
modalHeader.addEventListener('mousedown', function (event) {
isDragging = true;
offsetX = event.clientX - modal._dialog.offsetLeft;
offsetY = event.clientY - modal._dialog.offsetTop;
modal._dialog.style.pointerEvents = 'none';
});
document.addEventListener('mousemove', function (event) {
if (isDragging) {
modal._dialog.style.left = `${event.clientX - offsetX}px`;
modal._dialog.style.top = `${event.clientY - offsetY}px`;
}
});
document.addEventListener('mouseup', function () {
isDragging = false;
modal._dialog.style.pointerEvents = 'all';
});
endCellIdInput.addEventListener('input', function () {
const startParts = startCellIdInput.value.split('-');
const endParts = endCellIdInput.value.split('-');
if (startParts.length === 3 && endParts.length === 3 && startParts[0] === endParts[0] && startParts[1] === endParts[1]) {
const startValue = parseInt(startParts[2], 10);
const endValue = parseInt(endParts[2], 10);
console.log(" ++ " + startValue + " " + endValue);
const result = endValue - startValue;
rangeResult.textContent = `Nb jours : ${result} jours`;
if (result > 0) {
alert(`Nb jours : ${result} jours`);
}
} else {
rangeResult.textContent = "Nb jours : 0";
}
});
}
/**********************************************************************************************/
function updateCellRange(startCellId, endCellId) {
const startCell = document.querySelector(`td[data-cell-id="${startCellId}"]`);
const endCell = document.querySelector(`td[data-cell-id="${endCellId}"]`);
if (startCell && endCell && startCell.parentElement === endCell.parentElement) {
const startIndex = Array.from(startCell.parentElement.cells).indexOf(startCell);
const endIndex = Array.from(endCell.parentElement.cells).indexOf(endCell);
for (let i = startIndex; i <= endIndex; i++) {
const cell = startCell.parentElement.cells[i];
cell.dataset.cellValue = "1";
cell.textContent = "1";
cell.style.backgroundColor = "green";
cell.dataset.cellColor = "green";
updateRowData(cell);
}
updateCountCell(startCell.parentElement);
} else {
showMessageModal("Les cellules doivent être sur la même ligne.");
}
}
/**********************************************************************************************/
tableBody.addEventListener("mouseover", function (event) {
const cell = event.target.closest("td");
if (cell) {
currentCell = cell;
}
});
document.addEventListener("keydown", function (event) {
if (event.key === "p" && currentCell) {
openRangeSelectionModal(currentCell);
}
});
document.getElementById("SauveButton").addEventListener("click", function ()
{
const rows = tableBody.querySelectorAll("tr");
if (rows.length === 0)
{
showMessageModal("Aucune ligne à sauvegarder. Veuillez ajouter des lignes avant de sauvegarder.");
}
else
{
const modal = new bootstrap.Modal(document.getElementById('confirmSaveModal'));
modal.show();
document.getElementById('confirmSave').addEventListener('click', function ()
{
Jsondata();
modal.hide();
});
document.getElementById('cancelSave').addEventListener('click', function ()
{
modal.hide();
});
}
});
/**********************************************************************************************/
function Jsondata() {
const jsonData = [];
const rows = document.querySelectorAll("tbody tr");
rows.forEach(row => {
const rowId = row.dataset.rowId;
const cells = row.querySelectorAll("td");
if (rowId.startsWith("standard-")) {
const standardRow = {
id: rowId,
name: cells[0].querySelector("input").value,
selectValue: cells[1].querySelector("select").value,
count: cells[2].textContent.trim(),
cells: [],
selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
};
cells.forEach((cell, index) => {
if (index > 2) {
standardRow.cells.push({
value: cell.dataset.cellValue,
color: cell.dataset.cellColor,
full_date: cell.dataset.fullDate // Ajouter la clé full_date
});
}
});
jsonData.push(standardRow);
} else if (rowId.startsWith("estimation-")) {
const estimationRow = {
id: rowId,
name: cells[0].querySelector("input").value,
selectValue: cells[1].querySelector("select").value,
estimationValue: cells[2].querySelector("input").value,
selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
};
jsonData.push(estimationRow);
} else if (rowId.startsWith("special-")) {
const specialRow = {
id: rowId,
name: cells[0].querySelector("input").value,
selection: cells[0].style.backgroundColor === "blue" ? "ON" : "OFF" // TAG : SELECTION
};
jsonData.push(specialRow);
}
});
// Ajouter les objets linkage
linkages.forEach(linkage => {
jsonData.push({
id: linkage.id,
standardRowId: linkage.standardRowId,
estimationRowId: linkage.estimationRowId
});
});
console.log(JSON.stringify(jsonData, null, 2));
sendDataToPHP(jsonData);
}
/**********************************************************************************************/
function logRowTypes() {
console.log("TRACE Start");
const rowDataArray = [];
const rows = tableBody.querySelectorAll("tr");
const rowTypes = {
standard: 0,
estimation: 0,
special: 0
};
linkages.forEach((linkage, index) => {
rowDataArray.push(linkage);
});
rows.forEach(row => {
const rowId = row.dataset.rowId;
if (rowId.startsWith("standard-")) {
rowTypes.standard++;
} else if (rowId.startsWith("estimation-")) {
rowTypes.estimation++;
} else if (rowId.startsWith("special-")) {
rowTypes.special++;
}
let rowData = null;
if (rowId.startsWith("standard-")) {
rowData = standardRowsData.find(data => data.id === rowId);
} else if (rowId.startsWith("estimation-")) {
rowData = estimationRowsData.find(data => data.id === rowId);
} else if (rowId.startsWith("special-")) {
rowData = specialRowsData.find(data => data.id === rowId);
}
if (rowData) {
console.log("Identifiant de la ligne :", rowId);
console.log("Détails de l'objet :", rowData);
rowDataArray.push(rowData);
} else {
console.log("Aucune donnée trouvée pour l'identifiant de la ligne :", rowId);
}
});
linkages.forEach((linkage, index) => {
console.log(`Liaison ${index + 1} :`, linkage);
});
console.log("Nombre de lignes standard :", rowTypes.standard);
console.log("Nombre de lignes d'estimation :", rowTypes.estimation);
console.log("Nombre de lignes spéciales :", rowTypes.special);
sendDataToPHP(rowDataArray);
console.log("TRACE end");
}
/**********************************************************************************************/
function sendDataToPHP(rowDataArray) {
// Afficher les données dans la console
console.log("Données envoyées à PHP :", rowDataArray);
// Envoyer les données au script PHP
fetch('script_export02.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(rowDataArray)
})
.then(response => response.json())
.then(data => {
// Gérer les différents types de messages renvoyés
if (data.status === 'success') {
console.log('Succès :', data.message);
showMessageModal(data.message);
} else if (data.status === 'error') {
console.error('Erreur :', data.message);
showMessageModal(data.message);
} else {
console.error('Réponse inattendue :', data);
showMessageModal('Réponse inattendue du serveur.');
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
});
}
document.getElementById("ChargeButton").addEventListener("click", fetchJsonData);
/**********************************************************************************************/
function fetchJsonData() {
// Envoyer une requête GET au script PHP
fetch('script_import_02.php')
.then(response => response.json())
.then(data => {
// Gérer les différents types de messages renvoyés
if (data.status === 'success') {
//console.log("<--------------- Début file.json --------------------->");
console.log('Données JSON récupérées :', data.data);
// Parcourir chaque élément (sous-tableau JSON) de data
data.data.forEach((item, index) => {
//console.log("<------------------------------------>");
//console.log(`Élément ${index + 1} :`);
if (item.id.includes('standard')) {
//console.log('Détails de la ligne standard :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
if (key === 'cells' && Array.isArray(item[key])) {
//console.log(` ${key}:`);
/* pas utile de voir le détail de chaque cellule
item[key].forEach((cell, cellIndex) => {
console.log(` Cell ${cellIndex + 1}:`);
for (const cellKey in cell) {
if (cell.hasOwnProperty(cellKey)) {
console.log(` ${cellKey}: ${cell[cellKey]}`);
}
}
});*/
}
else
{
// console.log(` ${key}: ${item[key]}`);
}
}
}
}
else if (item.id.includes('estimation'))
{
//console.log('Détails de la ligne d\'estimation :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
//console.log(` ${key}: ${item[key]}`);
}
}
}
else if (item.id.includes('special'))
{
//console.log('Détails de la ligne spéciale :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
//console.log(` ${key}: ${item[key]}`);
}
}
}
else if (item.id.includes('linkage'))
{
//console.log('Détails de la liaison :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
//console.log(` ${key}: ${item[key]}`);
}
}
}
else
{
//console.log('Type de ligne inconnu :', item.id);
}
// Afficher les détails de chaque sous-tableau JSON
/*if (item.standardRow) {
console.log('Détails de la ligne standard :', item.standardRow);
}
if (item.estimationRow) {
console.log('Détails de la ligne d\'estimation :', item.estimationRow);
}
if (item.specialRow) {
console.log('Détails de la ligne spéciale :', item.specialRow);
}*/
});
//console.log("<--------------- FIN file.json --------------------->");
//preparation(data.data);
regeneration(data.data);
}
else if (data.status === 'error')
{
console.error('Erreur :', data.message);
showMessageModal(data.message);
}
else
{
console.error('Réponse inattendue :', data);
showMessageModal('Réponse inattendue du serveur.');
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de la récupération des données.');
});
}
/**********************************************************************************************/
function showMessageModal(message)
{
const modal = new bootstrap.Modal(document.getElementById('messageModal'));
const modalBody = document.getElementById('messageModalBody');
modalBody.textContent = message;
modal.show();
}
/**********************************************************************************************/
/*
function preparation(data)
{
regeneration(data);
//display_import(data);
}
*/
/**********************************************************************************************/
function display_import(data)
{
// Parcourir chaque élément (sous-tableau JSON) de data
data.forEach((item, index) => {
console.log(`Élément ${index + 1} :`);
// Vérifier si l'id contient 'standard', 'estimation' ou 'special'
if (item.id.includes('standard')) {
console.log('Import : détails de la ligne standard :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
if (key === 'cells' && Array.isArray(item[key])) {
console.log(` ${key}:`);
// pas utile de voir le détail de chaque cellule
/*item[key].forEach((cell, cellIndex) => {
console.log(` Cell ${cellIndex + 1}:`);
for (const cellKey in cell) {
if (cell.hasOwnProperty(cellKey)) {
console.log(` ${cellKey}: ${cell[cellKey]}`);
}
}
});*/
} else {
console.log(` ${key}: ${item[key]}`);
}
}
}
} else if (item.id.includes('estimation')) {
console.log('Import : Détails de la ligne d\'estimation :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
console.log(` ${key}: ${item[key]}`);
}
}
} else if (item.id.includes('special')) {
console.log('Import : Détails de la ligne spéciale :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
console.log(` ${key}: ${item[key]}`);
}
}
}
else if (item.id.includes('linkage')) {
console.log('Détails de la liaison :');
for (const key in item) {
if (item.hasOwnProperty(key)) {
console.log(` ${key}: ${item[key]}`);
}
}
}
else {
console.log('Type de ligne inconnu :', item.id);
}
});
}
/**********************************************************************************************/
function code_annexe(data)
{
/*
console.log(" ********** Début recherche ******************** ");
// Afficher le contenu détaillé des objets
//console.log("Contenu de standardRowsData :");
standardRowsData.forEach((row, index) => {
console.log(`Ligne standard ${index + 1} :`, row);
});
//console.log("Contenu de estimationRowsData :");
estimationRowsData.forEach((row, index) => {
console.log(`Ligne d'estimation ${index + 1} :`, row);
});
//console.log("Contenu de specialRowsData :");
specialRowsData.forEach((row, index) => {
console.log(`Ligne spéciale ${index + 1} :`, row);
});
//console.log("Contenu de linkages :");
linkages.forEach((linkage, index) => {
console.log(`Liaison ${index + 1} :`, linkage);
});
console.log(" ********** Fin recherche ******************** ");
console.log(" ********** Début vérification purge ******************** ");
standardRowsData.length = 0;
estimationRowsData.length = 0;
specialRowsData.length = 0;
linkages.length = 0;
if (standardRowsData.length === 0) {
console.log(" standardRowsData empty");
}
if (estimationRowsData.length === 0) {
console.log(" estimationRowsData empty");
}
if (specialRowsData.length === 0) {
console.log(" specialRowsData empty");
}
if (linkages.length === 0) {
console.log(" linkages empty");
}
console.log(" ********** Fin vérification purge ******************** ");
*/
// Afficher le nombre de sous-tableaux dans data
//console.log("Nombre de sous-tableaux dans data :", data.length);
/*for (const item of data)
{
if (item.id.includes('special'))
{
const specialRowData = {
id: item.id,
name: item.name
};
specialRowsData.push(specialRowData);
}
}*/
/*for (let i = 0; i < data.length; i++)
{
console.log(" Indice " + i);
}*/
}
/**********************************************************************************************/
function regeneration(data) {
console.log("Purging table and regenerating rows...");
// Clear existing table data
tableBody.innerHTML = "";
standardRowsData.length = 0;
estimationRowsData.length = 0;
specialRowsData.length = 0;
linkages.length = 0;
objet_selection = []; // Réinitialiser l'objet objet_selection
data.forEach(item => {
if (item.id.includes('linkage')) {
console.log("Creating a linkage...");
const linkage = {
id: item.id,
standardRowId: item.standardRowId,
estimationRowId: item.estimationRowId,
};
linkages.push(linkage);
}
if (item.id.includes('standard')) {
console.log("Creating a standard row...");
const standardRowData = {
id: item.id,
name: item.name,
selectValue: item.selectValue,
count: item.count,
cells: item.cells,
selection: item.selection // TAG : SELECTION
};
standardRowsData.push(standardRowData);
const standardRow = document.createElement("tr");
standardRow.setAttribute("draggable", "true");
standardRow.dataset.rowId = item.id;
standardRow.title = standardRow.dataset.rowId; // Ajoutez cette ligne
const firstCells = [item.name, "", item.count];
firstCells.forEach((text, index) => {
const td = document.createElement("td");
td.dataset.cellId = `cell-${item.id}-${index}`;
if (index === 0) {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = item.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
console.log("Input clicked, setting width to 130px");
});
input.addEventListener("blur", function () {
if (!keydownHandled && !alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
keydownHandled = false;
alertShown = false;
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
keydownHandled = true;
if (!alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
}
});
td.appendChild(input);
} else if (index === 1) {
const select = document.createElement("select");
for (let i = 1; i <= 10; i++) {
const option = document.createElement("option");
option.value = i;
option.textContent = `Option ${i}`;
select.appendChild(option);
}
select.value = item.selectValue;
select.addEventListener("change", function () {
updateRowData(select);
});
td.appendChild(select);
} else {
td.textContent = text;
}
if (index === 0) {
td.classList.add("row-header");
td.addEventListener("click", function (event) {
event.preventDefault();
handleRowClick(standardRow, td); // TAG : SELECTION
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, standardRow);
});
}
standardRow.appendChild(td);
});
const headerCells = document.querySelectorAll("thead tr:nth-child(2) th:not(.weekend):not(.holiday)");
const workingDaysCount = headerCells.length;
for (let i = 0; i < workingDaysCount - 3; i++) {
const td = document.createElement("td");
td.dataset.cellId = `cell-${item.id}-${i}`;
td.dataset.cellValue = item.cells[i].value;
td.dataset.cellColor = item.cells[i].color;
td.dataset.fullDate = item.cells[i].full_date; // Ajouter la clé full_date
td.textContent = item.cells[i].value;
td.style.backgroundColor = item.cells[i].color;
td.addEventListener("click", function () {
const newValue = td.dataset.cellValue === "0" ? "1" : "0";
td.dataset.cellValue = newValue;
td.textContent = newValue;
td.style.backgroundColor = newValue === "1" ? "green" : "white";
td.dataset.cellColor = newValue === "1" ? "green" : "white";
updateCountCell(standardRow);
updateRowData(td);
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
if (td.dataset.cellValue === "1") {
showColorContextMenu(event, td);
}
});
// Ajouter l'écouteur d'événement pour afficher la date complète
td.addEventListener("click", function (event) {
const fullDate = event.target.dataset.fullDate;
console.log("Date complète :", fullDate);
//alert(fullDate);
// Maintenant utiliser fullDate pour d'autres opérations
});
td.title = `ID: ${td.dataset.cellId}`;
standardRow.appendChild(td);
}
if (item.selection === "ON") {
standardRow.cells[0].style.backgroundColor = "red";
}
tableBody.appendChild(standardRow);
standardRow.addEventListener("dragstart", dragStart);
standardRow.addEventListener("dragover", dragOver);
standardRow.addEventListener("drop", drop);
}
if (item.id.includes('estimation')) {
console.log("Creating an estimation row...");
const estimationRowData = {
id: item.id,
name: item.name,
selectValue: item.selectValue,
estimationValue: item.estimationValue,
selection: item.selection // TAG : SELECTION
};
estimationRowsData.push(estimationRowData);
const estimationRow = document.createElement("tr");
estimationRow.setAttribute("draggable", "true");
estimationRow.dataset.rowId = item.id;
estimationRow.classList.add("estimation-row");
estimationRow.title = estimationRow.dataset.rowId; // Ajoutez cette ligne
const estimationFirstCells = [item.name, "", item.estimationValue];
estimationFirstCells.forEach((text, index) => {
const td = document.createElement("td");
td.dataset.cellId = `cell-${item.id}-${index}`;
if (index === 0) {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = item.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
console.log("Input clicked, setting width to 130px");
});
input.addEventListener("blur", function () {
if (!keydownHandled && !alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
keydownHandled = false;
alertShown = false;
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
keydownHandled = true;
if (!alertShown) {
alertShown = true;
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
console.clear;
updateRowData(input);
}
}
});
td.appendChild(input);
} else if (index === 1) {
const select = document.createElement("select");
for (let i = 1; i <= 10; i++) {
const option = document.createElement("option");
option.value = i;
option.textContent = `Option ${i}`;
select.appendChild(option);
}
select.value = item.selectValue;
select.addEventListener("change", function () {
updateRowData(select);
});
td.appendChild(select);
} else {
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = text;
input.addEventListener("blur", function () {
const value = parseInt(input.value, 10);
if (isNaN(value) || value < 1 || value > 365) {
input.value = "1";
showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
} else {
updateRowData(input);
}
input.classList.remove("editing");
input.style.width = "65px";
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
const value = parseInt(input.value, 10);
if (isNaN(value) || value < 1 || value > 365) {
input.value = "1";
showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
} else {
updateRowData(input);
}
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
}
});
td.appendChild(input);
}
if (index === 0) {
td.classList.add("row-header");
td.addEventListener("click", function (event) {
event.preventDefault();
handleRowClick(estimationRow, td); // TAG : SELECTION
});
td.addEventListener("contextmenu", function (event) {
event.preventDefault();
showContextMenu(event, estimationRow);
});
}
estimationRow.appendChild(td);
});
const mergedCell = document.createElement("td");
mergedCell.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
mergedCell.textContent = "";
mergedCell.classList.add("no-click");
estimationRow.appendChild(mergedCell);
if (item.selection === "ON") {
estimationRow.cells[0].style.backgroundColor = "red";
}
tableBody.appendChild(estimationRow);
estimationRow.addEventListener("dragstart", dragStart);
estimationRow.addEventListener("dragover", dragOver);
estimationRow.addEventListener("drop", drop);
}
if (item.id.includes('special')) {
console.log("Creating a special row...");
const specialRowData = {
id: item.id,
name: item.name,
selection: item.selection // TAG : SELECTION
};
specialRowsData.push(specialRowData);
const specialRow = document.createElement("tr");
specialRow.classList.add("special-row");
specialRow.setAttribute("draggable", "true");
specialRow.dataset.rowId = item.id;
specialRow.title = specialRow.dataset.rowId; // Ajoutez cette ligne
const firstCell = document.createElement("td");
firstCell.classList.add("row-header");
const input = document.createElement("input");
input.type = "text";
input.classList.add("editable-input");
input.value = item.name;
input.addEventListener("click", function (event) {
event.stopPropagation();
input.focus();
input.style.width = "130px";
console.log("Input clicked, setting width to 130px");
});
input.addEventListener("blur", function () {
input.classList.remove("editing");
input.style.width = "65px";
updateRowData(input);
});
input.addEventListener("keydown", function (event) {
if (event.key === "Escape" || event.key === "Enter") {
input.classList.remove("editing");
input.blur();
input.style.width = "65px";
updateRowData(input);
}
});
input.addEventListener("input", function () {
updateRowData(input);
});
const addButton = document.createElement("button");
addButton.classList.add("add-button");
addButton.textContent = "+";
addButton.addEventListener("click", function () {
toggleCollapse(specialRow);
});
firstCell.appendChild(input);
firstCell.appendChild(addButton);
firstCell.addEventListener("contextmenu", function (event) {
event.preventDefault();
showSpecialContextMenu(event, specialRow);
});
// Ajouter un gestionnaire de clic pour changer la couleur de fond
firstCell.addEventListener("click", function () {
handleSpecialRowClick(specialRow, firstCell);
});
if (item.selection === "ON") {
firstCell.style.backgroundColor = "blue";
}
specialRow.appendChild(firstCell);
const mergedCell = document.createElement("td");
mergedCell.colSpan = 2;
mergedCell.textContent = "";
specialRow.appendChild(mergedCell);
const td = document.createElement("td");
td.textContent = `${item.name} - Détails`;
td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
specialRow.appendChild(td);
tableBody.appendChild(specialRow);
specialRow.addEventListener("dragstart", dragStart);
specialRow.addEventListener("dragover", dragOver);
specialRow.addEventListener("drop", drop);
}
});
// Recréer l'objet objet_selection
linkages.forEach(linkage => {
const standardRowData = standardRowsData.find(data => data.id === linkage.standardRowId);
const estimationRowData = estimationRowsData.find(data => data.id === linkage.estimationRowId);
if (standardRowData && estimationRowData && standardRowData.selection === "ON" && estimationRowData.selection === "ON") {
objet_selection.push(standardRowData.id, estimationRowData.id);
}
});
// Afficher les liaisons dans la console
//displayLinkages();
}
/*document.getElementById("logButton").addEventListener("click", function ()
{
//const tableData = traceTable();
//displayJSONData(tableData);
});*/
/*function displayJSONData(data)
{
const jsonOutputElement = document.getElementById("jsonOutput");
const jsonOutput = JSON.stringify(data, null, 2);
jsonOutputElement.textContent = jsonOutput;
}*/
document.getElementById("queryButton").addEventListener("click", function () {
query();
});
/*
document.getElementById("writeButton").addEventListener("click", function ()
{
// Afficher la fenêtre de dialogue modale pour saisir le nom du fichier
const modal = new bootstrap.Modal(document.getElementById('fileNameModal'));
modal.show();
// Remplir la combo box avec les noms des fichiers JSON
fetch('script_get_files.php')
.then(response => response.json())
.then(data => {
const fileList = document.getElementById('fileList');
fileList.innerHTML = '';
data.files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file;
fileList.appendChild(option);
});
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de la récupération des noms de fichiers.');
});
document.getElementById('saveFileName').addEventListener('click', function ()
{
const fileName = document.getElementById('fileName').value;
if (fileName)
{
// Fermer la première fenêtre modale
$('#fileNameModal').modal('hide');
// Vérifier si le fichier existe déjà dans la liste
const fileList = document.getElementById('fileList');
const fileExists = Array.from(fileList.options).some(option => option.value === fileName);
if (fileExists)
{
// Afficher une fenêtre modale de confirmation
const confirmationModal = new bootstrap.Modal(document.getElementById('confirmOverwriteModal'));
confirmationModal.show();
// Gérer le clic sur le bouton "OK" de la fenêtre modale de confirmation
document.getElementById('confirmOverwrite').addEventListener('click', function ()
{
// Récupérer les données du tableau HTML
const tableData = traceTable();
// Envoyer les données à un script PHP pour sauvegarder au format JSON
fetch('script_save.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ fileName: fileName, data: tableData })
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showMessageModal("Fichier sauvegardé avec succès !");
} else {
showMessageModal("Erreur lors de la sauvegarde du fichier.");
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
});
// Fermer la fenêtre modale de confirmation
confirmationModal.hide();
});
// Gérer le clic sur le bouton "Annuler" de la fenêtre modale de confirmation
document.getElementById('cancelOverwrite').addEventListener('click', function ()
{
// Fermer la fenêtre modale de confirmation
confirmationModal.hide();
});
}
else
{
// Récupérer les données du tableau HTML
const tableData = traceTable();
// Envoyer les données à un script PHP pour sauvegarder au format JSON
fetch('script_save.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ fileName: fileName, data: tableData })
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showMessageModal("Fichier sauvegardé avec succès !");
} else {
showMessageModal("Erreur lors de la sauvegarde du fichier.");
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
});
}
}
else
{
showMessageModal("Veuillez entrer un nom de fichier.");
}
});
// Mettre à jour l'input text avec la valeur sélectionnée dans la combo box
document.getElementById('fileList').addEventListener('change', function ()
{
document.getElementById('fileName').value = this.value;
});
modal.hide(); // Fermer la fenêtre modale
});*/
document.getElementById("writeButton").addEventListener("click", function () {
const rows = tableBody.querySelectorAll("tr");
if (rows.length === 0)
{
showMessageModal("Aucune ligne à sauvegarder. Veuillez ajouter des lignes avant de sauvegarder.");
return;
}
// Afficher la fenêtre de dialogue modale pour saisir le nom du fichier
const modal = new bootstrap.Modal(document.getElementById('fileNameModal'));
modal.show();
// Remplir la combo box avec les noms des fichiers JSON
fetch('script_get_files.php')
.then(response => response.json())
.then(data => {
const fileList = document.getElementById('fileList');
fileList.innerHTML = '';
data.files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file;
fileList.appendChild(option);
});
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de la récupération des noms de fichiers.');
});
document.getElementById('saveFileName').addEventListener('click', function () {
const fileName = document.getElementById('fileName').value;
if (fileName) {
// Vérifier si le fichier existe déjà dans la liste
const fileList = document.getElementById('fileList');
const fileExists = Array.from(fileList.options).some(option => option.value === fileName);
if (fileExists) {
// Afficher le message d'avertissement
document.getElementById('fileExistsMessage').style.display = 'block';
// Afficher le bouton de confirmation d'écrasement
document.getElementById('confirmOverwrite').style.display = 'inline-block';
// Masquer le bouton Enregistrer
document.getElementById('saveFileName').style.display = 'none';
} else {
// Récupérer les données du tableau HTML
const tableData = traceTable();
// Envoyer les données à un script PHP pour sauvegarder au format JSON
fetch('script_save.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ fileName: fileName, data: tableData })
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showMessageModal("Fichier sauvegardé avec succès !");
} else {
showMessageModal("Erreur lors de la sauvegarde du fichier.");
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
});
}
} else {
showMessageModal("Veuillez entrer un nom de fichier.");
}
/// 555
console.log("Bouton Enregistrer cliqué"); // Ajout du message dans la console
});
// Gérer le clic sur le bouton "Confirmer l'écrasement"
document.getElementById('confirmOverwrite').addEventListener('click', function () {
const fileName = document.getElementById('fileName').value;
// Récupérer les données du tableau HTML
const tableData = traceTable();
// Envoyer les données à un script PHP pour sauvegarder au format JSON
fetch('script_save.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ fileName: fileName, data: tableData })
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showMessageModal("Fichier sauvegardé avec succès !");
} else {
showMessageModal("Erreur lors de la sauvegarde du fichier.");
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
});
// Fermer la fenêtre modale
$('#fileNameModal').modal('hide');
});
// Mettre à jour l'input text avec la valeur sélectionnée dans la combo box
document.getElementById('fileList').addEventListener('change', function () {
document.getElementById('fileName').value = this.value;
});
});
document.getElementById("readButton").addEventListener("click", function ()
{
// Afficher la fenêtre de dialogue modale pour saisir le nom du fichier à lire
const modal = new bootstrap.Modal(document.getElementById('readFileNameModal'));
modal.show();
// Remplir la combo box avec les noms des fichiers JSON
fetch('script_get_files.php')
.then(response => response.json())
.then(data => {
console.log('Fichiers récupérés pour read:', data.files); // Ajoutez ce log
const fileList_read = document.getElementById('fileList_read');
fileList_read.innerHTML = '';
data.files.forEach(file => {
// 555
console.log("--->>> " + file);
const option = document.createElement('option');
option.value = file;
option.textContent = file;
fileList_read.appendChild(option);
});
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de la récupération des noms de fichiers.');
});
// Gérer le clic sur le bouton "Lire" de la fenêtre de dialogue modale
document.getElementById('readFile').addEventListener('click', function ()
{
const fileName = document.getElementById('readFileName').value;
if (fileName)
{
// Vérifier que le fichier existe et lire son contenu
fetch('script_read.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ fileName: fileName })
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
// Transmettre les données au code principal pour recréer les objets et mettre à jour le tableau HTML
regeneration(data.data);
showMessageModal("Fichier lu avec succès !");
} else {
showMessageModal("Erreur lors de la lecture du fichier.");
}
})
.catch(error => {
console.error('Erreur :', error);
showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
});
// Fermer la fenêtre de dialogue modale
modal.hide();
}
else
{
showMessageModal("Veuillez entrer un nom de fichier.");
}
});
// Mettre à jour l'input text avec la valeur sélectionnée dans la combo box
document.getElementById('fileList_read').addEventListener('change', function ()
{
document.getElementById('readFileName').value = this.value;
});
});
document.getElementById("GraphiqueButton").addEventListener("click", function ()
{
console.log("Envoie ...");
const tableData = traceTable();
console.log("Données envoyées à graphique.php :", tableData);
// Filtrer les lignes pour supprimer les lignes spéciales
//tableData = tableData.filter(row => !row.id.includes('special'));
// Filtrer les lignes pour supprimer celles dont l'id contient "special"
//const filteredTableData = tableData.filter(row => !row.id.includes('special'));
const filteredTableData = tableData.filter(row => !row.id.includes('special') && !row.id.startsWith('linkage'));
// Convertir les données en chaîne JSON
const jsonData = JSON.stringify(filteredTableData);
console.log("Stop ...");
filteredTableData.forEach(row => {
if (row.id) {
console.log("ID de la ligne :", row.id);
}
});
// Créer un formulaire temporaire pour envoyer les données via POST
const form = document.createElement('form');
form.method = 'post';
form.action = 'graphique0021.php';
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'data';
input.value = jsonData;
form.appendChild(input);
document.body.appendChild(form);
form.submit();
});
// Récupérer la valeur renvoyée
/*
const returnValue = sessionStorage.getItem('returnValue');
if (returnValue === "rechargement") {
console.log('Valeur renvoyée :', returnValue);
// Faites quelque chose avec la valeur renvoyée
fetchJsonData();
console.log("Fin");
}
*/
document.getElementById("EnregistrerButton").addEventListener("click", function ()
{
const modal = new bootstrap.Modal(document.getElementById('singlefileNameModal'));
modal.show();
});
document.getElementById("saveFileName").addEventListener("click", function () {
const fileName = document.getElementById('fileName').value;
if (fileName) {
// Récupérer les données du tableau
const tableData = traceTable();
// Convertir les données en chaîne JSON
const jsonData = JSON.stringify(tableData, null, 2);
// Créer un Blob avec les données JSON
const blob = new Blob([jsonData], { type: 'application/json' });
// Créer un lien de téléchargement pour le fichier
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName.endsWith('.json') ? fileName : `${fileName}.json`;
document.body.appendChild(a);
a.click();
// Nettoyer et supprimer le lien
document.body.removeChild(a);
URL.revokeObjectURL(url);
// Afficher un message de succès
showMessageModal("Fichier sauvegardé avec succès !");
} else {
showMessageModal("Veuillez entrer un nom de fichier.");
}
});
document.getElementById("LectureButton").addEventListener("click", function ()
{
// Ouvrir la fenêtre de l'explorateur de fichiers
const fileInput = document.getElementById('fileInput');
fileInput.click();
});
document.getElementById("fileInput").addEventListener("change", function (event)
{
const file = event.target.files[0];
if (file)
{
const reader = new FileReader();
reader.onload = function (e) {
const content = e.target.result;
const data = JSON.parse(content);
// Mettre à jour le tableau HTML avec les données du fichier JSON
regeneration(data);
};
reader.readAsText(file);
}
else
{
showMessageModal("Veuillez sélectionner un fichier.");
}
});
/**** FIN */
});
/**** FIN */
</script>
</body>
</html>