diff --git a/backend/reviews/adapters.py b/backend/reviews/adapters.py index e07863e137..2c05f8c2c9 100644 --- a/backend/reviews/adapters.py +++ b/backend/reviews/adapters.py @@ -467,6 +467,7 @@ def get_shortlist_context( all_reimbursement_categories=GrantReimbursementCategory.objects.for_conference( conference=review_session.conference ), + country_type_choices=[*Grant.CountryType.choices, ("", "Unknown")], review_session=review_session, title="Shortlist", ) diff --git a/backend/reviews/templates/grants-shortlist.html b/backend/reviews/templates/grants-shortlist.html index 7c2d883b7e..e5a3a689ee 100644 --- a/backend/reviews/templates/grants-shortlist.html +++ b/backend/reviews/templates/grants-shortlist.html @@ -452,34 +452,48 @@ }); }); - const filterByStatusInputs = [...document.querySelectorAll('input[name="filter-by-status"]')]; - filterByStatusInputs.forEach( - filterByStatusInput => { - filterByStatusInput.addEventListener('change', e => { - e.preventDefault(); - - const filterValue = e.target.value; - const visibleStatuses = filterByStatusInputs.filter( - input => input.checked - ).map( - input => input.value - ); - - document.querySelectorAll('.grant-item').forEach( - grantRow => { - const grantId = parseInt(grantRow.id.split('-')[1], 10); - const grantData = grantsById[grantId]; - - if (visibleStatuses.includes(grantData.originalStatus)) { - grantRow.classList.remove('hidden') - } else { - grantRow.classList.add('hidden') - } - } - ); - }); - } - ); + const getCheckedValues = (name) => + [...document.querySelectorAll(`input[name="${name}"]`)] + .filter(i => i.checked) + .map(i => i.value); + + // An empty checked list means the filter group is ignored (show all). + const matchesFilter = (checkedValues, rowValue) => + checkedValues.length === 0 || checkedValues.includes(rowValue); + + const applyFilters = () => { + const visibleStatuses = getCheckedValues('filter-by-status'); + const visibleNeedsFunds = getCheckedValues('filter-needs-funds-for-travel'); + const visibleNeedVisa = getCheckedValues('filter-need-visa'); + const visibleNeedAccommodation = getCheckedValues('filter-need-accommodation'); + const visibleCountryTypes = getCheckedValues('filter-country-type'); + + document.querySelectorAll('.grant-item').forEach(grantRow => { + const matches = + matchesFilter(visibleStatuses, grantRow.dataset.originalStatus) && + matchesFilter(visibleNeedsFunds, grantRow.dataset.needsFundsForTravel) && + matchesFilter(visibleNeedVisa, grantRow.dataset.needVisa) && + matchesFilter(visibleNeedAccommodation, grantRow.dataset.needAccommodation) && + matchesFilter(visibleCountryTypes, grantRow.dataset.countryType); + + grantRow.classList.toggle('hidden', !matches); + }); + }; + + [ + 'input[name="filter-by-status"]', + 'input[name="filter-needs-funds-for-travel"]', + 'input[name="filter-need-visa"]', + 'input[name="filter-need-accommodation"]', + 'input[name="filter-country-type"]', + ].forEach(selector => { + document.querySelectorAll(selector).forEach(input => { + input.addEventListener('change', applyFilters); + }); + }); + + // Sync visible rows with any restored checkbox state (e.g. bfcache back-nav). + applyFilters(); @@ -663,6 +677,56 @@