This commit is contained in:
+269
-2
@@ -357,6 +357,31 @@
|
||||
.scrollable-table-body {
|
||||
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
/* Стили для подсветки результатов поиска */
|
||||
.search-highlight {
|
||||
background-color: #fff3cd !important;
|
||||
border-left: 4px solid #ffc107 !important;
|
||||
animation: searchPulse 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes searchPulse {
|
||||
0% { background-color: #fff3cd; }
|
||||
50% { background-color: #ffeaa7; }
|
||||
100% { background-color: #fff3cd; }
|
||||
}
|
||||
|
||||
/* Стили для полей поиска */
|
||||
.input-group .form-control:focus {
|
||||
border-color: #86b7fe;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
}
|
||||
|
||||
.input-group .btn-outline-secondary:hover {
|
||||
background-color: #6c757d;
|
||||
border-color: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -444,7 +469,16 @@
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">Список постов</h5>
|
||||
<div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="input-group me-2" style="width: 200px;">
|
||||
<input type="text" class="form-control form-control-sm" id="posts-search" placeholder="Поиск...">
|
||||
<button class="btn btn-outline-secondary btn-sm" type="button" id="posts-search-prev">
|
||||
<i class="fas fa-chevron-up"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" type="button" id="posts-search-next">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-success" id="add-post-btn">
|
||||
<i class="fas fa-plus"></i> Добавить
|
||||
</button>
|
||||
@@ -528,7 +562,16 @@
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">Список событий</h5>
|
||||
<div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="input-group me-2" style="width: 200px;">
|
||||
<input type="text" class="form-control form-control-sm" id="events-search" placeholder="Поиск...">
|
||||
<button class="btn btn-outline-secondary btn-sm" type="button" id="events-search-prev">
|
||||
<i class="fas fa-chevron-up"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" type="button" id="events-search-next">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-success" id="add-event-btn-sm">
|
||||
<i class="fas fa-plus"></i> Добавить
|
||||
</button>
|
||||
@@ -3034,6 +3077,230 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
alert('Ошибка при сохранении изменений');
|
||||
}
|
||||
});
|
||||
|
||||
// Функции поиска
|
||||
let postsSearchResults = [];
|
||||
let eventsSearchResults = [];
|
||||
let currentPostsSearchIndex = -1;
|
||||
let currentEventsSearchIndex = -1;
|
||||
|
||||
// Поиск по постам
|
||||
function searchPosts(query) {
|
||||
if (!query.trim()) {
|
||||
postsSearchResults = [];
|
||||
currentPostsSearchIndex = -1;
|
||||
clearPostsSearchHighlight();
|
||||
return;
|
||||
}
|
||||
|
||||
const posts = document.querySelectorAll('.post-row');
|
||||
postsSearchResults = [];
|
||||
|
||||
posts.forEach((post, index) => {
|
||||
const postId = post.dataset.id;
|
||||
const shortname = post.querySelector('.shortname-preview')?.textContent || '';
|
||||
const textPreview = post.querySelector('.post-text-preview')?.textContent || '';
|
||||
|
||||
const searchText = `${shortname} ${textPreview}`.toLowerCase();
|
||||
if (searchText.includes(query.toLowerCase())) {
|
||||
postsSearchResults.push({
|
||||
element: post,
|
||||
index: index,
|
||||
id: postId
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
currentPostsSearchIndex = postsSearchResults.length > 0 ? 0 : -1;
|
||||
highlightSearchResults('posts');
|
||||
}
|
||||
|
||||
// Поиск по событиям (расширенный с тэгами)
|
||||
async function searchEvents(query) {
|
||||
if (!query.trim()) {
|
||||
eventsSearchResults = [];
|
||||
currentEventsSearchIndex = -1;
|
||||
clearEventsSearchHighlight();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Получаем все события из API для поиска по тэгам
|
||||
const response = await fetch(`${PREFIX}/api/events`);
|
||||
const allEvents = await response.json();
|
||||
|
||||
const events = document.querySelectorAll('.event-row');
|
||||
eventsSearchResults = [];
|
||||
|
||||
events.forEach((event, index) => {
|
||||
const eventId = event.dataset.id;
|
||||
const name = event.querySelector('.event-name-preview')?.textContent || '';
|
||||
const unitName = event.querySelector('.shortname-preview')?.textContent || '';
|
||||
|
||||
// Находим полные данные события для поиска по тэгам
|
||||
const eventData = allEvents.find(e => e.id == eventId);
|
||||
const tags = eventData?.tags || '';
|
||||
|
||||
const searchText = `${name} ${unitName} ${tags}`.toLowerCase();
|
||||
if (searchText.includes(query.toLowerCase())) {
|
||||
eventsSearchResults.push({
|
||||
element: event,
|
||||
index: index,
|
||||
id: eventId
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
currentEventsSearchIndex = eventsSearchResults.length > 0 ? 0 : -1;
|
||||
highlightSearchResults('events');
|
||||
} catch (error) {
|
||||
console.error('Ошибка при поиске событий:', error);
|
||||
// Fallback к простому поиску без тэгов
|
||||
searchEventsSimple(query);
|
||||
}
|
||||
}
|
||||
|
||||
// Простой поиск по событиям (без тэгов)
|
||||
function searchEventsSimple(query) {
|
||||
const events = document.querySelectorAll('.event-row');
|
||||
eventsSearchResults = [];
|
||||
|
||||
events.forEach((event, index) => {
|
||||
const eventId = event.dataset.id;
|
||||
const name = event.querySelector('.event-name-preview')?.textContent || '';
|
||||
const unitName = event.querySelector('.shortname-preview')?.textContent || '';
|
||||
|
||||
const searchText = `${name} ${unitName}`.toLowerCase();
|
||||
if (searchText.includes(query.toLowerCase())) {
|
||||
eventsSearchResults.push({
|
||||
element: event,
|
||||
index: index,
|
||||
id: eventId
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
currentEventsSearchIndex = eventsSearchResults.length > 0 ? 0 : -1;
|
||||
highlightSearchResults('events');
|
||||
}
|
||||
|
||||
// Подсветка результатов поиска
|
||||
function highlightSearchResults(type) {
|
||||
if (type === 'posts') {
|
||||
clearPostsSearchHighlight();
|
||||
if (currentPostsSearchIndex >= 0 && currentPostsSearchIndex < postsSearchResults.length) {
|
||||
const result = postsSearchResults[currentPostsSearchIndex];
|
||||
result.element.classList.add('search-highlight');
|
||||
result.element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
|
||||
// Выделяем найденный пост
|
||||
highlightSelectedPost(result.id);
|
||||
}
|
||||
} else if (type === 'events') {
|
||||
clearEventsSearchHighlight();
|
||||
if (currentEventsSearchIndex >= 0 && currentEventsSearchIndex < eventsSearchResults.length) {
|
||||
const result = eventsSearchResults[currentEventsSearchIndex];
|
||||
result.element.classList.add('search-highlight');
|
||||
result.element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
|
||||
// Выделяем найденное событие
|
||||
highlightSelectedEvent(result.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Очистка подсветки поиска постов
|
||||
function clearPostsSearchHighlight() {
|
||||
document.querySelectorAll('.post-row.search-highlight').forEach(row => {
|
||||
row.classList.remove('search-highlight');
|
||||
});
|
||||
}
|
||||
|
||||
// Очистка подсветки поиска событий
|
||||
function clearEventsSearchHighlight() {
|
||||
document.querySelectorAll('.event-row.search-highlight').forEach(row => {
|
||||
row.classList.remove('search-highlight');
|
||||
});
|
||||
}
|
||||
|
||||
// Навигация по результатам поиска постов
|
||||
function navigatePostsSearch(direction) {
|
||||
if (postsSearchResults.length === 0) return;
|
||||
|
||||
if (direction === 'next') {
|
||||
currentPostsSearchIndex = (currentPostsSearchIndex + 1) % postsSearchResults.length;
|
||||
} else if (direction === 'prev') {
|
||||
currentPostsSearchIndex = currentPostsSearchIndex <= 0 ? postsSearchResults.length - 1 : currentPostsSearchIndex - 1;
|
||||
}
|
||||
|
||||
highlightSearchResults('posts');
|
||||
}
|
||||
|
||||
// Навигация по результатам поиска событий
|
||||
function navigateEventsSearch(direction) {
|
||||
if (eventsSearchResults.length === 0) return;
|
||||
|
||||
if (direction === 'next') {
|
||||
currentEventsSearchIndex = (currentEventsSearchIndex + 1) % eventsSearchResults.length;
|
||||
} else if (direction === 'prev') {
|
||||
currentEventsSearchIndex = currentEventsSearchIndex <= 0 ? eventsSearchResults.length - 1 : currentEventsSearchIndex - 1;
|
||||
}
|
||||
|
||||
highlightSearchResults('events');
|
||||
}
|
||||
|
||||
// Обработчики событий для поиска постов
|
||||
document.getElementById('posts-search').addEventListener('input', (e) => {
|
||||
searchPosts(e.target.value);
|
||||
});
|
||||
|
||||
document.getElementById('posts-search-prev').addEventListener('click', () => {
|
||||
navigatePostsSearch('prev');
|
||||
});
|
||||
|
||||
document.getElementById('posts-search-next').addEventListener('click', () => {
|
||||
navigatePostsSearch('next');
|
||||
});
|
||||
|
||||
// Обработчики событий для поиска событий
|
||||
document.getElementById('events-search').addEventListener('input', (e) => {
|
||||
searchEvents(e.target.value);
|
||||
});
|
||||
|
||||
document.getElementById('events-search-prev').addEventListener('click', () => {
|
||||
navigateEventsSearch('prev');
|
||||
});
|
||||
|
||||
document.getElementById('events-search-next').addEventListener('click', () => {
|
||||
navigateEventsSearch('next');
|
||||
});
|
||||
|
||||
// Обработчики клавиш для поиска
|
||||
document.getElementById('posts-search').addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
navigatePostsSearch('next');
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
navigatePostsSearch('prev');
|
||||
} else if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
navigatePostsSearch('next');
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('events-search').addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
navigateEventsSearch('next');
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
navigateEventsSearch('prev');
|
||||
} else if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
navigateEventsSearch('next');
|
||||
}
|
||||
});
|
||||
});
|
||||
// Убедимся, что функция доступна глобально, если потребуется вызвать из HTML
|
||||
window.resetLayout = resetLayout;
|
||||
|
||||
Reference in New Issue
Block a user