|
|
@@ -25,6 +25,122 @@ echo core::filAriane(array(
|
|
|
"refresh-json" => "documents"
|
|
|
));
|
|
|
?>
|
|
|
+
|
|
|
+<!-- Panel de filtres avancés -->
|
|
|
+<div class="card mb-3" id="advancedFiltersPanel">
|
|
|
+ <div class="card-header d-flex justify-content-between align-items-center" style="cursor: pointer;" onclick="toggleAdvancedFilters()">
|
|
|
+ <span><i class="bi bi-funnel"></i> Filtres avancés</span>
|
|
|
+ <i class="bi bi-chevron-up" id="advancedFiltersIcon"></i>
|
|
|
+ </div>
|
|
|
+ <div class="card-body" id="advancedFiltersBody">
|
|
|
+ <div class="row">
|
|
|
+ <!-- Filtre par mots-clés sur le titre -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Mots-clés dans le Titre</label>
|
|
|
+ <input type="text" class="form-control form-control-sm" id="search-titre-keywords" placeholder="Ex: facture contrat">
|
|
|
+ <small class="text-muted">Mots-clés séparés par espaces</small>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par plage de dates -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Période (Date)</label>
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <input type="date" id="dateDebut" class="form-control form-control-sm me-2">
|
|
|
+ <span class="me-2">à</span>
|
|
|
+ <input type="date" id="dateFin" class="form-control form-control-sm">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par échéance -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Période (Échéance)</label>
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <input type="date" id="deadlineDebut" class="form-control form-control-sm me-2">
|
|
|
+ <span class="me-2">à</span>
|
|
|
+ <input type="date" id="deadlineFin" class="form-control form-control-sm">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row">
|
|
|
+ <!-- Filtre par montant -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Recherche montant</label>
|
|
|
+ <input type="text" class="form-control form-control-sm" id="searchMontant" placeholder="Ex: 5086 ou >1000">
|
|
|
+ <small class="text-muted">Recherche exacte ou avec opérateur</small>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par plage de montant -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Plage Montant</label>
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <input type="number" step="0.01" id="minMontant" class="form-control form-control-sm me-2" placeholder="Min" style="width: 100px;">
|
|
|
+ <span class="me-2">à</span>
|
|
|
+ <input type="number" step="0.01" id="maxMontant" class="form-control form-control-sm" placeholder="Max" style="width: 100px;">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par tags -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Tags</label>
|
|
|
+ <input type="text" class="form-control form-control-sm" id="searchTags" placeholder="Ex: urgent important">
|
|
|
+ <small class="text-muted">Mots-clés séparés par espaces</small>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row">
|
|
|
+ <!-- Filtre par Type -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Type</label>
|
|
|
+ <select class="form-select form-select-sm" id="filterType">
|
|
|
+ <option value="">-- Tous les types --</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par Attachement -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Attachement</label>
|
|
|
+ <select class="form-select form-select-sm" id="filterAttach">
|
|
|
+ <option value="">-- Tous les attachements --</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par Attribution -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Attribution</label>
|
|
|
+ <select class="form-select form-select-sm" id="filterAssign">
|
|
|
+ <option value="">-- Toutes les attributions --</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filtre par Statut -->
|
|
|
+ <div class="col-lg-3 col-md-6 mb-3">
|
|
|
+ <label class="form-label fw-bold">Statut</label>
|
|
|
+ <select class="form-select form-select-sm" id="filterStatut">
|
|
|
+ <option value="">-- Tous les statuts --</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="mt-2">
|
|
|
+ <button type="button" class="btn btn-sm btn-primary me-2" onclick="applyAdvancedFilters()">
|
|
|
+ <i class="bi bi-funnel-fill"></i> Appliquer les filtres
|
|
|
+ </button>
|
|
|
+ <button type="button" class="btn btn-sm btn-outline-secondary" onclick="clearAllAdvancedFilters()">
|
|
|
+ <i class="bi bi-x-circle"></i> Réinitialiser les filtres
|
|
|
+ </button>
|
|
|
+ <span class="ms-3 text-muted" id="filterInfo"></span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+
|
|
|
+<style>
|
|
|
+ #advancedFiltersPanel .card-header:hover {
|
|
|
+ background-color: #f8f9fa;
|
|
|
+ }
|
|
|
+</style>
|
|
|
+
|
|
|
<div>
|
|
|
<table
|
|
|
id="table"
|
|
|
@@ -36,7 +152,6 @@ echo core::filAriane(array(
|
|
|
data-buttons-align="left"
|
|
|
data-show-footer="true"
|
|
|
data-pagination="true"
|
|
|
- data-filter-control="true"
|
|
|
data-flat="true"
|
|
|
data-sort-name="date"
|
|
|
data-sort-order="desc"
|
|
|
@@ -45,15 +160,15 @@ echo core::filAriane(array(
|
|
|
data-url="<?php echo $jsonTarget ?>">
|
|
|
<thead>
|
|
|
<tr>
|
|
|
- <th data-sortable="true" data-field="date" data-filter-control="input" data-width="90">Date</th>
|
|
|
- <th data-sortable="true" data-field="titre" data-filter-control="input">Titre</th>
|
|
|
- <th data-sortable="true" data-field="label" data-filter-control="select" data-width="125">Type</th>
|
|
|
- <th data-sortable="true" data-field="attach" data-filter-control="select" data-width="180">Attachement</th>
|
|
|
- <th data-sortable="true" data-field="deadline" data-filter-control="input" data-width="90">Echéance</th>
|
|
|
- <th data-sortable="true" data-field="tags" data-filter-control="input" data-width="200">Tags</th>
|
|
|
- <th data-sortable="true" data-field="assign" data-filter-control="select" data-width="200">Attribution</th>
|
|
|
- <th data-sortable="true" s data-field="done" data-filter-control="select" data-width="100">Statut</th>
|
|
|
- <th data-sortable="true" data-field="montant" data-filter-control="input" data-width="110" data-formatter="dataFormatter" data-footer-formatter="montantFormatter">Montant</th>
|
|
|
+ <th data-sortable="true" data-field="date" data-width="90">Date</th>
|
|
|
+ <th data-sortable="true" data-field="titre">Titre</th>
|
|
|
+ <th data-sortable="true" data-field="label" data-width="125">Type</th>
|
|
|
+ <th data-sortable="true" data-field="attach" data-width="180">Attachement</th>
|
|
|
+ <th data-sortable="true" data-field="deadline" data-width="90">Echéance</th>
|
|
|
+ <th data-sortable="true" data-field="tags" data-width="200">Tags</th>
|
|
|
+ <th data-sortable="true" data-field="assign" data-width="200">Attribution</th>
|
|
|
+ <th data-sortable="true" data-field="done" data-width="100">Statut</th>
|
|
|
+ <th data-sortable="true" data-field="montant" data-width="110" data-formatter="dataFormatter" data-footer-formatter="montantFormatter">Montant</th>
|
|
|
<th data-field="id" data-formatter="selectFormatter" data-width="60"></th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
@@ -61,29 +176,28 @@ echo core::filAriane(array(
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
-
|
|
|
-<?php
|
|
|
+ <?php
|
|
|
if (core::ifGet("tag")) { ?>
|
|
|
|
|
|
- $(function() {
|
|
|
- tagValue = "<?php echo core::getGet("tag"); ?>";
|
|
|
+ $(function() {
|
|
|
+ tagValue = "<?php echo core::getGet("tag"); ?>";
|
|
|
|
|
|
- if (tagValue) {
|
|
|
- function applyTagFilter() {
|
|
|
- var $input = $('#table input.bootstrap-table-filter-control-tags');
|
|
|
- console.log('input:', $input.length, 'valeur:', tagValue);
|
|
|
- if ($input.length) {
|
|
|
- $input.val(tagValue).trigger('input');
|
|
|
+ if (tagValue) {
|
|
|
+ function applyTagFilter() {
|
|
|
+ var $input = $('#table input.bootstrap-table-filter-control-tags');
|
|
|
+ console.log('input:', $input.length, 'valeur:', tagValue);
|
|
|
+ if ($input.length) {
|
|
|
+ $input.val(tagValue).trigger('input');
|
|
|
+ }
|
|
|
}
|
|
|
+ $('#table').on('post-body.bs.table post-header.bs.table', applyTagFilter);
|
|
|
+ setTimeout(applyTagFilter, 800);
|
|
|
}
|
|
|
- $('#table').on('post-body.bs.table post-header.bs.table', applyTagFilter);
|
|
|
- setTimeout(applyTagFilter, 800);
|
|
|
- }
|
|
|
- });
|
|
|
+ });
|
|
|
|
|
|
-<?php
|
|
|
+ <?php
|
|
|
}
|
|
|
-?>
|
|
|
+ ?>
|
|
|
|
|
|
function selectFormatter(value, row) {
|
|
|
return '<a href="/document-' + row.id + '.html"><button type="submit" class="btn btn-outline-primary btn-sm">Ouvrir</button></a>';
|
|
|
@@ -105,4 +219,380 @@ echo core::filAriane(array(
|
|
|
});
|
|
|
return parseFloat(total) === 0 ? euro.format(0.00) : euro.format(total.toFixed(2));
|
|
|
}
|
|
|
+
|
|
|
+ // Données originales
|
|
|
+ let originalData = [];
|
|
|
+
|
|
|
+ // Toggle du panneau de filtres avancés
|
|
|
+ function toggleAdvancedFilters() {
|
|
|
+ const body = document.getElementById('advancedFiltersBody');
|
|
|
+ const icon = document.getElementById('advancedFiltersIcon');
|
|
|
+ if (body.style.display === 'none') {
|
|
|
+ body.style.display = 'block';
|
|
|
+ icon.className = 'bi bi-chevron-up';
|
|
|
+ } else {
|
|
|
+ body.style.display = 'none';
|
|
|
+ icon.className = 'bi bi-chevron-down';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convertir une date en objet Date (supporte DD/MM/YYYY et YYYY-MM-DD)
|
|
|
+ function parseDate(dateStr) {
|
|
|
+ if (!dateStr) return null;
|
|
|
+
|
|
|
+ // Format DD/MM/YYYY
|
|
|
+ if (dateStr.includes('/')) {
|
|
|
+ const parts = dateStr.split('/');
|
|
|
+ if (parts.length === 3) {
|
|
|
+ return new Date(parseInt(parts[2]), parseInt(parts[1]) - 1, parseInt(parts[0]), 0, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Format YYYY-MM-DD (format ISO/MySQL)
|
|
|
+ if (dateStr.includes('-')) {
|
|
|
+ const parts = dateStr.split('-');
|
|
|
+ if (parts.length === 3 && parts[0].length === 4) {
|
|
|
+ return new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]), 0, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fonction de filtre pour les montants
|
|
|
+ function filterMontant(searchValue, numValue) {
|
|
|
+ if (!searchValue || searchValue.trim() === '') return true;
|
|
|
+
|
|
|
+ const absNumValue = Math.abs(numValue);
|
|
|
+
|
|
|
+ let searchNormalized = searchValue.trim()
|
|
|
+ .replace(/\s/g, '')
|
|
|
+ .replace(/€/g, '')
|
|
|
+ .replace(/\./g, '')
|
|
|
+ .replace(/,/g, '.');
|
|
|
+
|
|
|
+ let operator = null;
|
|
|
+ if (searchNormalized.startsWith('>=')) {
|
|
|
+ operator = '>=';
|
|
|
+ searchNormalized = searchNormalized.substring(2);
|
|
|
+ } else if (searchNormalized.startsWith('<=')) {
|
|
|
+ operator = '<=';
|
|
|
+ searchNormalized = searchNormalized.substring(2);
|
|
|
+ } else if (searchNormalized.startsWith('>')) {
|
|
|
+ operator = '>';
|
|
|
+ searchNormalized = searchNormalized.substring(1);
|
|
|
+ } else if (searchNormalized.startsWith('<')) {
|
|
|
+ operator = '<';
|
|
|
+ searchNormalized = searchNormalized.substring(1);
|
|
|
+ } else if (searchNormalized.startsWith('=')) {
|
|
|
+ operator = '=';
|
|
|
+ searchNormalized = searchNormalized.substring(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ const searchNum = parseFloat(searchNormalized);
|
|
|
+
|
|
|
+ if (isNaN(searchNum)) {
|
|
|
+ const formattedValue = euro.format(numValue).toLowerCase();
|
|
|
+ return formattedValue.includes(searchValue.toLowerCase());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (operator) {
|
|
|
+ switch (operator) {
|
|
|
+ case '>':
|
|
|
+ return numValue > searchNum;
|
|
|
+ case '<':
|
|
|
+ return numValue < searchNum;
|
|
|
+ case '>=':
|
|
|
+ return numValue >= searchNum;
|
|
|
+ case '<=':
|
|
|
+ return numValue <= searchNum;
|
|
|
+ case '=':
|
|
|
+ return Math.abs(numValue - searchNum) < 0.01;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Math.abs(numValue - searchNum) < 0.01 || Math.abs(absNumValue - searchNum) < 0.01) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ const intPart = Math.floor(absNumValue);
|
|
|
+ const searchInt = Math.floor(searchNum);
|
|
|
+
|
|
|
+ if (intPart === searchInt) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ const numStr = absNumValue.toFixed(2);
|
|
|
+ const searchStr = searchInt.toString();
|
|
|
+
|
|
|
+ return numStr.startsWith(searchStr) || intPart.toString().includes(searchStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Appliquer tous les filtres avancés
|
|
|
+ function applyAdvancedFilters() {
|
|
|
+ // Récupérer les dates
|
|
|
+ const dateDebutStr = document.getElementById('dateDebut').value;
|
|
|
+ const dateFinStr = document.getElementById('dateFin').value;
|
|
|
+ const deadlineDebutStr = document.getElementById('deadlineDebut').value;
|
|
|
+ const deadlineFinStr = document.getElementById('deadlineFin').value;
|
|
|
+
|
|
|
+ let dateDebut = null,
|
|
|
+ dateFin = null,
|
|
|
+ deadlineDebut = null,
|
|
|
+ deadlineFin = null;
|
|
|
+
|
|
|
+ if (dateDebutStr) {
|
|
|
+ const parts = dateDebutStr.split('-');
|
|
|
+ dateDebut = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]), 0, 0, 0);
|
|
|
+ }
|
|
|
+ if (dateFinStr) {
|
|
|
+ const parts = dateFinStr.split('-');
|
|
|
+ dateFin = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]), 23, 59, 59);
|
|
|
+ }
|
|
|
+ if (deadlineDebutStr) {
|
|
|
+ const parts = deadlineDebutStr.split('-');
|
|
|
+ deadlineDebut = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]), 0, 0, 0);
|
|
|
+ }
|
|
|
+ if (deadlineFinStr) {
|
|
|
+ const parts = deadlineFinStr.split('-');
|
|
|
+ deadlineFin = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]), 23, 59, 59);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fonction pour normaliser le texte (retirer accents et passer en majuscules)
|
|
|
+ const normalizeText = (text) => (text || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toUpperCase();
|
|
|
+
|
|
|
+ // Récupérer les mots-clés du titre
|
|
|
+ const titreInput = document.getElementById('search-titre-keywords').value.trim();
|
|
|
+ const titreKeywords = titreInput.split(/\s+/).filter(k => k.length > 0).map(k => normalizeText(k));
|
|
|
+
|
|
|
+ // Récupérer les tags
|
|
|
+ const tagsInput = document.getElementById('searchTags').value.trim();
|
|
|
+ const tagsKeywords = tagsInput.split(/\s+/).filter(k => k.length > 0).map(k => normalizeText(k));
|
|
|
+
|
|
|
+ // Récupérer la recherche de montant
|
|
|
+ const searchMontant = document.getElementById('searchMontant').value.trim();
|
|
|
+
|
|
|
+ const minMontant = parseFloat(document.getElementById('minMontant').value);
|
|
|
+ const maxMontant = parseFloat(document.getElementById('maxMontant').value);
|
|
|
+
|
|
|
+ // Récupérer les filtres Type, Attachement, Attribution, Statut
|
|
|
+ const filterType = document.getElementById('filterType').value;
|
|
|
+ const filterAttach = document.getElementById('filterAttach').value;
|
|
|
+ const filterAssign = document.getElementById('filterAssign').value;
|
|
|
+ const filterStatut = document.getElementById('filterStatut').value;
|
|
|
+
|
|
|
+ let filteredData = originalData.filter(row => {
|
|
|
+ // Filtre par plage de dates
|
|
|
+ if (dateDebut || dateFin) {
|
|
|
+ const rowDate = parseDate(row.date);
|
|
|
+ if (!rowDate) return false;
|
|
|
+ if (dateDebut && rowDate < dateDebut) return false;
|
|
|
+ if (dateFin && rowDate > dateFin) return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Filtre par plage d'échéance
|
|
|
+ if (deadlineDebut || deadlineFin) {
|
|
|
+ const rowDeadline = parseDate(row.deadline);
|
|
|
+ if (!rowDeadline) return false;
|
|
|
+ if (deadlineDebut && rowDeadline < deadlineDebut) return false;
|
|
|
+ if (deadlineFin && rowDeadline > deadlineFin) return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Filtre par mots-clés dans le titre
|
|
|
+ if (titreKeywords.length > 0) {
|
|
|
+ const titreNorm = normalizeText(row.titre);
|
|
|
+ const hasAllKeywords = titreKeywords.every(keyword => titreNorm.includes(keyword));
|
|
|
+ if (!hasAllKeywords) return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Filtre par tags
|
|
|
+ if (tagsKeywords.length > 0) {
|
|
|
+ const tagsNorm = normalizeText(row.tags);
|
|
|
+ const hasAllTags = tagsKeywords.every(keyword => tagsNorm.includes(keyword));
|
|
|
+ if (!hasAllTags) return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Filtre par recherche de montant
|
|
|
+ if (searchMontant) {
|
|
|
+ const montant = parseFloat(row.montant) || 0;
|
|
|
+ if (!filterMontant(searchMontant, montant)) return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Filtre par plage de montant
|
|
|
+ const montant = parseFloat(row.montant) || 0;
|
|
|
+ if (!isNaN(minMontant) && montant < minMontant) return false;
|
|
|
+ if (!isNaN(maxMontant) && montant > maxMontant) return false;
|
|
|
+
|
|
|
+ // Filtre par Type
|
|
|
+ if (filterType && (row.label || '') !== filterType) return false;
|
|
|
+
|
|
|
+ // Filtre par Attachement
|
|
|
+ if (filterAttach && (row.attach || '') !== filterAttach) return false;
|
|
|
+
|
|
|
+ // Filtre par Attribution
|
|
|
+ if (filterAssign && (row.assign || '') !== filterAssign) return false;
|
|
|
+
|
|
|
+ // Filtre par Statut
|
|
|
+ if (filterStatut && (row.done || '') !== filterStatut) return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ // Recharger le tableau avec les données filtrées
|
|
|
+ $('#table').bootstrapTable('load', filteredData);
|
|
|
+ updateFilterInfo(filteredData.length, titreKeywords);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Réinitialiser tous les filtres avancés
|
|
|
+ function clearAllAdvancedFilters() {
|
|
|
+ document.getElementById('dateDebut').value = '';
|
|
|
+ document.getElementById('dateFin').value = '';
|
|
|
+ document.getElementById('deadlineDebut').value = '';
|
|
|
+ document.getElementById('deadlineFin').value = '';
|
|
|
+ document.getElementById('search-titre-keywords').value = '';
|
|
|
+ document.getElementById('searchTags').value = '';
|
|
|
+ document.getElementById('searchMontant').value = '';
|
|
|
+ document.getElementById('minMontant').value = '';
|
|
|
+ document.getElementById('maxMontant').value = '';
|
|
|
+ document.getElementById('filterType').value = '';
|
|
|
+ document.getElementById('filterAttach').value = '';
|
|
|
+ document.getElementById('filterAssign').value = '';
|
|
|
+ document.getElementById('filterStatut').value = '';
|
|
|
+
|
|
|
+ $('#table').bootstrapTable('load', originalData);
|
|
|
+ updateFilterInfo(originalData.length, []);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Mettre à jour l'info des filtres actifs
|
|
|
+ function updateFilterInfo(count, keywords) {
|
|
|
+ const infoEl = document.getElementById('filterInfo');
|
|
|
+ const activeFilters = [];
|
|
|
+
|
|
|
+ const dateDebut = document.getElementById('dateDebut').value;
|
|
|
+ const dateFin = document.getElementById('dateFin').value;
|
|
|
+ if (dateDebut || dateFin) {
|
|
|
+ activeFilters.push(`Date: ${dateDebut || 'début'} à ${dateFin || 'fin'}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const deadlineDebut = document.getElementById('deadlineDebut').value;
|
|
|
+ const deadlineFin = document.getElementById('deadlineFin').value;
|
|
|
+ if (deadlineDebut || deadlineFin) {
|
|
|
+ activeFilters.push(`Échéance: ${deadlineDebut || 'début'} à ${deadlineFin || 'fin'}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (keywords && keywords.length > 0) {
|
|
|
+ activeFilters.push(`Titre: "${keywords.join(' + ')}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const searchTags = document.getElementById('searchTags').value;
|
|
|
+ if (searchTags) {
|
|
|
+ activeFilters.push(`Tags: "${searchTags}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const searchMontant = document.getElementById('searchMontant').value;
|
|
|
+ if (searchMontant) {
|
|
|
+ activeFilters.push(`Montant: "${searchMontant}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const minMontant = document.getElementById('minMontant').value;
|
|
|
+ const maxMontant = document.getElementById('maxMontant').value;
|
|
|
+ if (minMontant || maxMontant) {
|
|
|
+ activeFilters.push(`Plage: ${minMontant || '0'} - ${maxMontant || '∞'}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const filterType = document.getElementById('filterType').value;
|
|
|
+ if (filterType) {
|
|
|
+ activeFilters.push(`Type: "${filterType}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const filterAttach = document.getElementById('filterAttach').value;
|
|
|
+ if (filterAttach) {
|
|
|
+ activeFilters.push(`Attachement: "${filterAttach}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const filterAssign = document.getElementById('filterAssign').value;
|
|
|
+ if (filterAssign) {
|
|
|
+ activeFilters.push(`Attribution: "${filterAssign}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const filterStatut = document.getElementById('filterStatut').value;
|
|
|
+ if (filterStatut) {
|
|
|
+ activeFilters.push(`Statut: "${filterStatut}"`);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeFilters.length > 0) {
|
|
|
+ infoEl.innerHTML = `<strong>${count}</strong> document(s) affiché(s) | Filtres: ${activeFilters.join(', ')}`;
|
|
|
+ } else {
|
|
|
+ infoEl.innerHTML = `<strong>${count || originalData.length}</strong> document(s) au total`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Populer les selects avec les valeurs uniques
|
|
|
+ function populateSelectFilters(data) {
|
|
|
+ const types = [...new Set(data.map(row => row.label).filter(v => v))].sort();
|
|
|
+ const attachs = [...new Set(data.map(row => row.attach).filter(v => v))].sort();
|
|
|
+ const assigns = [...new Set(data.map(row => row.assign).filter(v => v))].sort();
|
|
|
+ const statuts = [...new Set(data.map(row => row.done).filter(v => v))].sort();
|
|
|
+
|
|
|
+ const selectType = document.getElementById('filterType');
|
|
|
+ const selectAttach = document.getElementById('filterAttach');
|
|
|
+ const selectAssign = document.getElementById('filterAssign');
|
|
|
+ const selectStatut = document.getElementById('filterStatut');
|
|
|
+
|
|
|
+ // Réinitialiser et repeupler Type
|
|
|
+ selectType.innerHTML = '<option value="">-- Tous les types --</option>';
|
|
|
+ types.forEach(type => {
|
|
|
+ const option = document.createElement('option');
|
|
|
+ option.value = type;
|
|
|
+ option.textContent = type;
|
|
|
+ selectType.appendChild(option);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Réinitialiser et repeupler Attachement
|
|
|
+ selectAttach.innerHTML = '<option value="">-- Tous les attachements --</option>';
|
|
|
+ attachs.forEach(attach => {
|
|
|
+ const option = document.createElement('option');
|
|
|
+ option.value = attach;
|
|
|
+ option.textContent = attach;
|
|
|
+ selectAttach.appendChild(option);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Réinitialiser et repeupler Attribution
|
|
|
+ selectAssign.innerHTML = '<option value="">-- Toutes les attributions --</option>';
|
|
|
+ assigns.forEach(assign => {
|
|
|
+ const option = document.createElement('option');
|
|
|
+ option.value = assign;
|
|
|
+ option.textContent = assign;
|
|
|
+ selectAssign.appendChild(option);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Réinitialiser et repeupler Statut
|
|
|
+ selectStatut.innerHTML = '<option value="">-- Tous les statuts --</option>';
|
|
|
+ statuts.forEach(statut => {
|
|
|
+ const option = document.createElement('option');
|
|
|
+ option.value = statut;
|
|
|
+ option.textContent = statut;
|
|
|
+ selectStatut.appendChild(option);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Initialisation
|
|
|
+ $(document).ready(function() {
|
|
|
+ const $table = $('#table');
|
|
|
+
|
|
|
+ $table.on('load-success.bs.table', function(e, data) {
|
|
|
+ originalData = data;
|
|
|
+ populateSelectFilters(data);
|
|
|
+ updateFilterInfo(data.length, []);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Appliquer le filtre avec Entrée sur les champs texte
|
|
|
+ ['search-titre-keywords', 'searchTags', 'searchMontant'].forEach(id => {
|
|
|
+ document.getElementById(id).addEventListener('keypress', function(e) {
|
|
|
+ if (e.key === 'Enter') {
|
|
|
+ applyAdvancedFilters();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
</script>
|