activeadmin 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activeadmin might be problematic. Click here for more details.
- data/.document +5 -0
- data/.gitignore +25 -0
- data/Gemfile +16 -0
- data/LICENSE +20 -0
- data/README.rdoc +201 -0
- data/Rakefile +71 -0
- data/active_admin.gemspec +22 -0
- data/lib/active_admin.rb +229 -0
- data/lib/active_admin/action_builder.rb +60 -0
- data/lib/active_admin/action_items.rb +48 -0
- data/lib/active_admin/asset_registration.rb +34 -0
- data/lib/active_admin/breadcrumbs.rb +26 -0
- data/lib/active_admin/dashboards.rb +50 -0
- data/lib/active_admin/dashboards/dashboard_controller.rb +40 -0
- data/lib/active_admin/dashboards/renderer.rb +45 -0
- data/lib/active_admin/dashboards/section.rb +43 -0
- data/lib/active_admin/dashboards/section_renderer.rb +28 -0
- data/lib/active_admin/filters.rb +189 -0
- data/lib/active_admin/form_builder.rb +91 -0
- data/lib/active_admin/helpers/optional_display.rb +34 -0
- data/lib/active_admin/menu.rb +42 -0
- data/lib/active_admin/menu_item.rb +67 -0
- data/lib/active_admin/namespace.rb +111 -0
- data/lib/active_admin/page_config.rb +15 -0
- data/lib/active_admin/pages.rb +11 -0
- data/lib/active_admin/pages/base.rb +92 -0
- data/lib/active_admin/pages/edit.rb +21 -0
- data/lib/active_admin/pages/index.rb +58 -0
- data/lib/active_admin/pages/index/blog.rb +65 -0
- data/lib/active_admin/pages/index/table.rb +48 -0
- data/lib/active_admin/pages/index/thumbnails.rb +40 -0
- data/lib/active_admin/pages/new.rb +21 -0
- data/lib/active_admin/pages/show.rb +54 -0
- data/lib/active_admin/renderer.rb +72 -0
- data/lib/active_admin/resource.rb +96 -0
- data/lib/active_admin/resource_controller.rb +325 -0
- data/lib/active_admin/sidebar.rb +78 -0
- data/lib/active_admin/table_builder.rb +162 -0
- data/lib/active_admin/tabs_renderer.rb +39 -0
- data/lib/active_admin/version.rb +3 -0
- data/lib/active_admin/view_helpers.rb +106 -0
- data/lib/active_admin/views/active_admin_dashboard/index.html.erb +1 -0
- data/lib/active_admin/views/active_admin_default/edit.html.erb +1 -0
- data/lib/active_admin/views/active_admin_default/index.csv.erb +2 -0
- data/lib/active_admin/views/active_admin_default/index.html.erb +1 -0
- data/lib/active_admin/views/active_admin_default/new.html.erb +1 -0
- data/lib/active_admin/views/active_admin_default/show.html.erb +1 -0
- data/lib/active_admin/views/layouts/active_admin.html.erb +40 -0
- data/lib/activeadmin.rb +1 -0
- data/lib/generators/active_admin/install/install_generator.rb +31 -0
- data/lib/generators/active_admin/install/templates/active_admin.css +325 -0
- data/lib/generators/active_admin/install/templates/active_admin.js +10 -0
- data/lib/generators/active_admin/install/templates/active_admin.rb +47 -0
- data/lib/generators/active_admin/install/templates/active_admin_vendor.js +382 -0
- data/lib/generators/active_admin/install/templates/dashboards.rb +36 -0
- data/lib/generators/active_admin/install/templates/images/orderable.gif +0 -0
- data/lib/generators/active_admin/resource/resource_generator.rb +16 -0
- data/lib/generators/active_admin/resource/templates/admin.rb +3 -0
- data/spec/integration/dashboard_spec.rb +44 -0
- data/spec/integration/index_as_blog_spec.rb +65 -0
- data/spec/integration/index_as_csv_spec.rb +40 -0
- data/spec/integration/index_as_table_spec.rb +160 -0
- data/spec/integration/index_as_thumbnails_spec.rb +43 -0
- data/spec/integration/layout_spec.rb +82 -0
- data/spec/integration/new_view_spec.rb +52 -0
- data/spec/integration/show_view_spec.rb +91 -0
- data/spec/spec_helper.rb +104 -0
- data/spec/support/rails_template.rb +19 -0
- data/spec/unit/action_builder_spec.rb +76 -0
- data/spec/unit/action_items_spec.rb +41 -0
- data/spec/unit/active_admin_spec.rb +52 -0
- data/spec/unit/asset_registration_spec.rb +37 -0
- data/spec/unit/controller_filters_spec.rb +26 -0
- data/spec/unit/dashboard_section_spec.rb +63 -0
- data/spec/unit/dashboards_spec.rb +59 -0
- data/spec/unit/filter_form_builder_spec.rb +157 -0
- data/spec/unit/form_builder_spec.rb +238 -0
- data/spec/unit/menu_item_spec.rb +137 -0
- data/spec/unit/menu_spec.rb +53 -0
- data/spec/unit/namespace_spec.rb +107 -0
- data/spec/unit/registration_spec.rb +46 -0
- data/spec/unit/renderer_spec.rb +100 -0
- data/spec/unit/resource_controller_spec.rb +48 -0
- data/spec/unit/resource_spec.rb +197 -0
- data/spec/unit/routing_spec.rb +12 -0
- data/spec/unit/sidebar_spec.rb +96 -0
- data/spec/unit/table_builder_spec.rb +162 -0
- data/spec/unit/tabs_renderer_spec.rb +34 -0
- metadata +247 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
|
3
|
+
# Member Actions give you the functionality of defining both the
|
4
|
+
# action and the route directly from your ActiveAdmin registration
|
5
|
+
# block.
|
6
|
+
#
|
7
|
+
# For example:
|
8
|
+
#
|
9
|
+
# ActiveAdmin.register Post do
|
10
|
+
# member_action :comments do
|
11
|
+
# @post = Post.find(params[:id]
|
12
|
+
# @comments = @post.comments
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Will create a new controller action comments and will hook it up to
|
17
|
+
# the named route (comments_admin_post_path) /admin/posts/:id/comments
|
18
|
+
#
|
19
|
+
# You can treat everything within the block as a standard Rails controller
|
20
|
+
# action.
|
21
|
+
#
|
22
|
+
module ActionBuilder
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
base.extend ClassMethods
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def member_action(name, options = {}, &block)
|
30
|
+
active_admin_config.member_actions << ControllerAction.new(name, options)
|
31
|
+
define_method(name, &block || Proc.new{})
|
32
|
+
end
|
33
|
+
|
34
|
+
def clear_member_actions!
|
35
|
+
active_admin_config.clear_member_actions!
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def collection_action(name, options = {}, &block)
|
40
|
+
active_admin_config.collection_actions << ControllerAction.new(name, options)
|
41
|
+
define_method(name, &block || Proc.new{})
|
42
|
+
end
|
43
|
+
|
44
|
+
def clear_collection_actions!
|
45
|
+
active_admin_config.clear_collection_actions!
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class ControllerAction
|
50
|
+
attr_reader :name
|
51
|
+
def initialize(name, options = {})
|
52
|
+
@name, @options = name, options
|
53
|
+
end
|
54
|
+
|
55
|
+
def http_verb
|
56
|
+
@options[:method] ||= :get
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'active_admin/helpers/optional_display'
|
2
|
+
|
3
|
+
module ActiveAdmin
|
4
|
+
module ActionItems
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.send :extend, ClassMethods
|
8
|
+
base.class_inheritable_accessor :action_items
|
9
|
+
base.action_items = []
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def action_item(options = {}, &block)
|
14
|
+
self.action_items << ActiveAdmin::ActionItems::ActionItem.new(options, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear_action_items!
|
18
|
+
self.action_items = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def action_items_for(action)
|
22
|
+
action_items.select{|item| item.display_on?(action) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ActionItem
|
27
|
+
include ActiveAdmin::OptionalDisplay
|
28
|
+
|
29
|
+
attr_accessor :block
|
30
|
+
|
31
|
+
def initialize(options = {}, &block)
|
32
|
+
@options, @block = options, block
|
33
|
+
normalize_display_options!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Renderer < ActiveAdmin::Renderer
|
38
|
+
def to_html(action_items)
|
39
|
+
content_tag :div, :class => 'action_items' do
|
40
|
+
action_items.collect do |action_item|
|
41
|
+
instance_eval(&action_item.block)
|
42
|
+
end.join(" ")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module AssetRegistration
|
3
|
+
|
4
|
+
# Stylesheets
|
5
|
+
|
6
|
+
def register_stylesheet(name)
|
7
|
+
stylesheets << name
|
8
|
+
end
|
9
|
+
|
10
|
+
def stylesheets
|
11
|
+
@stylesheets ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear_stylesheets!
|
15
|
+
@stylesheets = []
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Javascripts
|
20
|
+
|
21
|
+
def register_javascript(name)
|
22
|
+
javascripts << name
|
23
|
+
end
|
24
|
+
|
25
|
+
def javascripts
|
26
|
+
@javascripts ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear_javascripts!
|
30
|
+
@javascripts = []
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Breadcrumbs
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def add_breadcrumb(name, url = '')
|
11
|
+
@breadcrumbs ||= []
|
12
|
+
url = send(url) if url.is_a?(Symbol)
|
13
|
+
@breadcrumbs << [name, url]
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
|
18
|
+
def add_breadcrumb(name, url, options = {})
|
19
|
+
before_filter options do |controller|
|
20
|
+
controller.send(:add_breadcrumb, name, url)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Dashboards
|
3
|
+
|
4
|
+
autoload :DashboardController, 'active_admin/dashboards/dashboard_controller'
|
5
|
+
autoload :Renderer, 'active_admin/dashboards/renderer'
|
6
|
+
autoload :Section, 'active_admin/dashboards/section'
|
7
|
+
autoload :SectionRenderer, 'active_admin/dashboards/section_renderer'
|
8
|
+
|
9
|
+
@@sections = {}
|
10
|
+
mattr_accessor :sections
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
# Eval an entire block in the context of this module to build
|
15
|
+
# dashboards quicker.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# ActiveAdmin::Dashboards.build do
|
20
|
+
# section "Recent Post" do
|
21
|
+
# # return a list of posts
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
def build(&block)
|
26
|
+
module_eval(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Add a new dashboard section to a namespace. If no namespace is given
|
30
|
+
# it will be added to the default namespace.
|
31
|
+
def add_section(name, options = {}, &block)
|
32
|
+
namespace = options.delete(:namespace) || ActiveAdmin.default_namespace
|
33
|
+
self.sections[namespace] ||= []
|
34
|
+
self.sections[namespace] << Section.new(namespace, name, options, &block)
|
35
|
+
self.sections[namespace].sort!
|
36
|
+
end
|
37
|
+
alias_method :section, :add_section
|
38
|
+
|
39
|
+
def sections_for_namespace(namespace)
|
40
|
+
@@sections[namespace] || []
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear_all_sections!
|
44
|
+
@@sections = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Dashboards
|
3
|
+
class DashboardController < ResourceController
|
4
|
+
|
5
|
+
# Render from here if not overriden
|
6
|
+
self.default_views = 'active_admin_dashboard'
|
7
|
+
|
8
|
+
clear_action_items!
|
9
|
+
|
10
|
+
def index
|
11
|
+
skip_sidebar!
|
12
|
+
@dashboard_sections = find_sections
|
13
|
+
render_or_default 'index'
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def set_current_tab
|
19
|
+
@current_tab = "Dashboard"
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_sections
|
23
|
+
ActiveAdmin::Dashboards.sections_for_namespace(namespace)
|
24
|
+
end
|
25
|
+
|
26
|
+
def namespace
|
27
|
+
self.class.name.split('::').first.underscore.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return the current menu for the view. This is a helper method
|
31
|
+
def current_menu
|
32
|
+
ActiveAdmin.namespaces[namespace].menu
|
33
|
+
end
|
34
|
+
|
35
|
+
# Override to do nothing
|
36
|
+
def add_section_breadcrumb
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Dashboards
|
3
|
+
class Renderer < ::ActiveAdmin::Pages::Base
|
4
|
+
|
5
|
+
def main_content
|
6
|
+
if @dashboard_sections && @dashboard_sections.any?
|
7
|
+
render_sections(@dashboard_sections)
|
8
|
+
else
|
9
|
+
default_welcome_section
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def title
|
16
|
+
"Dashboard"
|
17
|
+
end
|
18
|
+
|
19
|
+
def render_sections(sections)
|
20
|
+
content_tag :table, :class => "dashboard" do
|
21
|
+
sections.in_groups_of(3, false).collect do |row|
|
22
|
+
content_tag :tr do
|
23
|
+
row.collect do |section|
|
24
|
+
content_tag :td, render_section(section)
|
25
|
+
end.join
|
26
|
+
end
|
27
|
+
end.join
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Renders each section using their renderer
|
32
|
+
def render_section(section)
|
33
|
+
renderer = section.renderer.new(self)
|
34
|
+
renderer.to_html(section)
|
35
|
+
end
|
36
|
+
|
37
|
+
def default_welcome_section
|
38
|
+
content_tag :p, :id => "dashboard_default_message" do
|
39
|
+
"Welcome to Active Admin. This is the default dashboard page. To add dashboard sections, checkout 'app/admin/dashboards.rb'"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Dashboards
|
3
|
+
class Section
|
4
|
+
|
5
|
+
@@renderers = {
|
6
|
+
:default => SectionRenderer
|
7
|
+
}
|
8
|
+
cattr_accessor :renderers
|
9
|
+
|
10
|
+
DEFAULT_PRIORITY = 10
|
11
|
+
|
12
|
+
attr_accessor :name, :block
|
13
|
+
attr_reader :namespace
|
14
|
+
|
15
|
+
def initialize(namespace, name, options = {}, &block)
|
16
|
+
@namespace = namespace
|
17
|
+
@name = name
|
18
|
+
@options = options
|
19
|
+
@block = block
|
20
|
+
end
|
21
|
+
|
22
|
+
def priority
|
23
|
+
@options[:priority] || DEFAULT_PRIORITY
|
24
|
+
end
|
25
|
+
|
26
|
+
# Sort by priority then by name
|
27
|
+
def <=>(other)
|
28
|
+
result = priority <=> other.priority
|
29
|
+
result = name.to_s <=> other.name.to_s if result == 0
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the class to use as this sections renderer. Raises
|
34
|
+
# an exception if the renderer could not be found
|
35
|
+
def renderer
|
36
|
+
klass = Section.renderers[@options[:as] || :default]
|
37
|
+
raise StandardError, "Could not find the #{@options[:as].inspect} dashboard section renderer." unless klass
|
38
|
+
klass
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Dashboards
|
3
|
+
class SectionRenderer < ::ActiveAdmin::Renderer
|
4
|
+
|
5
|
+
def to_html(section)
|
6
|
+
@section = section
|
7
|
+
content_tag :div, title_wrapped + content_wrapped, :class => 'dashboard_section', :id => "#{section.name.to_s.downcase.gsub(' ', '_')}_dashboard_section"
|
8
|
+
end
|
9
|
+
|
10
|
+
def title_wrapped
|
11
|
+
content_tag :h3, title
|
12
|
+
end
|
13
|
+
|
14
|
+
def title
|
15
|
+
@section.name.to_s.titleize
|
16
|
+
end
|
17
|
+
|
18
|
+
def content_wrapped
|
19
|
+
content_tag :div, content, :class => 'dashboard_section_content'
|
20
|
+
end
|
21
|
+
|
22
|
+
def content
|
23
|
+
instance_eval(&@section.block)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Filters
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
base.send :helper_method, :filters_config
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def filter(attribute, options = {})
|
11
|
+
return false if attribute.nil?
|
12
|
+
@filters ||= []
|
13
|
+
@filters << options.merge(:attribute => attribute)
|
14
|
+
end
|
15
|
+
|
16
|
+
def filters_config
|
17
|
+
@filters && @filters.any? ? @filters : default_filters_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset_filters!
|
21
|
+
@filters = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a sane set of filters by default for the object
|
25
|
+
def default_filters_config
|
26
|
+
default_association_filters + default_content_filters
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a default set of filters for the associations
|
30
|
+
def default_association_filters
|
31
|
+
if resource_class.respond_to?(:reflections)
|
32
|
+
resource_class.reflections.collect{|name, r| { :attribute => name }}
|
33
|
+
else
|
34
|
+
[]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns a default set of filters for the content columns
|
39
|
+
def default_content_filters
|
40
|
+
if resource_class.respond_to?(:content_columns)
|
41
|
+
resource_class.content_columns.collect{|c| { :attribute => c.name.to_sym } }
|
42
|
+
else
|
43
|
+
[]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def filters_config
|
50
|
+
self.class.filters_config
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
class FormBuilder < FormBuilder
|
55
|
+
|
56
|
+
def filter(method, options = {})
|
57
|
+
return "" if method.nil? || method == ""
|
58
|
+
options[:as] ||= default_filter_type(method)
|
59
|
+
return "" unless options[:as]
|
60
|
+
content = skip_form_buffers do
|
61
|
+
send("filter_#{options.delete(:as)}_input", method, options)
|
62
|
+
end
|
63
|
+
@form_buffers.last << template.content_tag(:div, content, :class => "filter-form-field")
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def filter_string_input(method, options = {})
|
69
|
+
field_name = "#{method}_contains"
|
70
|
+
|
71
|
+
[ label(field_name, "Search #{method.to_s.titlecase}"),
|
72
|
+
text_field(field_name)
|
73
|
+
].join("\n").html_safe
|
74
|
+
end
|
75
|
+
|
76
|
+
def filter_date_range_input(method, options = {})
|
77
|
+
gt_field_name = "#{method}_gte"
|
78
|
+
lt_field_name = "#{method}_lte"
|
79
|
+
|
80
|
+
[ label(gt_field_name, method.to_s.titlecase),
|
81
|
+
filter_date_text_field(gt_field_name),
|
82
|
+
" - ",
|
83
|
+
filter_date_text_field(lt_field_name)
|
84
|
+
].join("\n").html_safe
|
85
|
+
end
|
86
|
+
|
87
|
+
def filter_date_text_field(method)
|
88
|
+
current_value = @object.send(method)
|
89
|
+
text_field(method, :size => 12, :class => "datepicker", :max => 10, :value => current_value.respond_to?(:strftime) ? current_value.strftime("%Y-%m-%d") : "")
|
90
|
+
end
|
91
|
+
|
92
|
+
def filter_numeric_input(method, options = {})
|
93
|
+
filters = numeric_filters_for_method(method, options.delete(:filters) || default_numeric_filters)
|
94
|
+
current_filter = current_numeric_scope(filters)
|
95
|
+
filter_select = @template.select_tag '', @template.options_for_select(filters, current_filter),
|
96
|
+
:onchange => "document.getElementById('#{method}_numeric').name = 'q[' + this.value + ']';"
|
97
|
+
filter_input = text_field current_filter, :size => 10, :id => "#{method}_numeric"
|
98
|
+
|
99
|
+
[ label(method),
|
100
|
+
filter_select,
|
101
|
+
" ",
|
102
|
+
filter_input
|
103
|
+
].join("\n").html_safe
|
104
|
+
end
|
105
|
+
|
106
|
+
def numeric_filters_for_method(method, filters)
|
107
|
+
filters.collect{|scope| [scope[0], [method,scope[1]].join("_") ] }
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the scope for which we are currently searching. If no search is available
|
111
|
+
# it returns the first scope
|
112
|
+
def current_numeric_scope(filters)
|
113
|
+
filters[1..-1].inject(filters.first){|a,b| object.send(b[1].to_sym) ? b : a }[1]
|
114
|
+
end
|
115
|
+
|
116
|
+
def default_numeric_filters
|
117
|
+
[['Equal To', 'eq'], ['Greater Than', 'gt'], ['Less Than', 'lt']]
|
118
|
+
end
|
119
|
+
|
120
|
+
def filter_select_input(method, options = {})
|
121
|
+
association_name = method.to_s.gsub(/_id$/, '').to_sym
|
122
|
+
input_name = (generate_association_input_name(method).to_s + "_eq").to_sym
|
123
|
+
collection = find_collection_for_column(association_name, options)
|
124
|
+
|
125
|
+
[ label(input_name, method.to_s.titlecase),
|
126
|
+
select(input_name, collection, options.merge(:include_blank => 'Any'))
|
127
|
+
].join("\n").html_safe
|
128
|
+
end
|
129
|
+
|
130
|
+
def filter_check_boxes_input(method, options = {})
|
131
|
+
input_name = (generate_association_input_name(method).to_s + "_in").to_sym
|
132
|
+
collection = find_collection_for_column(method, options)
|
133
|
+
selected_values = @object.send(input_name) || []
|
134
|
+
checkboxes = collection.map do |c|
|
135
|
+
label = c.is_a?(Array) ? c.first : c
|
136
|
+
value = c.is_a?(Array) ? c.last : c
|
137
|
+
"<label><input type=\"checkbox\" name=\"q[#{input_name}][]\" value=\"#{value}\" #{selected_values.include?(value) ? "checked" : ""}/> #{label}</label>"
|
138
|
+
end.join("\n").html_safe
|
139
|
+
|
140
|
+
[ label(input_name, method.to_s.titlecase),
|
141
|
+
checkboxes
|
142
|
+
].join("\n").html_safe
|
143
|
+
end
|
144
|
+
|
145
|
+
# Override the standard finder to accept a proc
|
146
|
+
def find_collection_for_column(method, options = {})
|
147
|
+
options = options.dup
|
148
|
+
case options[:collection]
|
149
|
+
when Proc
|
150
|
+
options[:collection] = options[:collection].call
|
151
|
+
end
|
152
|
+
super(method, options)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns the default filter type for a given attribute
|
156
|
+
def default_filter_type(method)
|
157
|
+
if column = column_for(method)
|
158
|
+
case column.type
|
159
|
+
when :date, :datetime
|
160
|
+
return :date_range
|
161
|
+
when :string, :text
|
162
|
+
return :string
|
163
|
+
when :integer
|
164
|
+
return :select if method.to_s =~ /_id$/
|
165
|
+
return :numeric
|
166
|
+
when :float, :decimal
|
167
|
+
return :numeric
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
if reflection = reflection_for(method)
|
172
|
+
return :select if reflection.macro == :belongs_to
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns the column for an attribute on the object being searched
|
177
|
+
# if it exists. Otherwise returns nil
|
178
|
+
def column_for(method)
|
179
|
+
@object.base.columns_hash[method.to_s] if @object.base.respond_to?(:columns_hash)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the association reflection for the method if it exists
|
183
|
+
def reflection_for(method)
|
184
|
+
@object.base.reflect_on_association(method) if @object.base.respond_to?(:reflect_on_association)
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|