MediaWiki:CRT Search.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 12: | Line 12: | ||
var filterOptions = {}; | var filterOptions = {}; | ||
var totalResults = 0; | var totalResults = 0; | ||
var totalResultsKnown = true; // Track if we know the exact count | |||
var isLoading = false; | var isLoading = false; | ||
var searchDebounceTimer = null; | var searchDebounceTimer = null; | ||
| Line 916: | Line 917: | ||
var api = new mw.Api(); | var api = new mw.Api(); | ||
// First get count | // First get count using limit=0 which returns meta.count | ||
api.get({ | api.get({ | ||
action: 'ask', | action: 'ask', | ||
query: query + '|format= | query: query + | ||
'|limit=0' + | |||
'|format=json', | |||
format: 'json' | format: 'json' | ||
}).done(function(countData) { | }).done(function(countData) { | ||
totalResults = | // Parse count from meta.count | ||
totalResults = 0; | |||
totalResultsKnown = true; | |||
if (countData.query && countData.query.meta && countData.query.meta.count !== undefined) { | |||
totalResults = parseInt(countData.query.meta.count, 10) || 0; | |||
} | |||
// Now get actual results | // Now get actual results | ||
| Line 951: | Line 960: | ||
}).fail(function(error) { | }).fail(function(error) { | ||
isLoading = false; | // Count query failed - still try to get results | ||
showError('Search failed. Please try again.'); | console.warn('Count query failed, proceeding without count:', error); | ||
totalResults = 0; | |||
totalResultsKnown = false; | |||
api.get({ | |||
action: 'ask', | |||
query: query + | |||
'|?Has image#100px=image' + | |||
'|?Has brand=brand' + | |||
'|?Has model code=model' + | |||
'|?Has CRT type=type' + | |||
'|?Has screen size inches=size' + | |||
'|?Has aspect ratio=aspect' + | |||
'|?Has TVL=tvl' + | |||
'|sort=' + sortProperty + | |||
'|order=asc' + | |||
'|limit=' + RESULTS_PER_PAGE + | |||
'|offset=' + currentOffset + | |||
'|format=json', | |||
format: 'json' | |||
}).done(function(data) { | |||
isLoading = false; | |||
displayResults(data); | |||
}).fail(function(error) { | |||
isLoading = false; | |||
showError('Search failed. Please try again.'); | |||
console.error('SMW query error:', error); | |||
}); | |||
}); | }); | ||
} | } | ||
| Line 1,023: | Line 1,058: | ||
isLoading = false; | isLoading = false; | ||
totalResults = 0; | totalResults = 0; | ||
totalResultsKnown = true; | |||
displayResults({ query: { results: {} } }); | displayResults({ query: { results: {} } }); | ||
return; | return; | ||
| Line 1,029: | Line 1,065: | ||
var matchingModelsArray = Array.from(matchingModels).sort(); | var matchingModelsArray = Array.from(matchingModels).sort(); | ||
totalResults = matchingModelsArray.length; | totalResults = matchingModelsArray.length; | ||
totalResultsKnown = true; | |||
// Check if we have additional main conditions beyond just Category:CRT models | // Check if we have additional main conditions beyond just Category:CRT models | ||
| Line 1,163: | Line 1,200: | ||
} | } | ||
return String(val); | return String(val); | ||
} | } | ||
| Line 1,230: | Line 1,231: | ||
var resultKeys = Object.keys(results); | var resultKeys = Object.keys(results); | ||
// | // Handle case where we don't know the exact total | ||
if (!totalResultsKnown || totalResults === 0) { | |||
if (totalResults === | // We got results but don't have a count | ||
// | |||
if (resultKeys.length === RESULTS_PER_PAGE) { | if (resultKeys.length === RESULTS_PER_PAGE) { | ||
totalResults = resultKeys.length + | // Full page - there might be more | ||
// Estimate based on current offset + results + 1 to indicate more | |||
totalResults = currentOffset + resultKeys.length + 1; | |||
totalResultsKnown = false; | |||
} else { | |||
// Partial page - this is all of them from this offset | |||
totalResults = currentOffset + resultKeys.length; | |||
totalResultsKnown = true; | |||
} | } | ||
} | } | ||
| Line 1,243: | Line 1,249: | ||
var startNum = currentOffset + 1; | var startNum = currentOffset + 1; | ||
var endNum = currentOffset + resultKeys.length; | var endNum = currentOffset + resultKeys.length; | ||
if ( | |||
countDiv.textContent = 'Showing ' + startNum + '–' + endNum + ' of ' + totalResults + ' CRTs'; | if (!totalResultsKnown) { | ||
countDiv.textContent = 'Showing ' + startNum + '–' + endNum + ' of ' + totalResults + '+ CRTs'; | |||
} else { | } else { | ||
endNum = Math.min(endNum, totalResults); | endNum = Math.min(endNum, totalResults); | ||
| Line 1,289: | Line 1,296: | ||
grid.classList.add('grid-view'); | grid.classList.add('grid-view'); | ||
buildPagination(); | buildPagination(resultKeys.length); | ||
} | } | ||
| Line 1,331: | Line 1,338: | ||
/** | /** | ||
* Build pagination controls | * Build pagination controls | ||
* @param {number} currentPageResultCount - Number of results on the current page | |||
*/ | */ | ||
function buildPagination() { | function buildPagination(currentPageResultCount) { | ||
var pagination = document.getElementById('pagination'); | var pagination = document.getElementById('pagination'); | ||
if ( | // No pagination needed if we have all results on one page | ||
if (currentOffset === 0 && currentPageResultCount < RESULTS_PER_PAGE && totalResultsKnown) { | |||
pagination.innerHTML = ''; | pagination.innerHTML = ''; | ||
return; | return; | ||
} | } | ||
var currentPage = Math.floor(currentOffset / RESULTS_PER_PAGE) + 1; | var currentPage = Math.floor(currentOffset / RESULTS_PER_PAGE) + 1; | ||
var html = '<div class="crt-pagination-info">'; | |||
if (totalResultsKnown && totalResults > 0) { | |||
var totalPages = Math.ceil(totalResults / RESULTS_PER_PAGE); | |||
html += 'Page ' + currentPage + ' of ' + totalPages; | |||
} else { | |||
html += 'Page ' + currentPage; | |||
} | |||
html += '</div>'; | html += '</div>'; | ||
html += '<div class="crt-pagination-buttons">'; | html += '<div class="crt-pagination-buttons">'; | ||
// Previous button | // Previous button - show if not on first page | ||
if (currentPage > 1) { | if (currentPage > 1) { | ||
html += '<button class="crt-page-btn crt-page-prev" data-offset="' + ((currentPage - 2) * RESULTS_PER_PAGE) + '">← Previous</button>'; | html += '<button class="crt-page-btn crt-page-prev" data-offset="' + ((currentPage - 2) * RESULTS_PER_PAGE) + '">← Previous</button>'; | ||
} | } | ||
// Page numbers | // Page numbers - only show if we know the total | ||
var startPage = Math.max(1, currentPage - 2); | if (totalResultsKnown && totalResults > 0) { | ||
var totalPages = Math.ceil(totalResults / RESULTS_PER_PAGE); | |||
var startPage = Math.max(1, currentPage - 2); | |||
var endPage = Math.min(totalPages, currentPage + 2); | |||
if (startPage > 1) { | |||
html += '<button class="crt-page-btn" data-offset="0">1</button>'; | |||
if (startPage > 2) html += '<span class="crt-page-ellipsis">…</span>'; | |||
} | |||
for (var i = startPage; i <= endPage; i++) { | |||
var active = i === currentPage ? ' active' : ''; | |||
html += '<button class="crt-page-btn' + active + '" data-offset="' + ((i - 1) * RESULTS_PER_PAGE) + '">' + i + '</button>'; | |||
} | |||
if (endPage < totalPages) { | |||
if (endPage < totalPages - 1) html += '<span class="crt-page-ellipsis">…</span>'; | |||
html += '<button class="crt-page-btn" data-offset="' + ((totalPages - 1) * RESULTS_PER_PAGE) + '">' + totalPages + '</button>'; | |||
} | |||
} | } | ||
// Next button | // Next button - show if we got a full page of results (there might be more) | ||
if ( | if (currentPageResultCount === RESULTS_PER_PAGE) { | ||
html += '<button class="crt-page-btn crt-page-next" data-offset="' + (currentPage * RESULTS_PER_PAGE) + '">Next →</button>'; | html += '<button class="crt-page-btn crt-page-next" data-offset="' + (currentPage * RESULTS_PER_PAGE) + '">Next →</button>'; | ||
} | } | ||