mod/search/set/self/search.rb
def match_start_only?
Card.config.search_box_match_start_only
end
format do
delegate :match_start_only?, to: :card
view :search_error, cache: :never do
# don't show card content; not very helpful in this case
%(#{search_with_params.class} :: #{search_with_params.message})
end
def search_with_params
@search_with_params ||= cql_keyword? ? cql_search : super
end
def cql_search
query = card.parse_json_cql search_keyword
rescuing_bad_query(query) { Card.search query }
end
def search_keyword
@search_keyword ||= term_param || search_vars&.dig(:keyword)
end
def search_vars
root.respond_to?(:search_params) ? root.search_params[:vars] : search_params[:vars]
end
def cql_keyword?
search_keyword&.match?(/^\{.+\}$/)
end
def complete_path
path mark: :search, view: :search_box_complete, format: :json
# path mark: :search, view: :test, format: :json
end
def results_path keyword
path mark: :search, query: { keyword: keyword }
end
end
format :html do
view :search_box, template: :haml, cache: :never
view :title do
voo.title ||= t(:search_results_title)
super()
end
view :core, cache: :never do
[render_results_for_keyword, super()]
end
view :results_for_keyword, cache: :never, template: :haml
def search_item term
autocomplete_item :search, icon_tag(:search), term
end
private
def search_form &block
form_tag path, method: "get", role: "search", class: classy("search-box-form"), &block
end
def search_box_contents
text_field_tag "query[keyword]", search_keyword,
class: "_search-box #{classy 'search-box'} form-control w-100",
autocomplete: :off,
data: { completepath: complete_path },
placeholder: t(:search_search_box_placeholder)
end
end
format :json do
view :search_box_complete, cache: :never do
search_box_items :search_item, :add_item, :goto_items
end
view :complete, cache: :never do
complete_or_match_search(start_only: match_start_only?).map do |name|
goto_item_label name
end
end
private
def search_box_items *methods
[].tap do |items|
each_search_box_item methods do |action, value, label, data|
items << data.merge(action: action, value: value, label: label)
end
end
end
def each_search_box_item methods, &block
term = search_keyword
exact = Card.fetch term, new: {}
methods.map { |method| send method, term, exact, &block }
end
def search_item term, _exact
yield :search, term, card.format.search_item(term), url: card_url(results_path(term))
end
def add_item term, exact
return unless exact.add_autocomplete_ok?
fmt = exact.format
yield :add, term, fmt.render_add_autocomplete_item,
url: card_url(fmt.add_autocomplete_item_path)
end
def goto_items _term, exact
map_goto_items exact do |item|
yield :goto, item, goto_item_label(item), url: path(mark: item)
end
end
def goto_item_label item
item.card.format.render_goto_autocomplete_item
end
def map_goto_items exact, &block
goto_names = complete_or_match_search start_only: match_start_only?
goto_names.unshift exact.name if go_to_exact_match? exact
goto_names.uniq.map(&block)
end
def go_to_exact_match? exact
exact.known?
end
def term_param
# return nil unless query_params.present?
#
# term = query_params[:keyword]
return unless (term = super)&.present?
if (term =~ /^\+/) && (main = params["main"])
term = main + term
end
term
end
end