mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-08 07:46:59 +00:00
Refactor SearchableDropdownComponent and integrate remote data loading with TomSelect
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SearchableDropdownComponent < ViewComponent::Base
|
||||
REMOVED_SEARCH_PLUGIN = { 'tom-select-options-value': '{ "plugins": [] }' }.freeze
|
||||
MINIMUM_OPTIONS_FOR_SEARCH_FIELD = 11 # at least 11 options are required for the search field
|
||||
|
||||
def initialize(
|
||||
form:,
|
||||
name:,
|
||||
options:,
|
||||
selected_option:,
|
||||
placeholder_value:,
|
||||
form: nil,
|
||||
placeholder_value: '',
|
||||
include_blank: false,
|
||||
aria_label: '',
|
||||
multiple: false,
|
||||
remote_url: nil,
|
||||
other_attrs: {}
|
||||
)
|
||||
@f = form
|
||||
@@ -21,13 +22,15 @@ class SearchableDropdownComponent < ViewComponent::Base
|
||||
@placeholder_value = placeholder_value
|
||||
@include_blank = include_blank
|
||||
@aria_label = aria_label
|
||||
@multiple = multiple
|
||||
@remote_url = remote_url
|
||||
@other_attrs = other_attrs
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :f, :name, :options, :selected_option, :placeholder_value, :include_blank,
|
||||
:aria_label, :other_attrs
|
||||
:aria_label, :multiple, :remote_url, :other_attrs
|
||||
|
||||
def classes
|
||||
"fullwidth #{'no-input' if remove_search_plugin?}"
|
||||
@@ -36,11 +39,31 @@ class SearchableDropdownComponent < ViewComponent::Base
|
||||
def data
|
||||
{
|
||||
controller: "tom-select",
|
||||
'tom-select-placeholder-value': placeholder_value
|
||||
}.merge(remove_search_plugin? ? REMOVED_SEARCH_PLUGIN : {})
|
||||
'tom-select-placeholder-value': placeholder_value,
|
||||
'tom-select-options-value': tom_select_options_value,
|
||||
'tom-select-remote-url-value': remote_url,
|
||||
}
|
||||
end
|
||||
|
||||
def tom_select_options_value
|
||||
plugins = remove_search_plugin? ? [] : ['dropdown_input']
|
||||
multiple ? plugins << 'remove_button' : plugins
|
||||
|
||||
{
|
||||
plugins:,
|
||||
maxItems: multiple ? nil : 1,
|
||||
}
|
||||
end
|
||||
|
||||
def uses_form_builder?
|
||||
f.present?
|
||||
end
|
||||
|
||||
def remove_search_plugin?
|
||||
@remove_search_plugin ||= options.count < MINIMUM_OPTIONS_FOR_SEARCH_FIELD
|
||||
# Remove the search plugin when:
|
||||
# - the select is multiple (it already includes a search field), or
|
||||
# - there is no remote URL and the options are below the search threshold
|
||||
@remove_search_plugin ||= multiple ||
|
||||
(@remote_url.nil? && options.count < MINIMUM_OPTIONS_FOR_SEARCH_FIELD)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
= f.select name, options_for_select(options, selected_option), { include_blank: }, class: classes, data:, 'aria-label': aria_label, **other_attrs
|
||||
- if uses_form_builder?
|
||||
= f.select name, options, { selected: selected_option, include_blank:, multiple: }, class: classes, data:, 'aria-label': aria_label, **other_attrs
|
||||
- else
|
||||
= select_tag name, options_for_select(options, selected_option), include_blank: include_blank, multiple: multiple, class: classes, data: data, 'aria-label': aria_label, **other_attrs
|
||||
|
||||
Reference in New Issue
Block a user