Class: TagsInput
- Inherits:
-
TomSelectInput
- Object
- SimpleForm::Inputs::CollectionSelectInput
- TomSelectInput
- TagsInput
- Defined in:
- app/inputs/tags_input.rb
Overview
Custom SimpleForm input for centralized tag selection
This input provides a TomSelect-powered multiselect that:
- Loads tags on demand from Crm::TagsController#autocomplete
- Allows creating new tags on the fly
- Works with the Taggable concern's
tags=setter
Only the currently selected tags are rendered as elements; the rest
arrive over the wire as the user types. Embedding the whole ~5k tag table added
~9.6k option nodes to a page, and because each TomSelect init forces a
synchronous full-document layout, that taxed every other select on the page —
a 16-option dropdown measured 479ms. Publications' edit form spent ~8.7s in
TomSelect init; selected-only brings it to ~150ms.
Usage in forms:
<%= f.input :tags, as: :tags %>
<%= f.input :tags, as: :tags, placeholder: 'Select or create tags...' %>
<%= f.input :tags, as: :tags, create: false %> # Disable new tag creation
<%= f.input :tags, as: :tags, taggable_type: 'Image' %> # only tags applied to Images
<%= f.input :tags, as: :tags, exclude_tags: Image::POPULAR_TAGS %>
Instance Method Summary collapse
-
#collection ⇒ Object
Only the selected tags are rendered inline; the rest are fetched on demand from Crm::TagsController#autocomplete.
- #input(wrapper_options = nil) ⇒ Object
Methods inherited from TomSelectInput
Instance Method Details
#collection ⇒ Object
Only the selected tags are rendered inline; the rest are fetched on demand from
Crm::TagsController#autocomplete. Values are plain tag names because
Taggable#tags= takes names (and Taggable#tags already returns names).
59 60 61 62 63 64 |
# File 'app/inputs/tags_input.rb', line 59 def collection # If a custom collection is provided, use it return [:collection] if [:collection].present? Array(selected_value || []).compact_blank.map { |tag_name| [tag_name.to_s, tag_name.to_s] }.uniq end |
#input(wrapper_options = nil) ⇒ Object
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 |
# File 'app/inputs/tags_input.rb', line 24 def input( = nil) # Consume the input-specific options before `super` — SimpleForm forwards # anything it doesn't recognise down to the collection helper, and the repo # pattern (Redactor4Input, TomSelectInput) is to delete custom keys here. @taggable_type = .delete(:taggable_type).presence @exclude_tags = Array(.delete(:exclude_tags)).compact_blank # Enable multiple selection by default for tags [:multiple] = true # Enable creation of new tags by default (can be overridden with create: false) [:create] = true unless .key?(:create) && [:create] == false # Set default placeholder [:placeholder] ||= 'Select or create tags...' # Add tag-specific data attributes [:data] ||= {} [:data]['tom-select-allow-empty-option-value'] = true # Remote lookup. An explicit :collection opts out entirely (the caller supplied # its own fixed list), so don't point that at the endpoint. if [:collection].blank? [:data]['tom-select-suggest-url-value'] = template.(lookup_params) [:data]['tom-select-min-chars-value'] = 1 # Populate the dropdown on focus so tags stay browsable without typing. [:preload] = true unless .key?(:preload) end super end |