]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Ajout d'un example de select de chatgpt
authorJean-Marc Pigeon <jmp@safe.c>
Wed, 10 Dec 2025 12:19:03 +0000 (07:19 -0500)
committerJean-Marc Pigeon <jmp@safe.c>
Wed, 10 Dec 2025 12:19:03 +0000 (07:19 -0500)
www/chat.php [new file with mode: 0644]
www/chat1.php [new file with mode: 0644]
www/chat2.php [new file with mode: 0644]
www/lvlmai.php

diff --git a/www/chat.php b/www/chat.php
new file mode 100644 (file)
index 0000000..fe1708f
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+$fields = ["Nom", "Email", "Âge"];
+$data = [
+    ["Alice", "alice@example.com", 25],
+    ["Bob", "bob@example.com", 30],
+    ["Charlie", "charlie@example.com", 22],
+];
+?>
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+<meta charset="UTF-8">
+<title>Tableau filtrable "super débile écoeurant"</title>
+<style>
+table { border-collapse: collapse; width: 60%; margin-top: 10px; }
+th, td { border: 1px solid #000; padding: 6px 12px; text-align: left; cursor: pointer; transition: background-color 0.3s; }
+th.selected { background-color: #ffd700; color: #000; }
+td span.highlight { background-color: #ff4; font-weight: bold; }
+input { width: 60%; padding: 6px; font-size: 16px; }
+</style>
+</head>
+<body>
+
+<h2>Recherche filtrable “Super, débile, écoeurante” 😎</h2>
+
+<input type="text" id="searchInput" placeholder="Tapez pour filtrer...">
+
+<table id="myTable">
+    <thead>
+        <tr>
+            <?php foreach($fields as $field): ?>
+                <th><?= htmlspecialchars($field) ?></th>
+            <?php endforeach; ?>
+        </tr>
+    </thead>
+    <tbody>
+        <?php foreach($data as $row): ?>
+            <tr>
+                <?php foreach($row as $cell): ?>
+                    <td><?= htmlspecialchars($cell) ?></td>
+                <?php endforeach; ?>
+            </tr>
+        <?php endforeach; ?>
+    </tbody>
+</table>
+
+<script>
+// --- Setup ---
+const input = document.getElementById('searchInput');
+const table = document.getElementById('myTable');
+const rows = table.tBodies[0].rows;
+const headers = table.tHead.rows[0].cells;
+let activeCols = new Set([0]); // colonne(s) active(s) par défaut
+
+// --- Gestion du clic sur les en-têtes ---
+for (let i = 0; i < headers.length; i++) {
+    headers[i].addEventListener('click', () => {
+        if (activeCols.has(i)) {
+            activeCols.delete(i);
+            headers[i].classList.remove('selected');
+        } else {
+            activeCols.add(i);
+            headers[i].classList.add('selected');
+        }
+        filterTable();
+    });
+}
+
+// --- Fonction de filtrage et highlight ---
+input.addEventListener('input', filterTable);
+
+function filterTable() {
+    const query = input.value.toLowerCase();
+
+    for (let row of rows) {
+        let match = false;
+        for (let i = 0; i < row.cells.length; i++) {
+            const cell = row.cells[i];
+            const text = cell.textContent;
+            
+            if (activeCols.has(i) && text.toLowerCase().includes(query) && query !== "") {
+                // highlight
+                const regex = new RegExp(`(${escapeRegExp(query)})`, 'gi');
+                cell.innerHTML = text.replace(regex, '<span class="highlight">$1</span>');
+                match = true;
+            } else {
+                // reset
+                cell.textContent = text;
+            }
+        }
+        row.style.display = match || query === "" ? '' : 'none';
+    }
+}
+
+// --- Fonction helper pour regex ---
+function escapeRegExp(string) {
+    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
+// --- Initialisation visuelle ---
+for (let i of activeCols) headers[i].classList.add('selected');
+</script>
+
+</body>
+</html>
+
diff --git a/www/chat1.php b/www/chat1.php
new file mode 100644 (file)
index 0000000..1c88c09
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+$fields = ["Nom", "Email", "Âge"];
+$data = [
+    ["Alice", "alice@example.com", 25],
+    ["Bob", "bob@example.com", 30],
+    ["Charlie", "charlie@example.com", 22],
+];
+?>
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+<meta charset="UTF-8">
+<title>Tableau Filtrable Ultime 😎</title>
+<style>
+body { font-family: sans-serif; }
+table { border-collapse: collapse; width: 60%; margin-top: 10px; }
+th, td { border: 1px solid #000; padding: 6px 12px; text-align: left; cursor: pointer; transition: background-color 0.3s, transform 0.2s; }
+th.selected { background-color: #ff9800; color: #fff; }
+td span.highlight { font-weight: bold; transition: background-color 0.3s; }
+input { width: 60%; padding: 6px; font-size: 16px; margin-bottom: 10px; }
+
+/* Confetti effect */
+.confetti { position: absolute; width: 6px; height: 6px; background-color: red; animation: confetti-fall 1s linear forwards; z-index: 1000; border-radius: 50%; }
+@keyframes confetti-fall { 0% { transform: translateY(0) rotate(0deg); opacity: 1; } 100% { transform: translateY(100px) rotate(360deg); opacity: 0; } }
+</style>
+</head>
+<body>
+
+<h2>Recherche “Ultime, Écoeurante, Joyeuse” 😎</h2>
+<input type="text" id="searchInput" placeholder="Tapez pour filtrer...">
+
+<table id="myTable">
+    <thead>
+        <tr>
+            <?php foreach($fields as $field): ?>
+                <th><?= htmlspecialchars($field) ?></th>
+            <?php endforeach; ?>
+        </tr>
+    </thead>
+    <tbody>
+        <?php foreach($data as $row): ?>
+            <tr>
+                <?php foreach($row as $cell): ?>
+                    <td><?= htmlspecialchars($cell) ?></td>
+                <?php endforeach; ?>
+            </tr>
+        <?php endforeach; ?>
+    </tbody>
+</table>
+
+<script>
+const input = document.getElementById('searchInput');
+const table = document.getElementById('myTable');
+const rows = table.tBodies[0].rows;
+const headers = table.tHead.rows[0].cells;
+
+// Colonne active par défaut
+let activeCols = new Set([0]);
+
+// Palette dynamique pour highlight par colonne
+const colors = ["#ffeb3b","#8bc34a","#03a9f4","#e91e63","#9c27b0"];
+
+// --- clic sur en-tête pour sélectionner/désélectionner colonnes ---
+for (let i = 0; i < headers.length; i++) {
+    headers[i].addEventListener('click', () => {
+        if (activeCols.has(i)) {
+            activeCols.delete(i);
+            headers[i].classList.remove('selected');
+        } else {
+            activeCols.add(i);
+            headers[i].classList.add('selected');
+        }
+        filterTable();
+    });
+}
+
+// --- filtrage et highlight ---
+input.addEventListener('input', filterTable);
+
+function filterTable() {
+    const query = input.value.toLowerCase();
+
+    for (let row of rows) {
+        let match = false;
+        for (let i = 0; i < row.cells.length; i++) {
+            const cell = row.cells[i];
+            const text = cell.textContent;
+
+            if (activeCols.has(i) && text.toLowerCase().includes(query) && query !== "") {
+                const regex = new RegExp(`(${escapeRegExp(query)})`, 'gi');
+                cell.innerHTML = text.replace(regex, `<span class="highlight" style="background-color:${colors[i % colors.length]}">$1</span>`);
+                match = true;
+            } else {
+                cell.textContent = text;
+            }
+        }
+        row.style.display = match || query === "" ? '' : 'none';
+        if (match && query !== "") {
+            triggerConfetti(row);
+            row.style.transform = "scale(1.02)";
+            setTimeout(()=>row.style.transform="scale(1)",200);
+        }
+    }
+}
+
+// --- helper regex ---
+function escapeRegExp(string) {
+    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
+// --- confetti ---
+function triggerConfetti(row) {
+    for (let i=0;i<5;i++){
+        const conf = document.createElement('div');
+        conf.className = 'confetti';
+        conf.style.left = (row.getBoundingClientRect().left + Math.random()*row.offsetWidth) + 'px';
+        conf.style.top = (row.getBoundingClientRect().top + window.scrollY) + 'px';
+        conf.style.backgroundColor = colors[Math.floor(Math.random()*colors.length)];
+        document.body.appendChild(conf);
+        setTimeout(()=>conf.remove(),1000);
+    }
+}
+
+// --- initialisation ---
+for (let i of activeCols) headers[i].classList.add('selected');
+</script>
+
+</body>
+</html>
+
diff --git a/www/chat2.php b/www/chat2.php
new file mode 100644 (file)
index 0000000..796ba8a
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+// ----------------------
+// Fichier PHP principal
+// ----------------------
+
+// Données du tableau
+$fields = ["Nom", "Email", "Âge"];
+$data = [
+    ["Alice", "alice@example.com", 25],
+    ["Bob", "bob@example.com", 30],
+    ["Charlie", "charlie@example.com", 22],
+];
+
+// Génération du HTML des en-têtes
+function generateTableHeader(array $fields): string {
+    $html = '';
+    foreach ($fields as $field) {
+        $html .= "<th>" . htmlspecialchars($field) . "</th>";
+    }
+    return $html;
+}
+
+// Génération du HTML du corps
+function generateTableBody(array $data): string {
+    $html = '';
+    foreach ($data as $row) {
+        $html .= "<tr>";
+        foreach ($row as $cell) {
+            $html .= "<td>" . htmlspecialchars($cell) . "</td>";
+        }
+        $html .= "</tr>";
+    }
+    return $html;
+}
+
+// Injection des contenus dans des variables
+$tableHeaderHTML = generateTableHeader($fields);
+$tableBodyHTML = generateTableBody($data);
+?>
+
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+<meta charset="UTF-8">
+<title>Tableau filtrable Super</title>
+<style>
+table { border-collapse: collapse; width: 50%; margin-top: 10px; }
+th, td { border: 1px solid #000; padding: 4px 8px; text-align: left; cursor: pointer; }
+th.selected { background-color: #cce5ff; }
+td span.highlight { background-color: #ffeb3b; font-weight: bold; }
+input.filter-input { width: 50%; padding: 4px; margin-bottom: 8px; font-size: 14px; }
+</style>
+</head>
+<body>
+
+<h2>Tableau filtrable “Super”</h2>
+
+<input type="text" class="filter-input" placeholder="Tapez pour filtrer...">
+
+<table class="filter-table">
+    <thead>
+        <tr><?= $tableHeaderHTML ?></tr>
+    </thead>
+    <tbody>
+        <?= $tableBodyHTML ?>
+    </tbody>
+</table>
+
+<script>
+// Classe générique pour filtrer un tableau avec multi-colonnes
+class TableFilter {
+    constructor(tableElement, inputElement) {
+        this.table = tableElement;
+        this.input = inputElement;
+        this.rows = tableElement.tBodies[0].rows;
+        this.headers = tableElement.tHead.rows[0].cells;
+        this.activeCols = new Set([0]); // colonne(s) active(s) par défaut
+
+        this.init();
+    }
+
+    init() {
+        for (let i = 0; i < this.headers.length; i++) {
+            this.headers[i].addEventListener('click', () => {
+                // toggle colonne active
+                if (this.activeCols.has(i)) {
+                    this.activeCols.delete(i);
+                    this.headers[i].classList.remove('selected');
+                } else {
+                    this.activeCols.add(i);
+                    this.headers[i].classList.add('selected');
+                }
+                this.filter();
+            });
+        }
+
+        this.input.addEventListener('input', () => this.filter());
+
+        // Initialisation visuelle
+        for (let i of this.activeCols) this.headers[i].classList.add('selected');
+    }
+
+    filter() {
+        const query = this.input.value.toLowerCase();
+
+        for (let row of this.rows) {
+            let match = false;
+
+            for (let i = 0; i < row.cells.length; i++) {
+                const cell = row.cells[i];
+                const text = cell.textContent;
+
+                if (this.activeCols.has(i) && query && text.toLowerCase().includes(query)) {
+                    const regex = new RegExp(`(${this.escapeRegExp(query)})`, 'gi');
+                    cell.innerHTML = text.replace(regex, '<span class="highlight">$1</span>');
+                    match = true;
+                } else {
+                    cell.textContent = text; // reset highlight
+                }
+            }
+
+            // Affichage : au moins une colonne correspond
+            row.style.display = match || query === "" ? '' : 'none';
+        }
+    }
+
+    escapeRegExp(string) {
+        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+    }
+}
+
+// Instanciation générique pour tous les tableaux
+document.querySelectorAll('.filter-table').forEach(table => {
+    const input = document.querySelector('.filter-input');
+    new TableFilter(table, input);
+});
+</script>
+
+</body>
+</html>
+
index 19be2b79ea25ac3f1f7afad94e292e06a7f2bb8d..36560e95db1451ba5e9e832a600450afb4f64c74 100644 (file)
@@ -106,10 +106,14 @@ global $userlang;
 global $isadmin;
 global $myfilename;
 
+$originator=gettranslate($userlang,"Originator");
+$recipient=gettranslate($userlang,"Recipient");
+$date=gettranslate($userlang,"Date");
+
 $limit=20;
 $offset=0;
 $dsearch="";
-$selectedField = 'rcptto';
+$selectedField = $recipient;
 
 if (isset($_POST['limit']))
   $limit=intval($_POST['limit']);
@@ -124,7 +128,7 @@ if (isset($_POST['dsearch'])) {
   $dsearch=trim($_POST['dsearch']);
   if (strlen($dsearch)>0) {
     // sécuriser le champ sélectionné
-    $allowedFields = ['smtpfrom','rcptto','creation'];
+    $allowedFields = [$originator,$recipient,$date];
   if (!in_array($selectedField,$allowedFields))
     $selectedField = 'rcptto';
 
@@ -224,10 +228,6 @@ $tblfooter="";
 if ($limit>30) 
   $tblfooter=$tblheader;
 
-$originator=gettranslate($userlang,"Originator");
-$recipient=gettranslate($userlang,"Recipient");
-$date=gettranslate($userlang,"Date");
-
 $STR  = <<<EOT
 
 $start