Class: TomSelect
- Inherits:
-
Object
- Object
- TomSelect
- Defined in:
- app/models/tom_select.rb
Overview
Helper module for building JSON payloads consumed by the Tom Select
JS library — Heatwave's standard typeahead/dropdown widget. Pairs a
paginated ActiveRecord relation with Pagy metadata so the front end
can lazy-load the next page when the user keeps scrolling.
Class Method Summary collapse
-
.format_json_results(view, results, page = nil, per_page = nil, id_method = nil, text_method = nil) {|item| ... } ⇒ Hash
Formats query results for Tom Select dropdowns Handles both flat arrays and option groups.
-
.format_option_groups(option_groups, pagination = nil) ⇒ Hash
Formats option groups (like Activity::ResourceList) for Tom Select Option groups are already in the format: { text: "Group Name", children: [{ id, text }, ...] } This ensures text fields are normalized and returns the format Tom Select expects.
-
.normalize_text(text) ⇒ String
Normalizes text to always be a string (handles arrays, nil, etc.).
Class Method Details
.format_json_results(view, results, page = nil, per_page = nil, id_method = nil, text_method = nil) {|item| ... } ⇒ Hash
Formats query results for Tom Select dropdowns
Handles both flat arrays and option groups
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 |
# File 'app/models/tom_select.rb', line 19 def self.format_json_results(view, results, page = nil, per_page = nil, id_method = nil, text_method = nil, &) page = page.presence&.to_i || 1 per_page = per_page.presence&.to_i || 20 # Use Pagy in the controller's context (provides request for URL generation) # Use instance_exec to pass arguments explicitly for proper :countless support pagy, paginated_results = if results.is_a?(Array) # For arrays, use Pagy's offset pagination view.instance_exec(results, page, per_page) { |r, p, pp| pagy(:offset, r, page: p, limit: pp) } else # For ActiveRecord relations, use countless pagination (no COUNT query needed for infinite scrolling) view.instance_exec(results, page, per_page) { |r, p, pp| pagy(:countless, r, page: p, limit: pp) } end # Check if there's a next page (for infinite scrolling) more = !pagy.next.nil? results_array = paginated_results.map do |e| if block_given? yield(e) else id_method ||= :id text_method ||= :selection_name { id: e.try(id_method) || e.to_s, text: normalize_text(e.try(text_method) || e.to_s) } end end { results: results_array.uniq, pagination: { more: more } } end |
.format_option_groups(option_groups, pagination = nil) ⇒ Hash
Formats option groups (like Activity::ResourceList) for Tom Select
Option groups are already in the format: { text: "Group Name", children: [{ id, text }, ...] }
This ensures text fields are normalized and returns the format Tom Select expects
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'app/models/tom_select.rb', line 71 def self.format_option_groups(option_groups, pagination = nil) normalized_groups = option_groups.map do |group| { text: normalize_text(group[:text] || group['text'] || ''), children: (group[:children] || group['children'] || []).map do |child| { id: child[:id] || child['id'], text: normalize_text(child[:text] || child['text'] || '') } end } end { results: normalized_groups, pagination: pagination || { more: false } } end |
.normalize_text(text) ⇒ String
Normalizes text to always be a string (handles arrays, nil, etc.)
53 54 55 56 57 58 59 60 61 62 |
# File 'app/models/tom_select.rb', line 53 def self.normalize_text(text) case text when Array text.compact.join(' - ') when nil '' else text.to_s end end |