Add general search and refactor header
This commit is contained in:
@@ -356,4 +356,12 @@ $('#switchDarkmode').click(function (event) {
|
||||
$(this).find('.fa-moon').removeClass('far').addClass('fa');
|
||||
$(this).attr('data-title', 'Dark Theme')
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function addSnackbar(type, text) {
|
||||
const snackbar = $(`<div class="alert alert-${type} snackbar" role="alert" >${text}</div>`);
|
||||
$('.snackbar-container').append(snackbar);
|
||||
setTimeout(() => {
|
||||
snackbar.remove();
|
||||
}, 5500);
|
||||
}
|
158
assets/js/search.js
Normal file
158
assets/js/search.js
Normal file
@@ -0,0 +1,158 @@
|
||||
let offset = 0;
|
||||
let query;
|
||||
let searching = {query: null, offset: 0, filters: []};
|
||||
const filters = [];
|
||||
let moreAvailable = true;
|
||||
|
||||
let executing = false;
|
||||
|
||||
function loadSearchResults() {
|
||||
if (executing) {
|
||||
setTimeout(() => loadSearchResults(), 100);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!query || query.trim().length < 3) {
|
||||
$('.loadingSpinner').hide();
|
||||
$('.error-container .message').hide();
|
||||
$('.error-container .message-search-term').show();
|
||||
$('.error-container').show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (searching.query === query && (searching.offset === offset || !moreAvailable) && searching.filters.length === filters.length) {
|
||||
$('.loadingSpinner').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (query !== searching.query || searching.filters.length !== filters.length) {
|
||||
offset = 0;
|
||||
$('#searchResults').empty();
|
||||
}
|
||||
|
||||
$('.error-container').hide();
|
||||
$('.loadingSpinner').show();
|
||||
|
||||
console.log('executing with ', query);
|
||||
|
||||
searching = {
|
||||
query,
|
||||
offset,
|
||||
filters: filters.slice()
|
||||
};
|
||||
|
||||
executing = true;
|
||||
$.ajax({
|
||||
url: '/search/getSearchResults',
|
||||
method: 'POST',
|
||||
data: searching,
|
||||
success: data => {
|
||||
$('.loadingSpinner').hide();
|
||||
|
||||
if (data.error) {
|
||||
$('.error-container').show();
|
||||
$('.error-container .message').hide();
|
||||
$('.error-container .message-' + data.message).show();
|
||||
moreAvailable = false;
|
||||
} else {
|
||||
const searchResults = $('#searchResults');
|
||||
data.forEach(item => {
|
||||
searchResults.append(`
|
||||
<li class="card mb-2">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<a href="${item.url}">
|
||||
<span class="badge badge-primary">
|
||||
${item.type}
|
||||
</span>
|
||||
${item.title}
|
||||
</a>
|
||||
</h5>
|
||||
<h6 class="card-subtitle mb-2 text-muted">
|
||||
<i class="fa fa-clock"></i> ${item.date}
|
||||
${item.showUser ? `
|
||||
-
|
||||
<a href="${item.authorUrl}" target="_blank">
|
||||
<i class="fa fa-user"></i> ${item.username}
|
||||
</a>
|
||||
` : ''}
|
||||
</h6>
|
||||
|
||||
${!!item.content ? `
|
||||
<p class="card-text">${item.content}</p>
|
||||
` : ''}
|
||||
</div>
|
||||
</li>
|
||||
`);
|
||||
});
|
||||
|
||||
registerScrollEvent();
|
||||
|
||||
if (data.length < 5)
|
||||
moreAvailable = false;
|
||||
}
|
||||
executing = false;
|
||||
},
|
||||
error: data => {
|
||||
console.log(data);
|
||||
$('.col').append(data.responseText);
|
||||
$('.loadingSpinner').hide();
|
||||
|
||||
$('.error-container .message').hide();
|
||||
$('.error-container .message-general').show();
|
||||
$('.error-container').show();
|
||||
|
||||
executing = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
query = $('#searchTerm').val();
|
||||
loadSearchResults();
|
||||
});
|
||||
|
||||
let timeout;
|
||||
$('#searchTerm').on('change keyup', function () {
|
||||
query = $(this).val();
|
||||
const url = window.location.pathname + '?q=' + encodeURI(query);
|
||||
const title = document.title.split('-')[0] + ' ' + query + ' ' + document.title.split('|')[1];
|
||||
window.history.replaceState('', title, url);
|
||||
document.title = title;
|
||||
moreAvailable = true;
|
||||
|
||||
startTimeout();
|
||||
});
|
||||
|
||||
$('.filter > .list-group-item-action').on('click', function () {
|
||||
$(this).toggleClass('active');
|
||||
|
||||
if ($(this).hasClass('active')) {
|
||||
filters.push($(this).data('filter'));
|
||||
} else {
|
||||
filters.splice(filters.indexOf($(this).data('filter')), 1);
|
||||
}
|
||||
|
||||
moreAvailable = true;
|
||||
|
||||
clearTimeout(timeout);
|
||||
loadSearchResults();
|
||||
});
|
||||
|
||||
function startTimeout() {
|
||||
clearTimeout(timeout);
|
||||
setTimeout(() => loadSearchResults(), 500);
|
||||
}
|
||||
|
||||
function registerScrollEvent() {
|
||||
const list = $('#searchResults');
|
||||
$(window).scroll(function () {
|
||||
if (!moreAvailable || executing)
|
||||
return;
|
||||
|
||||
if ($(document).scrollTop() + 360 + $(window).height() >= list.position().top + list.outerHeight()) {
|
||||
offset++;
|
||||
loadSearchResults();
|
||||
}
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user