-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
132 lines (111 loc) · 4.92 KB
/
script.js
File metadata and controls
132 lines (111 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('cactus-container');
const speciesCount = document.getElementById('species-count');
const viewer = document.getElementById('image-viewer');
const fullImg = document.getElementById('full-image');
const caption = document.getElementById('modal-caption');
const closeBtn = document.querySelector('.close-modal');
const backToTopBtn = document.getElementById("backToTop");
// Elementi di controllo
const searchInput = document.getElementById('search-input');
const sortSelect = document.getElementById('sort-select');
const filterType = document.getElementById('filter-type');
let allPlants = [];
function generaStelle(livello) {
const rating = Math.min(Math.max(livello, 1), 5);
return '★'.repeat(rating) + '☆'.repeat(5 - rating);
}
async function loadCactus() {
try {
const response = await fetch('data.json?v=' + Date.now());
if (!response.ok) throw new Error('Errore caricamento database');
const data = await response.json();
allPlants = data.piante;
if (speciesCount) speciesCount.innerText = allPlants.length;
applyFilters(); // Esegue il primo rendering con i filtri attivi
} catch (error) {
container.innerHTML = `<p style="text-align:center;">🌵 Errore: ${error.message}</p>`;
}
}
// Funzione unificata per filtrare e ordinare
function applyFilters() {
const term = searchInput.value.toLowerCase();
const type = filterType.value;
const sort = sortSelect.value;
// 1. Filtra per ricerca E per tipo
let filtered = allPlants.filter(plant => {
const matchesSearch =
plant.nome.toLowerCase().includes(term) ||
plant.soprannome.toLowerCase().includes(term) ||
plant.descrizione.toLowerCase().includes(term);
const matchesType = (type === 'all') || (plant.tipo === type);
return matchesSearch && matchesType;
});
// 2. Applica l'ordinamento
if (sort === 'nome') {
filtered.sort((a, b) => a.nome.localeCompare(b.nome));
} else if (sort === 'difficolta') {
filtered.sort((a, b) => a.difficolta - b.difficolta);
}
renderCards(filtered);
if (speciesCount) speciesCount.innerText = filtered.length;
}
function renderCards(plants) {
if (plants.length === 0) {
container.innerHTML = `<p style="text-align:center; grid-column: 1/-1;">Nessuna pianta trovata 🌵</p>`;
return;
}
container.innerHTML = plants.map(item => `
<article class="card">
<img src="${item.immagine}" class="zoomable" alt="${item.nome}"
onerror="this.src='https://via.placeholder.com/400x250?text=Immagine+Mancante'">
<div class="card-content">
<div class="card-header-flex">
<span class="badge">${item.soprannome}</span>
<span class="tag-tipo">${item.tipo}</span>
</div>
<h3>${item.nome}</h3>
<div class="extra-info">
<p><strong>Famiglia:</strong> ${item.famiglia || 'Cactaceae'}</p>
<p><strong>Origine:</strong> ${item.origine || 'Non specificata'}</p>
</div>
<p>${item.descrizione}</p>
<div class="difficulty">
Impegno: <span class="stars">${generaStelle(item.difficolta)}</span>
</div>
</div>
</article>
`).join('');
attachZoomEvents();
}
function attachZoomEvents() {
document.querySelectorAll('.zoomable').forEach(img => {
img.onclick = () => {
fullImg.src = img.src;
caption.innerText = img.alt;
viewer.showModal();
};
});
}
// Event Listeners per i controlli
searchInput.addEventListener('input', applyFilters);
sortSelect.addEventListener('change', applyFilters);
filterType.addEventListener('change', applyFilters);
// Scroll e pulsante Top
window.onscroll = function() {
if (backToTopBtn) {
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 300) {
backToTopBtn.style.display = "block";
} else {
backToTopBtn.style.display = "none";
}
}
};
if (backToTopBtn) {
backToTopBtn.onclick = () => window.scrollTo({ top: 0, behavior: "smooth" });
}
// Chiusura Popup
closeBtn.onclick = () => viewer.close();
viewer.onclick = (e) => { if (e.target === viewer) viewer.close(); };
loadCactus();
});