Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | const MIN_CATEGORIES = 1; const MAX_CATEGORIES = 2; interface CategorySelectorConfig { containerId?: string; sectionId?: string; checkboxSelector?: string; min?: number; max?: number; } class CategorySelector { container: HTMLElement | null; section: HTMLElement | null; checkboxSelector: string; min: number; max: number; checkboxes: HTMLInputElement[]; constructor({ containerId = "categories-list", sectionId = "categories-section", checkboxSelector = ".category-checkbox", min = MIN_CATEGORIES, max = MAX_CATEGORIES, }: CategorySelectorConfig = {}) { this.container = document.getElementById(containerId); this.section = document.getElementById(sectionId); this.checkboxSelector = checkboxSelector; this.min = min; this.max = max; this.checkboxes = []; if (!this.container) { return; } this.checkboxes = Array.from( this.container.querySelectorAll<HTMLInputElement>(checkboxSelector) ); this.checkboxes.forEach((checkbox) => { checkbox.addEventListener("change", () => this.handleChange()); }); this.enforce(); } getCheckedCount(): number { return this.checkboxes.filter((checkbox) => checkbox.checked).length; } handleChange(): void { this.enforce(); if (this.getCheckedCount() > 0) { this.clearError(); } } enforce(): void { if (!this.checkboxes) { return; } const limitReached = this.getCheckedCount() >= this.max; this.checkboxes.forEach((checkbox) => { checkbox.disabled = limitReached && !checkbox.checked; }); } clearError(): void { if (!this.section) { return; } this.section.classList.remove("is-error"); const message = this.section.querySelector(".p-form-validation__message"); if (message) { message.setAttribute("hidden", ""); } } showError(): void { if (!this.section) { return; } this.section.classList.add("is-error"); const message = this.section.querySelector(".p-form-validation__message"); if (message) { message.removeAttribute("hidden"); } this.section.scrollIntoView({ behavior: "smooth" }); } isValid(): boolean { if (!this.container || this.checkboxes.length === 0) { return true; } const count = this.getCheckedCount(); if (count < this.min || count > this.max) { this.showError(); return false; } this.clearError(); return true; } } export default CategorySelector; |