improved dynamic scrolling + fixed bug for dynamic scrolling not working when not enough results
This commit is contained in:
parent
a5221039f4
commit
488c55dd92
3 changed files with 100 additions and 116 deletions
96
static/js/dynamicscrolling.js
Normal file
96
static/js/dynamicscrolling.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
const templateData = document.getElementById('template-data');
|
||||||
|
let page = parseInt(templateData.getAttribute('data-page')) || 1;
|
||||||
|
const query = templateData.getAttribute('data-query') || '';
|
||||||
|
let searchType = templateData.getAttribute('data-type') || 'text'; // Default to 'text' if not provided
|
||||||
|
let loading = false;
|
||||||
|
let hasMoreResults = true;
|
||||||
|
const loadingIndicator = document.getElementById('message-bottom-left');
|
||||||
|
let loadingTimeout;
|
||||||
|
|
||||||
|
function loadResults(newPage) {
|
||||||
|
if (loading || !hasMoreResults) return;
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
// Show loading indicator if taking more than 100ms
|
||||||
|
loadingTimeout = setTimeout(() => {
|
||||||
|
loadingIndicator.style.display = 'flex';
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
fetch(`/search?q=${encodeURIComponent(query)}&t=${encodeURIComponent(searchType)}&p=${newPage}`)
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
clearTimeout(loadingTimeout);
|
||||||
|
loadingIndicator.style.display = 'none';
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(data, 'text/html');
|
||||||
|
const newResults = doc.getElementById('results').innerHTML;
|
||||||
|
const noResultsMessage = `No results found for '${query}'. Try different keywords.`;
|
||||||
|
const endOfResultsMessage = "Looks like this is the end of results.";
|
||||||
|
const serverError = "Internal Server Error";
|
||||||
|
|
||||||
|
if (newResults.includes(noResultsMessage) || newResults.includes(endOfResultsMessage) || newResults.includes(serverError)) {
|
||||||
|
document.getElementById('results').innerHTML += newResults;
|
||||||
|
hasMoreResults = false;
|
||||||
|
} else {
|
||||||
|
document.getElementById('results').innerHTML += newResults;
|
||||||
|
page = newPage;
|
||||||
|
// Automatically load more results if content height is less than window height
|
||||||
|
checkIfMoreResultsNeeded();
|
||||||
|
}
|
||||||
|
loading = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
clearTimeout(loadingTimeout);
|
||||||
|
loadingIndicator.style.display = 'none';
|
||||||
|
console.error('Error loading results:', error);
|
||||||
|
hasMoreResults = false;
|
||||||
|
loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIfMoreResultsNeeded() {
|
||||||
|
if (document.body.scrollHeight <= window.innerHeight && hasMoreResults) {
|
||||||
|
loadResults(page + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
||||||
|
loadResults(page + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure the correct search button has the active class at load
|
||||||
|
const buttons = document.querySelectorAll('.search-container-results-btn button');
|
||||||
|
if (buttons.length === 0) {
|
||||||
|
console.error("No search buttons found");
|
||||||
|
} else {
|
||||||
|
buttons.forEach(btn => {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
const activeElement = document.querySelector('.search-container-results-btn .search-active');
|
||||||
|
if (activeElement) {
|
||||||
|
activeElement.classList.remove('search-active');
|
||||||
|
}
|
||||||
|
this.classList.add('search-active');
|
||||||
|
// Update search type when button is clicked
|
||||||
|
searchType = this.getAttribute('value');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure one button is active on page load
|
||||||
|
const initialActiveElement = document.querySelector('.search-container-results-btn .search-active');
|
||||||
|
if (!initialActiveElement) {
|
||||||
|
buttons[0].classList.add('search-active');
|
||||||
|
searchType = buttons[0].getAttribute('value'); // Set default search type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if more results are needed right after the initial content is loaded
|
||||||
|
checkIfMoreResultsNeeded();
|
||||||
|
});
|
|
@ -108,70 +108,12 @@
|
||||||
<div class="message-bottom-left" id="message-bottom-left">
|
<div class="message-bottom-left" id="message-bottom-left">
|
||||||
<span>Searching for new results...</span>
|
<span>Searching for new results...</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="template-data" data-page="{{ .Page }}" data-query="{{ .Query }}" data-type="image"></div>
|
||||||
|
<script defer src="/static/js/dynamicscrolling.js"></script>
|
||||||
<script defer src="/static/js/autocomplete.js"></script>
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
</script>
|
</script>
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
let page = {{ .Page }};
|
|
||||||
const query = "{{ .Query }}";
|
|
||||||
let loading = false;
|
|
||||||
let hasMoreResults = true;
|
|
||||||
const loadingIndicator = document.getElementById('message-bottom-left');
|
|
||||||
let loadingTimeout;
|
|
||||||
|
|
||||||
function loadResults(newPage) {
|
|
||||||
if (loading || !hasMoreResults) return;
|
|
||||||
loading = true;
|
|
||||||
|
|
||||||
// Show loading indicator if taking more than 100ms
|
|
||||||
loadingTimeout = setTimeout(() => {
|
|
||||||
loadingIndicator.style.display = 'flex';
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
fetch(`/search?q=${encodeURIComponent(query)}&t=image&p=${newPage}`)
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network response was not ok');
|
|
||||||
}
|
|
||||||
return response.text();
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
clearTimeout(loadingTimeout);
|
|
||||||
loadingIndicator.style.display = 'none';
|
|
||||||
const parser = new DOMParser();
|
|
||||||
const doc = parser.parseFromString(data, 'text/html');
|
|
||||||
const newResults = doc.getElementById('results').innerHTML;
|
|
||||||
const noResultsMessage = "No results found for '{{ .Query }}'. Try different keywords.";
|
|
||||||
const endOfResultsMessage = "Looks like this is the end of results.";
|
|
||||||
const serverError = "Internal Server Error";
|
|
||||||
|
|
||||||
if (newResults.includes(noResultsMessage) || newResults.includes(endOfResultsMessage) || newResults.includes(serverError)) {
|
|
||||||
document.getElementById('results').innerHTML += newResults;
|
|
||||||
hasMoreResults = false;
|
|
||||||
} else {
|
|
||||||
document.getElementById('results').innerHTML += newResults;
|
|
||||||
page = newPage;
|
|
||||||
}
|
|
||||||
loading = false;
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
clearTimeout(loadingTimeout);
|
|
||||||
loadingIndicator.style.display = 'none';
|
|
||||||
console.error('Error loading results:', error);
|
|
||||||
hasMoreResults = false; // Stop further attempts
|
|
||||||
loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
|
||||||
loadResults(page + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -96,66 +96,12 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="template-data" data-page="{{ .Page }}" data-query="{{ .Query }}" data-type="text"></div>
|
||||||
|
<script defer src="/static/js/dynamicscrolling.js"></script>
|
||||||
<script defer src="/static/js/autocomplete.js"></script>
|
<script defer src="/static/js/autocomplete.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
</script>
|
</script>
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
if (document.getElementById('prev-next')) {
|
|
||||||
document.getElementById('prev-next').style.display = 'none';
|
|
||||||
|
|
||||||
let page = {{ .Page }};
|
|
||||||
const query = "{{ .Query }}";
|
|
||||||
let loading = false;
|
|
||||||
let hasMoreResults = true;
|
|
||||||
const loadingIndicator = document.getElementById('message-bottom-left');
|
|
||||||
let loadingTimeout;
|
|
||||||
|
|
||||||
function loadResults(newPage) {
|
|
||||||
if (loading || !hasMoreResults) return;
|
|
||||||
loading = true;
|
|
||||||
|
|
||||||
// Show loading indicator if taking more than 100ms
|
|
||||||
loadingTimeout = setTimeout(() => {
|
|
||||||
loadingIndicator.style.display = 'flex';
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
fetch(`/search?q=${encodeURIComponent(query)}&t=text&p=${newPage}`)
|
|
||||||
.then(response => response.text())
|
|
||||||
.then(data => {
|
|
||||||
clearTimeout(loadingTimeout);
|
|
||||||
loadingIndicator.style.display = 'none';
|
|
||||||
const parser = new DOMParser();
|
|
||||||
const doc = parser.parseFromString(data, 'text/html');
|
|
||||||
const newResults = doc.getElementById('results').innerHTML;
|
|
||||||
const noResultsMessage = "No results found for '{{ .Query }}'. Try different keywords.";
|
|
||||||
|
|
||||||
if (newResults.includes(noResultsMessage)) {
|
|
||||||
document.getElementById('results').innerHTML += "<div class='no-more-results'>Looks like this is the end of results.</div>";
|
|
||||||
hasMoreResults = false;
|
|
||||||
} else {
|
|
||||||
document.getElementById('results').innerHTML += newResults;
|
|
||||||
page = newPage;
|
|
||||||
}
|
|
||||||
loading = false;
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
clearTimeout(loadingTimeout);
|
|
||||||
loadingIndicator.style.display = 'none';
|
|
||||||
console.error('Error loading results:', error);
|
|
||||||
loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
|
||||||
loadResults(page + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Reference in a new issue