Skip to content

Commit 4f1a12d

Browse files
Refine attorney directory filters (#1654)
* Refine attorney directory filters * Update style.scss --------- Co-authored-by: hushline-dev <git-dev@scidsg.org>
1 parent d3b2ec7 commit 4f1a12d

File tree

7 files changed

+588
-135
lines changed

7 files changed

+588
-135
lines changed

assets/js/directory_verified.js

Lines changed: 191 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ document.addEventListener("DOMContentLoaded", function () {
77
const clearIcon = document.getElementById("clearIcon");
88
const searchStatus = document.getElementById("directory-search-status");
99
const publicRecordCountBadge = document.getElementById("public-record-count");
10+
const attorneyFiltersToggleShell = document.getElementById("attorney-filters-toggle-shell");
11+
const attorneyFiltersPanelShell = document.getElementById("attorney-filters-panel-shell");
1012
const attorneyFiltersToggle = document.getElementById("attorney-filters-toggle");
1113
const attorneyFiltersPanel = document.getElementById("attorney-filters-panel");
1214
const attorneyCountryFilter = document.getElementById("attorney-country-filter");
@@ -42,6 +44,18 @@ document.addEventListener("DOMContentLoaded", function () {
4244
attorneyFiltersToggle.textContent = isExpanded ? "Hide Filters" : "Show Filters";
4345
}
4446

47+
function updateAttorneyFilterVisibility() {
48+
const attorneyTabIsActive = activeTabName() === "public-records";
49+
50+
if (attorneyFiltersToggleShell) {
51+
attorneyFiltersToggleShell.hidden = !attorneyTabIsActive;
52+
}
53+
54+
if (attorneyFiltersPanelShell) {
55+
attorneyFiltersPanelShell.hidden = !attorneyTabIsActive;
56+
}
57+
}
58+
4559
function activeTabName() {
4660
return document.querySelector(".tab.active")?.getAttribute("data-tab") || "all";
4761
}
@@ -431,11 +445,16 @@ document.addEventListener("DOMContentLoaded", function () {
431445
const params = new URLSearchParams(search);
432446
attorneyCountryFilter.value = params.get("country") || "";
433447
attorneyRegionFilter.value = params.get("region") || "";
448+
if (!attorneyCountryFilter.value && attorneyRegionFilter.value) {
449+
attorneyCountryFilter.value = inferredCountryForRegionCode(attorneyRegionFilter.value);
450+
}
451+
updateAttorneyCountryLabels();
434452
updateAttorneyRegionOptions();
435453

436454
if (attorneyFiltersPanel) {
437455
attorneyFiltersPanel.hidden = !(attorneyCountryFilter.value || attorneyRegionFilter.value);
438456
updateAttorneyFiltersToggle();
457+
updateAttorneyFiltersClearVisibility();
439458
}
440459
}
441460

@@ -456,48 +475,164 @@ document.addEventListener("DOMContentLoaded", function () {
456475
attorneyRegionFilter.disabled = isLoading || disabledByCountry;
457476
}
458477

459-
const submitButton = attorneyFiltersPanel.querySelector('button[type="submit"]');
460-
if (submitButton) {
461-
submitButton.disabled = isLoading;
462-
}
463-
464478
const resetLink = attorneyFiltersPanel.querySelector("a");
465479
if (resetLink) {
466480
resetLink.setAttribute("aria-disabled", isLoading ? "true" : "false");
467481
resetLink.tabIndex = isLoading ? -1 : 0;
468482
}
469483
}
470484

485+
function updateAttorneyFiltersClearVisibility() {
486+
if (!attorneyFiltersPanel || !attorneyCountryFilter || !attorneyRegionFilter) {
487+
return;
488+
}
489+
490+
const resetActions = attorneyFiltersPanel.querySelector("#attorney-filters-actions");
491+
if (!resetActions) {
492+
return;
493+
}
494+
495+
resetActions.hidden = !(attorneyCountryFilter.value || attorneyRegionFilter.value);
496+
}
497+
498+
function updateAttorneyCountryLabels() {
499+
if (!attorneyCountryFilter) {
500+
return;
501+
}
502+
503+
const selectedCountry = attorneyCountryFilter.value;
504+
const showSelectedCount = attorneyCountryFilter.dataset.showSelectedCount === "true";
505+
506+
Array.from(attorneyCountryFilter.options).forEach((option) => {
507+
if (!option.value) {
508+
return;
509+
}
510+
511+
const country = Array.isArray(attorneyFilterMetadata.countries)
512+
? attorneyFilterMetadata.countries.find((item) => item.code === option.value)
513+
: null;
514+
if (!country) {
515+
return;
516+
}
517+
518+
option.textContent =
519+
option.value === selectedCountry && !showSelectedCount
520+
? country.label
521+
: `${country.label} (${country.count})`;
522+
});
523+
}
524+
525+
function setAttorneySelectExpandedState(select, isExpanded) {
526+
if (!select) {
527+
return;
528+
}
529+
530+
select.dataset.showSelectedCount = isExpanded ? "true" : "false";
531+
}
532+
533+
function updateAttorneySelectExpandedLabels(isExpanded) {
534+
setAttorneySelectExpandedState(attorneyCountryFilter, isExpanded);
535+
setAttorneySelectExpandedState(attorneyRegionFilter, isExpanded);
536+
updateAttorneyCountryLabels();
537+
updateAttorneyRegionOptions();
538+
}
539+
540+
function inferredCountryForRegionCode(regionCode) {
541+
if (!regionCode) {
542+
return "";
543+
}
544+
545+
const normalizedRegionCode = regionCode.trim().toLowerCase();
546+
const regionsByCountry =
547+
attorneyFilterMetadata.regions && typeof attorneyFilterMetadata.regions === "object"
548+
? attorneyFilterMetadata.regions
549+
: {};
550+
551+
for (const [countryName, countryRegions] of Object.entries(regionsByCountry)) {
552+
if (!Array.isArray(countryRegions)) {
553+
continue;
554+
}
555+
556+
const matchingRegion = countryRegions.find(
557+
(region) => String(region.code).trim().toLowerCase() === normalizedRegionCode,
558+
);
559+
if (matchingRegion) {
560+
return countryName;
561+
}
562+
}
563+
564+
return "";
565+
}
566+
471567
function updateAttorneyRegionOptions() {
472568
if (!attorneyCountryFilter || !attorneyRegionFilter) {
473569
return;
474570
}
475571

476572
const selectedCountry = attorneyCountryFilter.value;
477573
const selectedRegion = attorneyRegionFilter.value;
478-
const availableRegions = Array.isArray(attorneyFilterMetadata.regions?.[selectedCountry])
479-
? attorneyFilterMetadata.regions[selectedCountry]
480-
: [];
574+
const showSelectedCount = attorneyRegionFilter.dataset.showSelectedCount === "true";
575+
const regionsByCountry =
576+
attorneyFilterMetadata.regions && typeof attorneyFilterMetadata.regions === "object"
577+
? attorneyFilterMetadata.regions
578+
: {};
579+
const availableRegions = selectedCountry
580+
? Array.isArray(regionsByCountry[selectedCountry])
581+
? regionsByCountry[selectedCountry]
582+
: []
583+
: Object.values(regionsByCountry).flatMap((countryRegions) =>
584+
Array.isArray(countryRegions) ? countryRegions : [],
585+
);
481586

482587
attorneyRegionFilter.innerHTML = '<option value="">All</option>';
483588

484-
availableRegions.forEach((region) => {
485-
const option = document.createElement("option");
486-
option.value = region.code;
487-
option.textContent = region.label;
488-
if (region.code === selectedRegion) {
489-
option.selected = true;
490-
}
491-
attorneyRegionFilter.appendChild(option);
492-
});
589+
if (selectedCountry) {
590+
availableRegions.forEach((region) => {
591+
const option = document.createElement("option");
592+
option.value = region.code;
593+
option.textContent =
594+
region.code === selectedRegion && !showSelectedCount
595+
? region.label
596+
: `${region.label} (${region.count})`;
597+
if (region.code === selectedRegion) {
598+
option.selected = true;
599+
}
600+
attorneyRegionFilter.appendChild(option);
601+
});
602+
} else {
603+
Object.entries(regionsByCountry).forEach(([countryName, countryRegions]) => {
604+
if (!Array.isArray(countryRegions) || !countryRegions.length) {
605+
return;
606+
}
607+
608+
const optgroup = document.createElement("optgroup");
609+
optgroup.label = countryName;
610+
611+
countryRegions.forEach((region) => {
612+
const option = document.createElement("option");
613+
option.value = region.code;
614+
option.textContent =
615+
region.code === selectedRegion && !showSelectedCount
616+
? region.label
617+
: `${region.label} (${region.count})`;
618+
if (region.code === selectedRegion) {
619+
option.selected = true;
620+
}
621+
optgroup.appendChild(option);
622+
});
623+
624+
attorneyRegionFilter.appendChild(optgroup);
625+
});
626+
}
493627

494628
if (!availableRegions.some((region) => region.code === selectedRegion)) {
495629
attorneyRegionFilter.value = "";
496630
}
497631

498-
const disabledByCountry = !(selectedCountry && availableRegions.length);
632+
const disabledByCountry = !availableRegions.length;
499633
attorneyRegionFilter.dataset.disabledByCountry = disabledByCountry ? "true" : "false";
500634
attorneyRegionFilter.disabled = attorneyFiltersLoading || disabledByCountry;
635+
updateAttorneyFiltersClearVisibility();
501636
}
502637

503638
function ensureAttorneyFilterMetadata() {
@@ -518,6 +653,7 @@ document.addEventListener("DOMContentLoaded", function () {
518653
})
519654
.then((data) => {
520655
attorneyFilterMetadata = data;
656+
updateAttorneyCountryLabels();
521657
updateAttorneyRegionOptions();
522658
return data;
523659
})
@@ -644,22 +780,52 @@ document.addEventListener("DOMContentLoaded", function () {
644780

645781
if (attorneyFiltersPanel && attorneyCountryFilter && attorneyRegionFilter) {
646782
const resetLink = attorneyFiltersPanel.querySelector("a");
783+
const syncExpandedLabelsOnOpen = function (event) {
784+
if (
785+
event.type === "keydown" &&
786+
event.key !== "ArrowDown" &&
787+
event.key !== "ArrowUp" &&
788+
event.key !== "Enter" &&
789+
event.key !== " "
790+
) {
791+
return;
792+
}
647793

648-
attorneyFiltersPanel.addEventListener("submit", function (event) {
649-
event.preventDefault();
650-
void refreshAttorneyResults();
651-
});
794+
updateAttorneySelectExpandedLabels(true);
795+
};
796+
const syncExpandedLabelsOnClose = function () {
797+
updateAttorneySelectExpandedLabels(false);
798+
};
652799

653800
attorneyCountryFilter.addEventListener("change", async function () {
654801
await ensureAttorneyFilterMetadata();
802+
updateAttorneyCountryLabels();
655803
updateAttorneyRegionOptions();
804+
syncExpandedLabelsOnClose();
656805
void refreshAttorneyResults();
657806
});
658807

659808
attorneyRegionFilter.addEventListener("change", function () {
809+
if (!attorneyCountryFilter.value && attorneyRegionFilter.value) {
810+
attorneyCountryFilter.value = inferredCountryForRegionCode(attorneyRegionFilter.value);
811+
updateAttorneyRegionOptions();
812+
}
813+
updateAttorneyCountryLabels();
814+
updateAttorneyFiltersClearVisibility();
815+
syncExpandedLabelsOnClose();
660816
void refreshAttorneyResults();
661817
});
662818

819+
attorneyCountryFilter.addEventListener("focus", syncExpandedLabelsOnOpen);
820+
attorneyCountryFilter.addEventListener("pointerdown", syncExpandedLabelsOnOpen);
821+
attorneyCountryFilter.addEventListener("keydown", syncExpandedLabelsOnOpen);
822+
attorneyCountryFilter.addEventListener("blur", syncExpandedLabelsOnClose);
823+
824+
attorneyRegionFilter.addEventListener("focus", syncExpandedLabelsOnOpen);
825+
attorneyRegionFilter.addEventListener("pointerdown", syncExpandedLabelsOnOpen);
826+
attorneyRegionFilter.addEventListener("keydown", syncExpandedLabelsOnOpen);
827+
attorneyRegionFilter.addEventListener("blur", syncExpandedLabelsOnClose);
828+
663829
if (resetLink) {
664830
resetLink.addEventListener("click", function (event) {
665831
event.preventDefault();
@@ -669,9 +835,9 @@ document.addEventListener("DOMContentLoaded", function () {
669835

670836
attorneyCountryFilter.value = "";
671837
attorneyRegionFilter.value = "";
838+
updateAttorneyCountryLabels();
672839
updateAttorneyRegionOptions();
673-
attorneyFiltersPanel.hidden = true;
674-
updateAttorneyFiltersToggle();
840+
syncExpandedLabelsOnClose();
675841
void refreshAttorneyResults();
676842
});
677843
}
@@ -700,6 +866,7 @@ document.addEventListener("DOMContentLoaded", function () {
700866
targetPanel.style.display = "block";
701867
targetPanel.classList.add("active");
702868

869+
updateAttorneyFilterVisibility();
703870
updatePlaceholder();
704871
handleSearchInput();
705872
};

0 commit comments

Comments
 (0)