From c71b0b9a6bdb94efc9228165853b416985eac574 Mon Sep 17 00:00:00 2001 From: Fredrik Jonsson Date: Tue, 1 Sep 2026 18:32:29 +0200 Subject: [PATCH] Make category question widget render select input if more than 32 options for both single and multiselect fields. --- hypha/apply/categories/blocks.py | 31 ++++++++++++++++----------- hypha/apply/funds/forms.py | 6 +++--- hypha/apply/funds/tables.py | 4 ++-- hypha/apply/funds/widgets.py | 14 +++++++++--- hypha/apply/projects/forms/invoice.py | 4 ++-- 5 files changed, 37 insertions(+), 22 deletions(-) diff --git a/hypha/apply/categories/blocks.py b/hypha/apply/categories/blocks.py index 9eb4731505..9f9c1a05cb 100644 --- a/hypha/apply/categories/blocks.py +++ b/hypha/apply/categories/blocks.py @@ -1,4 +1,5 @@ from django import forms +from django.db.models import BLANK_CHOICE_DASH from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from wagtail.blocks import ( @@ -9,8 +10,13 @@ ) from wagtail.coreutils import resolve_model_string +from hypha.apply.funds.widgets import ChoicesSelectMultipleWidget, ChoicesSelectWidget from hypha.apply.stream_forms.blocks import OptionalFormFieldBlock +# Above this many options a radio/checkbox list stops being usable, so fall back +# to a searchable Choices.js select. +SEARCHABLE_SELECT_THRESHOLD = 32 + class ModelChooserBlock(ChoiceBlock): # Implement this block as it's referenced in the old migrations. @@ -65,23 +71,24 @@ def get_field_kwargs(self, struct_value): kwargs = super().get_field_kwargs(struct_value) category = self.get_instance(id=struct_value["category"]) kwargs = self.use_defaults_from_category(kwargs, category) - choices = category.options.values_list("id", "value") + choices = list(category.options.values_list("id", "value")) + if not struct_value["multi"] and len(choices) >= SEARCHABLE_SELECT_THRESHOLD: + # A