Initial work on sort_link. Mostly ported from MetaSearch, changes coming soon
This commit is contained in:
parent
c156fa4a7a
commit
f6973b3a3b
|
@ -73,6 +73,10 @@ module Ransack
|
|||
search_fields(:s, args, block)
|
||||
end
|
||||
|
||||
def sort_link(attribute, *args)
|
||||
@template.sort_link @object, attribute, *args
|
||||
end
|
||||
|
||||
def condition_fields(*args, &block)
|
||||
search_fields(:c, args, block)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module Ransack
|
||||
module Helpers
|
||||
module FormHelper
|
||||
|
||||
def search_form_for(record, options = {}, &proc)
|
||||
if record.is_a?(Ransack::Search)
|
||||
search = record
|
||||
|
@ -23,6 +24,52 @@ module Ransack
|
|||
form_for(record, options, &proc)
|
||||
end
|
||||
|
||||
def sort_link(search, attribute, *args)
|
||||
raise TypeError, "First argument must be a Ransack::Search!" unless Search === search
|
||||
|
||||
search_params = params[:q] || {}.with_indifferent_access
|
||||
|
||||
attr_name = attribute.to_s
|
||||
|
||||
name = (args.size > 0 && !args.first.is_a?(Hash)) ? args.shift.to_s : Translate.attribute(attr_name, :context => search.context)
|
||||
|
||||
if existing_sort = search.sorts.detect {|s| s.name == attr_name}
|
||||
prev_attr, prev_dir = existing_sort.name, existing_sort.dir
|
||||
end
|
||||
|
||||
options = args.first.is_a?(Hash) ? args.shift.dup : {}
|
||||
default_order = options.delete :default_order
|
||||
current_dir = prev_attr == attr_name ? prev_dir : nil
|
||||
|
||||
if current_dir
|
||||
new_dir = current_dir == 'desc' ? 'asc' : 'desc'
|
||||
else
|
||||
new_dir = default_order || 'asc'
|
||||
end
|
||||
|
||||
html_options = args.first.is_a?(Hash) ? args.shift.dup : {}
|
||||
css = ['sort_link', current_dir].compact.join(' ')
|
||||
html_options[:class] = [css, html_options[:class]].compact.join(' ')
|
||||
options.merge!(
|
||||
:q => search_params.merge(:s => "#{attr_name} #{new_dir}")
|
||||
)
|
||||
link_to [ERB::Util.h(name), order_indicator_for(current_dir)].compact.join(' ').html_safe,
|
||||
url_for(options),
|
||||
html_options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_indicator_for(order)
|
||||
if order == 'asc'
|
||||
'▲'
|
||||
elsif order == 'desc'
|
||||
'▼'
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -49,8 +49,10 @@ module Ransack
|
|||
sort = Nodes::Sort.new(@context).build(attrs)
|
||||
self.sorts << sort
|
||||
end
|
||||
else
|
||||
when String
|
||||
self.sorts = [args]
|
||||
else
|
||||
raise ArgumentError, "Invalid argument (#{args.class}) supplied to sorts="
|
||||
end
|
||||
end
|
||||
alias :s= :sorts=
|
||||
|
|
|
@ -12,7 +12,7 @@ module Ransack
|
|||
|
||||
def self.attribute(key, options = {})
|
||||
unless context = options.delete(:context)
|
||||
raise ArgumentError, "A context is required to translate associations"
|
||||
raise ArgumentError, "A context is required to translate attributes"
|
||||
end
|
||||
|
||||
original_name = key.to_s
|
||||
|
|
|
@ -47,6 +47,14 @@ module Ransack
|
|||
|
||||
end
|
||||
|
||||
describe '#sort_link' do
|
||||
subject { @f.sort_link :name, :controller => 'people' }
|
||||
|
||||
it { should match /people\?q%5Bs%5D=name\+asc/}
|
||||
it { should match /sort_link/}
|
||||
it { should match /Full Name<\/a>/}
|
||||
end
|
||||
|
||||
describe '#submit' do
|
||||
|
||||
it 'localizes :search when no default value given' do
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
require 'spec_helper'
|
||||
|
||||
module Ransack
|
||||
module Helpers
|
||||
describe FormHelper do
|
||||
|
||||
router = ActionDispatch::Routing::RouteSet.new
|
||||
router.draw do
|
||||
resources :people
|
||||
match ':controller(/:action(/:id(.:format)))'
|
||||
end
|
||||
|
||||
include router.url_helpers
|
||||
|
||||
# FIXME: figure out a cleaner way to get this behavior
|
||||
before do
|
||||
@controller = ActionView::TestCase::TestController.new
|
||||
@controller.instance_variable_set(:@_routes, router)
|
||||
@controller.class_eval do
|
||||
include router.url_helpers
|
||||
end
|
||||
|
||||
@controller.view_context_class.class_eval do
|
||||
include router.url_helpers
|
||||
end
|
||||
end
|
||||
|
||||
describe '#sort_link' do
|
||||
subject { @controller.view_context.sort_link(Person.search(:sorts => ['name desc']), :name, :controller => 'people') }
|
||||
|
||||
it { should match /people\?q%5Bs%5D=name\+asc/}
|
||||
it { should match /sort_link desc/}
|
||||
it { should match /Full Name ▼/}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue