document.addEventListener(‘DOMContentLoaded’, function() {
// — Données initiales pour le tableau —
// Ces données sont intégrées directement dans le script, comme demandé.
// Conformément aux contraintes, si une API externe était utilisée, son URL et un exemple
// de réponse JSON seraient inclus ici en commentaire.
//
// Exemple d’API publique gratuite (non utilisée ici car les données sont fournies directement) :
// API: JSONPlaceholder (pour des données factices génériques comme des posts, utilisateurs)
// URL: https://jsonplaceholder.typicode.com/posts
// Exemple de réponse JSON (extrait):
// [
// {
// “userId”: 1,
// “id”: 1,
// “title”: “sunt aut facere repellat provident occaecati excepturi optio reprehenderit”,
// “body”: “quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto”
// },
// …
// ]
const initialData = [
{‘Partenaire’: ‘Médecins Sans Frontières’, ‘Domaines d’intervention’: ‘Soins médicaux d’urgence, gestion d’épidémies’, ‘Contribution à la mission’: ‘Interventions rapides en zones d’urgence, gestion des crises sanitaires, protocoles médicaux standardisés’},
{‘Partenaire’: ‘La Chaîne de l’Espoir’, ‘Domaines d’intervention’: ‘Chirurgie pédiatrique, centres hospitaliers stratégiques’, ‘Contribution à la mission’: ‘Opérations chirurgicales vitales pour les enfants, transfert de compétences médicales et chirurgicales, formation locale’},
{‘Partenaire’: ‘Première Urgence Internationale’, ‘Domaines d’intervention’: ‘Aide humanitaire intégrée, protection et réhabilitation’, ‘Contribution à la mission’: ‘Programmes de réinsertion socio-économique, soutien psychosocial aux populations affectées, accès aux services essentiels’},
{‘Partenaire’: ‘Action contre la Faim’, ‘Domaines d’intervention’: ‘Nutrition, sécurité alimentaire, eau, assainissement’, ‘Contribution à la mission’: ‘Lutte contre la malnutrition aiguë sévère, promotion de pratiques d’hygiène, renforcement des capacités agricoles communautaires’},
{‘Partenaire’: ‘Alliances et Missions Médicales (AMM)’, ‘Domaines d’intervention’: ‘Coordination de missions longues, parrainages étudiants, infrastructures’, ‘Contribution à la mission’: ‘Soutien logistique et administratif complet pour la mission familiale, facilitation des liens avec les institutions locales, programmes de parrainage éducatif’}
];
let currentData = […initialData]; // Copie des données initiales pour les manipulations (tri, filtre)
let sortColumn = null;
let sortDirection = ‘asc’; // ‘asc’ pour ascendant, ‘desc’ pour descendant
// — Références aux éléments du DOM —
const tableBody = document.getElementById(‘tableBody’);
const searchInput = document.getElementById(‘searchInput’);
const resetSearchButton = document.getElementById(‘resetSearchButton’);
const tableHeaders = document.querySelectorAll(‘#comparateurPartenaires thead th[data-sort-key]’);
const noResultsMessage = document.getElementById(‘noResults’);
// — Fonction de rendu du tableau —
// Cette fonction prend un tableau de données et met à jour le contenu du tbody.
function renderTable(dataToDisplay) {
tableBody.innerHTML = ”; // Efface le contenu actuel du tableau
if (dataToDisplay.length === 0) {
noResultsMessage.classList.remove(‘hidden’); // Affiche le message “Aucun résultat”
return;
} else {
noResultsMessage.classList.add(‘hidden’); // Cache le message “Aucun résultat”
}
dataToDisplay.forEach((item, index) => {
const row = document.createElement(‘tr’);
// Ajout de classes Tailwind pour un style alterné et un effet au survol
row.classList.add(‘hover:bg-blue-50’, index % 2 === 0 ? ‘bg-white’ : ‘bg-gray-50’, ‘transition’, ‘duration-150’, ‘ease-in-out’);
// Création et ajout des cellules pour chaque propriété de l’objet
[‘Partenaire’, ‘Domaines d’intervention’, ‘Contribution à la mission’].forEach(key => {
const cell = document.createElement(‘td’);
// Classes pour le padding, le retour à la ligne automatique et la taille maximale
cell.classList.add(‘px-6’, ‘py-4’, ‘whitespace-normal’, ‘text-sm’, ‘text-gray-700’);
if (key === ‘Partenaire’) {
cell.classList.add(‘font-medium’, ‘text-gray-900’, ‘max-w-xs’); // Style spécifique pour le nom du partenaire
} else {
cell.classList.add(‘max-w-md’);
}
cell.textContent = item[key]; // Affecte le texte de la cellule
row.appendChild(cell);
});
tableBody.appendChild(row); // Ajoute la ligne au corps du tableau
});
}
// — Fonction de tri —
// Trie les données actuelles en fonction de la colonne cliquée et de la direction.
function sortData(key) {
// Inverse la direction si la même colonne est cliquée à nouveau
if (sortColumn === key) {
sortDirection = sortDirection === ‘asc’ ? ‘desc’ : ‘asc’;
} else {
sortColumn = key; // Définit la nouvelle colonne de tri
sortDirection = ‘asc’; // Commence toujours par un tri ascendant pour une nouvelle colonne
}
// Tri effectif des données
currentData.sort((a, b) => {
const valA = String(a[key]).toLowerCase();
const valB = String(b[key]).toLowerCase();
if (valA valB) return sortDirection === ‘asc’ ? 1 : -1;
return 0;
});
updateSortIcons(); // Met à jour les icônes de tri dans les en-têtes
renderTable(currentData); // Re-rend le tableau avec les données triées
}
// — Fonction pour mettre à jour les icônes de tri —
// Affiche la flèche appropriée (↑ ou ↓) et change la couleur de l’icône de tri.
function updateSortIcons() {
tableHeaders.forEach(header => {
const icon = header.querySelector(‘.sort-icon’);
header.setAttribute(‘aria-sort’, ‘none’); // Réinitialise l’attribut ARIA pour l’accessibilité
if (icon) {
icon.innerHTML = ‘⇅’; // Icône par défaut pour les colonnes non triées
icon.classList.remove(‘text-blue-700’, ‘opacity-100’, ‘rotate-180’); // Nettoyage des classes spécifiques au tri
icon.classList.add(‘text-blue-500’, ‘opacity-50’); // Style par défaut pour les icônes inactives
}
if (header.dataset.sortKey === sortColumn) {
// Si c’est la colonne actuellement triée
if (icon) {
icon.innerHTML = ‘↑’; // Flèche vers le haut pour ascendant
if (sortDirection === ‘desc’) {
icon.classList.add(‘rotate-180’); // Rotation pour la flèche descendante
} else {
icon.classList.remove(‘rotate-180’);
}
icon.classList.remove(‘text-blue-500’, ‘opacity-50’);
icon.classList.add(‘text-blue-700’, ‘opacity-100’); // Style actif
}
header.setAttribute(‘aria-sort’, sortDirection === ‘asc’ ? ‘ascending’ : ‘descending’); // Met à jour l’attribut ARIA
}
});
}
// — Fonction de filtrage/recherche —
// Filtre les données en fonction du terme de recherche saisi par l’utilisateur.
function filterData() {
const searchTerm = searchInput.value.toLowerCase().trim(); // Convertit en minuscules et enlève les espaces inutiles
let filteredSet = initialData; // Commence toujours par les données initiales pour le filtrage
if (searchTerm) {
filteredSet = initialData.filter(item =>
// Vérifie si une des valeurs de l’objet (Partenaire, Domaines, Contribution) contient le terme de recherche
Object.values(item).some(value =>
String(value).toLowerCase().includes(searchTerm)
)
);
}
currentData = […filteredSet]; // Met à jour `currentData` avec les résultats du filtrage
// Applique le tri si une colonne est actuellement triée, pour maintenir l’ordre après le filtrage
if (sortColumn) {
currentData.sort((a, b) => {
const valA = String(a[sortColumn]).toLowerCase();
const valB = String(b[sortColumn]).toLowerCase();
if (valA valB) return sortDirection === ‘asc’ ? 1 : -1;
return 0;
});
}
renderTable(currentData); // Re-rend le tableau avec les données filtrées et/ou triées
}
// — Écouteurs d’événements —
// Écoute les changements dans le champ de recherche
searchInput.addEventListener(‘input’, filterData);
// Écoute le clic sur le bouton de réinitialisation
resetSearchButton.addEventListener(‘click’, () => {
searchInput.value = ”; // Vide le champ de recherche
currentData = […initialData]; // Réinitialise les données à leur état initial
sortColumn = null; // Réinitialise la colonne de tri
sortDirection = ‘asc’; // Réinitialise la direction de tri
updateSortIcons(); // Met à jour les icônes de tri à leur état par défaut
renderTable(currentData); // Affiche le tableau avec les données initiales
});
// Ajoute un écouteur de clic à chaque en-tête de colonne triable
tableHeaders.forEach(header => {
header.addEventListener(‘click’, () => {
const key = header.dataset.sortKey; // Récupère la clé de tri de l’attribut `data-sort-key`
sortData(key); // Appelle la fonction de tri
});
});
// — Initialisation —
// Appelé au chargement de la page pour afficher le tableau initialement
renderTable(currentData);
updateSortIcons(); // Assure que les icônes de tri sont dans leur état par défaut au chargement
});
{“@context”:”https://schema.org”,”@type”:”FAQPage”,”mainEntity”:[{“@type”:”Question”,”name”:”Quel est le principal du00e9fi pour une famille en mission humanitaire de longue duru00e9e u00e0 Madagascar ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”L’adaptation u00e0 un environnement culturel, social et logistique tru00e8s diffu00e9rent est un du00e9fi majeur, notamment concernant la scolarisation des enfants et la gestion quotidienne dans un contexte de ressources limitu00e9es.”}},{“@type”:”Question”,”name”:”Les enfants peuvent-ils u00eatre intu00e9gru00e9s dans des u00e9coles locales pendant la mission ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Oui, il est courant d’inscrire les enfants dans des u00e9tablissements publics ou privu00e9s locaux, ce qui favorise leur immersion linguistique et culturelle au sein de la communautu00e9 malgache.”}},{“@type”:”Question”,”name”:”Quelles associations interviennent dans le domaine mu00e9dical u00e0 Madagascar ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Mu00e9decins Sans Frontiu00e8res, La Chau00eene de lu2019Espoir, Premiu00e8re Urgence Internationale, Action contre la Faim et Alliances et Missions Mu00e9dicales (AMM) sont parmi les principales ONG actives dans lu2019aide mu00e9dicale et chirurgicale sur place.”}},{“@type”:”Question”,”name”:”Comment soutenir une mission humanitaire u00e0 distance ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Il est possible de soutenir ces missions par des dons financiers, du bu00e9nu00e9volat pour des campagnes de sensibilisation, ou des actions de parrainage via des associations telles qu’Enfants du Monde ou Action contre la Faim.”}},{“@type”:”Question”,”name”:”Quels sont les bu00e9nu00e9fices pour les enfants participant u00e0 de telles missions ?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Ils du00e9veloppent une ouverture interculturelle, une adaptabilitu00e9 renforcu00e9e et une conscience des enjeux planu00e9taires, ce qui contribue grandement u00e0 leur formation personnelle et citoyenne.”}}]}
Découvrez la limonade Bonbon Anglais, la boisson gazeuse emblématique de Madagascar qui séduit petits et grands par son goût unique et rafraîchissant. Fabriquée avec des ingrédients de qualité et des arômes naturels, Bonbon Anglais vous offre une expérience gustative inégalée. Parfaite pour toutes les occasions, cette limonade apportera une touche d’exotisme et de fraîcheur à vos moments de détente. Essayez-la dès aujourd’hui et laissez-vous emporter par le peps et l’authenticité de Bonbon Anglais, la star des boissons malgaches !