add search functionality
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
// Update search function with fallback animation
|
||||
function handleSearch() {
|
||||
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
|
||||
const topicCards = document.querySelectorAll('.topic-card');
|
||||
|
||||
topicCards.forEach(card => {
|
||||
const title = card.querySelector('.topic-title')?.textContent.toLowerCase() || '';
|
||||
const description = card.querySelector('.topic-description')?.textContent.toLowerCase() || '';
|
||||
const relatedTopics = Array.from(card.querySelectorAll('.related-topics li'))
|
||||
.map(li => li.textContent.toLowerCase())
|
||||
.join(' ');
|
||||
|
||||
const content = `${title} ${description} ${relatedTopics}`;
|
||||
|
||||
if (content.includes(searchTerm)) {
|
||||
card.style.display = 'block';
|
||||
if (window.gsap) {
|
||||
gsap.to(card, {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.3
|
||||
});
|
||||
} else {
|
||||
card.style.opacity = 1;
|
||||
card.style.transform = 'translateY(0)';
|
||||
}
|
||||
} else {
|
||||
card.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -17,12 +17,11 @@
|
||||
|
||||
<!-- Login/Logout Button -->
|
||||
<div class="flex items-center space-x-4">
|
||||
<!-- Search Bar TODO: Implement search functionality -->
|
||||
<form action="search.php" method="GET" class="relative flex items-center">
|
||||
<input type="text" name="query" placeholder="Suche..."
|
||||
class="w-64 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--primary-color)] pl-10">
|
||||
<i class="fas fa-search absolute left-3 text-gray-400"></i>
|
||||
</form>
|
||||
<!-- Search Button -->
|
||||
<button id="openSearchDialog"
|
||||
class="bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
|
||||
<?php
|
||||
require_once("classes/User.php");
|
||||
@@ -31,21 +30,26 @@
|
||||
?>
|
||||
<div class="relative">
|
||||
<!-- Dropdown Trigger -->
|
||||
<button id="userDropdownToggle" class="bg-[var(--primary-color)] text-white px-4 py-2 rounded-lg hover:bg-[var(--accent-color)] transition duration-300 flex items-center">
|
||||
<button id="userDropdownToggle"
|
||||
class="bg-[var(--primary-color)] text-white px-4 py-2 rounded-lg hover:bg-[var(--accent-color)] transition duration-300 flex items-center">
|
||||
<span><?php echo htmlspecialchars($_SESSION['user']->getUsername()); ?></span>
|
||||
<i class="fas fa-chevron-down ml-2"></i>
|
||||
</button>
|
||||
|
||||
<!-- Dropdown Menu -->
|
||||
<div id="userDropdownMenu" class="hidden absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border">
|
||||
<a href="account.php" class="block px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-t-lg flex items-center">
|
||||
<div id="userDropdownMenu"
|
||||
class="hidden absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border">
|
||||
<a href="account.php"
|
||||
class="block px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-t-lg flex items-center">
|
||||
<i class="fas fa-user mr-2"></i> Accountseite
|
||||
</a>
|
||||
<button id="dropdownChangePasswordButton" class="block w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100 flex items-center">
|
||||
<button id="dropdownChangePasswordButton"
|
||||
class="block w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100 flex items-center">
|
||||
<i class="fas fa-key mr-2"></i> Passwort ändern
|
||||
</button>
|
||||
<form id="dropdownLogoutForm" action="logout.php" method="POST" class="block">
|
||||
<button type="submit" class="w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-b-lg flex items-center">
|
||||
<button type="submit"
|
||||
class="w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-b-lg flex items-center">
|
||||
<i class="fas fa-sign-out-alt mr-2"></i> Logout
|
||||
</button>
|
||||
</form>
|
||||
@@ -102,7 +106,8 @@ if (!isset($_SESSION['user']) || !$_SESSION['user']->isLoggedIn()) {
|
||||
<?php
|
||||
if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||
?>
|
||||
<div id="changePasswordPopup" class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50" role="dialog"
|
||||
<div id="changePasswordPopup" class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50"
|
||||
role="dialog"
|
||||
aria-labelledby="changePasswordTitle" aria-hidden="true">
|
||||
<div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-sm relative">
|
||||
<button id="closeChangePasswordPopupButton" class="absolute top-2 right-2 text-gray-500 text-xl"
|
||||
@@ -112,15 +117,18 @@ if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||
<form id="changePasswordForm" action="password.php" method="POST">
|
||||
<div class="mb-4">
|
||||
<label for="currentPassword" class="block text-gray-700 mb-2">Aktuelles Passwort:</label>
|
||||
<input type="password" id="currentPassword" name="currentPassword" class="w-full p-2 border rounded-lg" required>
|
||||
<input type="password" id="currentPassword" name="currentPassword"
|
||||
class="w-full p-2 border rounded-lg" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="newPassword" class="block text-gray-700 mb-2">Neues Passwort:</label>
|
||||
<input type="password" id="newPassword" name="newPassword" class="w-full p-2 border rounded-lg" required>
|
||||
<input type="password" id="newPassword" name="newPassword" class="w-full p-2 border rounded-lg"
|
||||
required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="confirmNewPassword" class="block text-gray-700 mb-2">Neues Passwort bestätigen:</label>
|
||||
<input type="password" id="confirmNewPassword" name="confirmNewPassword" class="w-full p-2 border rounded-lg" required>
|
||||
<input type="password" id="confirmNewPassword" name="confirmNewPassword"
|
||||
class="w-full p-2 border rounded-lg" required>
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="w-full bg-[var(--primary-color)] text-white px-4 py-2 rounded-lg hover:bg-[var(--accent-color)] transition duration-300">
|
||||
@@ -145,6 +153,16 @@ if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search Dialog -->
|
||||
<div id="searchDialog" class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
||||
<div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-lg relative">
|
||||
<button id="closeSearchDialog" class="absolute top-2 right-2 text-gray-500 text-xl">×</button>
|
||||
<h2 class="text-2xl font-bold mb-6 text-center">Suche</h2>
|
||||
<input type="text" id="searchInput" placeholder="Search..." class="w-full p-2 border rounded-lg mb-4">
|
||||
<div id="searchResults" class="max-h-64 overflow-y-auto"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// JavaScript to handle opening and closing of the login popup
|
||||
const loginButton = document.getElementById('loginButton');
|
||||
@@ -189,7 +207,6 @@ if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||
});
|
||||
|
||||
|
||||
|
||||
// JavaScript to handle opening and closing of the change password popup
|
||||
const changePasswordButton = document.getElementById('changePasswordButton');
|
||||
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
||||
@@ -304,5 +321,62 @@ if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||
}
|
||||
});
|
||||
}
|
||||
document.getElementById('openSearchDialog').addEventListener('click', function () {
|
||||
document.getElementById('searchDialog').classList.remove('hidden');
|
||||
});
|
||||
|
||||
document.getElementById('closeSearchDialog').addEventListener('click', function () {
|
||||
document.getElementById('searchDialog').classList.add('hidden');
|
||||
});
|
||||
|
||||
function debounce(func, delay) {
|
||||
let debounceTimer;
|
||||
return function () {
|
||||
const context = this;
|
||||
const args = arguments;
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(() => func.apply(context, args), delay);
|
||||
};
|
||||
}
|
||||
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
const resultsContainer = document.getElementById('searchResults');
|
||||
|
||||
searchInput.addEventListener('input', debounce(function () {
|
||||
const query = this.value.toLowerCase();
|
||||
resultsContainer.innerHTML = '';
|
||||
|
||||
if (query.length > 0) {
|
||||
fetch('search.php?query=' + query)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.forEach(item => {
|
||||
const resultItem = document.createElement('div');
|
||||
resultItem.classList.add('p-4', 'mb-2', 'rounded-lg', 'bg-white', 'hover:bg-gray-100', 'transition', 'duration-100', 'flex', 'items-center', 'space-x-2', 'cursor-pointer');
|
||||
|
||||
const subjectSpan = document.createElement('span');
|
||||
subjectSpan.classList.add('font-bold');
|
||||
subjectSpan.textContent = item.displayName.split(' - ')[0];
|
||||
|
||||
const breadcrumbSpan = document.createElement('span');
|
||||
breadcrumbSpan.classList.add('text-gray-500');
|
||||
breadcrumbSpan.textContent = item.displayName.split(' - ').slice(1).join(' > ');
|
||||
|
||||
resultItem.appendChild(subjectSpan);
|
||||
resultItem.appendChild(breadcrumbSpan);
|
||||
|
||||
resultItem.addEventListener('click', function () {
|
||||
if (item.type === 'subject') {
|
||||
window.location.href = 'subject.php?subject=' + item.id;
|
||||
} else {
|
||||
window.location.href = 'topic.php?subject=' + item.subjectId + '&topic=' + item.id;
|
||||
}
|
||||
});
|
||||
|
||||
resultsContainer.appendChild(resultItem);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, 300));
|
||||
|
||||
</script>
|
||||
|
||||
40
webseite/search.php
Normal file
40
webseite/search.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
require_once("classes/SubjectData.php");
|
||||
require_once("classes/TopicData.php");
|
||||
|
||||
if (!isset($_GET['query'])) {
|
||||
die(json_encode([]));
|
||||
}
|
||||
|
||||
$query = strtolower(trim($_GET['query']));
|
||||
$subjects = SubjectData::getAll();
|
||||
$results = [];
|
||||
|
||||
foreach ($subjects as $subject) {
|
||||
if (strpos(strtolower($subject->displayName), $query) !== false) {
|
||||
$results[] = [
|
||||
'type' => 'subject',
|
||||
'id' => $subject->id,
|
||||
'displayName' => $subject->displayName
|
||||
];
|
||||
}
|
||||
foreach ($subject->topics as $topic) {
|
||||
if (
|
||||
strpos(strtolower($subject->displayName), $query) !== false ||
|
||||
strpos(strtolower($topic->displayName), $query) !== false ||
|
||||
strpos(strtolower($topic->description), $query) !== false ||
|
||||
strpos(strtolower($topic->article), $query) !== false
|
||||
) {
|
||||
$results[] = [
|
||||
'type' => 'topic',
|
||||
'subjectId' => $topic->subjectId,
|
||||
'id' => $topic->id,
|
||||
'displayName' => $subject->displayName . ' - ' . $topic->displayName
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($results);
|
||||
?>
|
||||
Reference in New Issue
Block a user