activerecord-hackery--ransack/lib/ransack/helpers/form_helper.rb

205 lines
6.0 KiB
Ruby
Raw Normal View History

2011-03-31 00:31:39 +00:00
module Ransack
module Helpers
module FormHelper
# +search_form_for+
#
2014-12-08 23:11:21 +00:00
# <%= search_form_for(@q) do |f| %>
#
2011-03-31 00:31:39 +00:00
def search_form_for(record, options = {}, &proc)
if record.is_a? Ransack::Search
2011-03-31 00:31:39 +00:00
search = record
2014-04-18 08:49:38 +00:00
options[:url] ||= polymorphic_path(
search.klass, format: options.delete(:format)
)
elsif record.is_a? Array &&
(search = record.detect { |o| o.is_a? Ransack::Search })
2013-08-04 13:13:41 +00:00
options[:url] ||= polymorphic_path(
record.map { |o| o.is_a? Ransack::Search ? o.klass : o },
2014-04-18 08:49:38 +00:00
format: options.delete(:format)
2013-12-10 18:18:17 +00:00
)
2011-03-31 00:31:39 +00:00
else
2013-08-04 13:13:41 +00:00
raise ArgumentError,
'No Ransack::Search object was provided to search_form_for!'
2011-03-31 00:31:39 +00:00
end
options[:html] ||= {}
html_options = {
:class => options[:class].present? ?
2013-12-10 18:18:17 +00:00
"#{options[:class]}" :
"#{search.klass.to_s.underscore}_search",
:id => options[:id].present? ?
2013-12-10 18:18:17 +00:00
"#{options[:id]}" :
"#{search.klass.to_s.underscore}_search",
:method => :get
2011-03-31 00:31:39 +00:00
}
options[:as] ||= Ransack.options[:search_key]
2011-03-31 00:31:39 +00:00
options[:html].reverse_merge!(html_options)
options[:builder] ||= FormBuilder
form_for(record, options, &proc)
end
# +sort_link+
#
2014-12-08 23:11:21 +00:00
# <%= sort_link(@q, :name, [:name, 'kind ASC'], 'Player Name') %>
#
def sort_link(search, attribute, *args)
@search_object, routing_proxy = extract_search_obj_and_routing(search)
raise TypeError, 'First argument must be a Ransack::Search!' unless
Search === @search_object
2014-12-11 17:39:02 +00:00
initialize_sort_link_ivars(attribute, args)
link_to(name, url(routing_proxy), html_options(args))
end
private
2014-12-08 23:11:21 +00:00
# `initialize_sort_link_ivars` centralizes the +sort_link+ value
# mutations and order-dependent code. No ivars are mutated outside of
# this method. `args` are mutated in the `mutate_args!` methods.
2014-12-11 17:39:02 +00:00
def initialize_sort_link_ivars(attribute, args)
2014-12-08 23:11:21 +00:00
@field_name = attribute.to_s
@current_dir = existing_sort_direction
# begin order-dependent assignments
sort_fields = extract_sort_fields_and_mutate_args!(args).compact
2014-12-08 23:11:21 +00:00
@label_text = extract_label_text_and_mutate_args!(args)
@options = extract_options_and_mutate_args!(args)
@hide_indicator = @options.delete :hide_indicator
@default_order = @options.delete :default_order
if Hash === @default_order
@default_order = @default_order.with_indifferent_access
end
@sort_params = initialize_sort_params(sort_fields)
@sort_params = @sort_params.first if @sort_params.size == 1
# end order-dependent assignments
end
2014-12-08 23:11:21 +00:00
def extract_search_obj_and_routing(search)
if search.is_a? Array
[search.second, search.first]
else
[search, nil]
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def extract_sort_fields_and_mutate_args!(args)
if args.first.is_a? Array
args.shift
else
[@field_name]
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def extract_label_text_and_mutate_args!(args)
if args.first.is_a? String
args.shift
else
Translate.attribute(@field_name, :context => @search_object.context)
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def extract_options_and_mutate_args!(args)
if args.first.is_a? Hash
args.shift
else
{}
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def name
[ERB::Util.h(@label_text), order_indicator]
.compact.join(Constants::NON_BREAKING_SPACE).html_safe
end
2014-12-08 23:11:21 +00:00
def url(routing_proxy)
if routing_proxy && respond_to?(routing_proxy)
send(routing_proxy).url_for(options_for_url)
else
url_for(options_for_url)
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def options_for_url
params.merge(
@options.merge(
@search_object.context.search_key => search_and_sort_params
)
2014-12-08 23:11:21 +00:00
)
end
2014-12-08 23:11:21 +00:00
def search_and_sort_params
search_params.merge(:s => @sort_params)
end
2014-12-08 23:11:21 +00:00
def search_params
params[@search_object.context.search_key].presence ||
{}.with_indifferent_access
end
2014-12-08 23:11:21 +00:00
def html_options(args)
html_options = extract_options_and_mutate_args!(args)
2014-12-11 12:58:54 +00:00
html_options.merge(class:
[[Constants::SORT_LINK, @current_dir], html_options[:class]]
.compact.join(Constants::SPACE)
)
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def initialize_sort_params(sort_fields)
sort_fields.each_with_object([]) do |field, a|
attr_name, new_dir = field.to_s.split(/\s+/)
if no_sort_direction_specified?(new_dir)
new_dir = detect_previous_sort_direction_and_invert_it(attr_name)
end
2014-12-08 23:11:21 +00:00
a << "#{attr_name} #{new_dir}"
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def detect_previous_sort_direction_and_invert_it(attr_name)
sort_dir = existing_sort_direction(attr_name)
if sort_dir
direction_text(sort_dir)
else
default_sort_order(attr_name) || Constants::ASC
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def existing_sort_direction(attr_name = @field_name)
if sort = @search_object.sorts.detect { |s| s && s.name == attr_name }
2014-12-08 23:11:21 +00:00
sort.dir
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def default_sort_order(attr_name)
Hash === @default_order ? @default_order[attr_name] : @default_order
end
2014-12-08 23:11:21 +00:00
def order_indicator
if @hide_indicator || no_sort_direction_specified?
nil
else
direction_arrow
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def no_sort_direction_specified?(dir = @current_dir)
!Constants::ASC_DESC.include?(dir)
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def direction_arrow
if @current_dir == Constants::DESC
Constants::DESC_ARROW
else
Constants::ASC_ARROW
end
2014-12-08 23:11:21 +00:00
end
2014-12-08 23:11:21 +00:00
def direction_text(dir)
if dir == Constants::DESC
Constants::ASC
else
Constants::DESC
end
2014-12-08 23:11:21 +00:00
end
2011-03-31 00:31:39 +00:00
end
end
end