Module: SimpleAdmin::FilterHelper

Included in:
AdminHelper
Defined in:
app/helpers/simple_admin/filter_helper.rb

Instance Method Summary collapse

Instance Method Details

#boolean_collection(klass, column, options) ⇒ Object



148
149
150
# File 'app/helpers/simple_admin/filter_helper.rb', line 148

def boolean_collection(klass, column, options)
  [['No', false], ['Yes', true]]
end

#column_for(klass, method) ⇒ Object

Returns the column for an attribute on the object being searched if it exists. Otherwise returns nil



208
209
210
# File 'app/helpers/simple_admin/filter_helper.rb', line 208

def column_for(klass, method)
  klass.columns_hash[method.to_s] if klass.respond_to?(:columns_hash)
end

#current_numeric_scope(klass, filters) ⇒ Object

Returns the scope for which we are currently searching. If no search is available it returns the first scope



87
88
89
# File 'app/helpers/simple_admin/filter_helper.rb', line 87

def current_numeric_scope(klass, filters)
  filters[1..-1].inject(filters.first){|a,b| params[b[1].to_sym] ? b : a }[1]
end

#default_filter_type(klass, method) ⇒ Object

Returns the default filter type for a given attribute



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'app/helpers/simple_admin/filter_helper.rb', line 184

def default_filter_type(klass, method)
  if column = column_for(klass, method)
    case column.type
    when :date, :datetime
      return :date_range
    when :string, :text
      return :string
    when :integer
      return :select if reflection_for(klass, method.to_s.gsub('_id','').to_sym)
      return :numeric
    when :float, :decimal
      return :numeric
    when :boolean
      return :boolean
    end
  end

  if reflection = reflection_for(klass, method)
    return :select if reflection.macro == :belongs_to && !reflection.options[:polymorphic]
  end
end

#default_numeric_filtersObject



91
92
93
# File 'app/helpers/simple_admin/filter_helper.rb', line 91

def default_numeric_filters
  [['Equal To', 'eq'], ['Greater Than', 'gt'], ['Less Than', 'lt']]
end

#filter_boolean_input(klass, method, options = {}) ⇒ Object



152
153
154
155
156
157
158
159
160
# File 'app/helpers/simple_admin/filter_helper.rb', line 152

def filter_boolean_input(klass, method, options = {})
  field_name = options[:name] || (generate_association_input_name(klass, method).to_s + "_in")
  label_content = options[:title] || options[:label] || "#{method.to_s.titlecase}" unless options[:label] == false

  content = []
  content << check_box_tag(field_name, true, params[field_name.to_sym], options)
  content << label(field_name, label_content) unless label_content.blank?
  content.join("\n").html_safe
end

#filter_check_boxes_input(klass, method, options = {}) ⇒ Object Also known as: filter_checkboxes_input



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/helpers/simple_admin/filter_helper.rb', line 162

def filter_check_boxes_input(klass, method, options = {})
  field_name = options[:name] || (generate_association_input_name(klass, method).to_s + "_in")
  collection = find_collection_for_column(klass, method, options)
  selected_values = params[field_name.to_sym] || []
  checkboxes =  :div, :class => "check_boxes_wrapper" do
    collection.map do |c|
      label = c.is_a?(Array) ? c.first : c
      value = c.is_a?(Array) ? c.last : c
      "<label><input type=\"checkbox\" name=\"#{field_name}[]\" value=\"#{value}\" #{selected_values.include?(value) ? "checked" : ""}/> #{label}</label>"
    end.join("\n").html_safe
  end
  label_content = options[:title] || options[:label] || "#{method.to_s.titlecase}" unless options[:label] == false

  content = []
  content << label(field_name, label_content) unless label_content.blank?
  content << checkboxes
  content.join("\n").html_safe
end

#filter_date_range_input(klass, method, options = {}) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/helpers/simple_admin/filter_helper.rb', line 48

def filter_date_range_input(klass, method, options = {})
  gt_field_name = "#{method}_gteq"
  lt_field_name = "#{method}_lteq"
  label_content =  options[:title] || options[:label] || "#{method.to_s.titlecase}" unless options[:label] == false

  content = []
  content << label(gt_field_name, label_content) unless label_content.blank?
  content << filter_date_text_field(klass, gt_field_name)
  content << " - "
  content << filter_date_text_field(klass, lt_field_name)
  content.join("\n").html_safe
end

#filter_date_text_field(klass, method) ⇒ Object



61
62
63
64
# File 'app/helpers/simple_admin/filter_helper.rb', line 61

def filter_date_text_field(klass, method)
  current_value = params[method] || ''
  text_field_tag(method, current_value.respond_to?(:strftime) ? current_value.strftime("%Y-%m-%d") : current_value, :size => 12, :class => "datepicker", :max => 10)
end

#filter_fields(attributes) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/helpers/simple_admin/filter_helper.rb', line 3

def filter_fields(attributes)
  attributes.map do |col|
    options = col[:options].dup
    expand_block_options!(options)
    case col[:kind]
    when :attribute, :filter
      filter_for(col[:attribute], @interface.constant, options)
    when :content
      instance_exec(self, &col[:data])
    when :fieldset
       :fieldset, options do
         :legend do
          options[:legend]
        end unless options[:legend].blank
        filter_fields(col[:attributes])
      end
    else
       :div, options do
        filter_fields(col[:attributes])
      end
    end
  end.join.html_safe
end

#filter_for(method, klass, options = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'app/helpers/simple_admin/filter_helper.rb', line 27

def filter_for(method, klass, options={})
  options[:as] ||= default_filter_type(klass, method)
  return "" unless options[:as]
  field_type = options.delete(:as)
  wrapper_options = options[:wrapper_html] || {}
  wrapper_options[:class] = (wrapper_options[:class] || "") + " filter_form_field filter_#{field_type}"
   :div, wrapper_options do
    send("filter_#{field_type}_input", klass, method, options)
  end
end

#filter_numeric_input(klass, method, options = {}) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/helpers/simple_admin/filter_helper.rb', line 66

def filter_numeric_input(klass, method, options = {})
  field_name = "#{method}_numeric"
  filters = numeric_filters_for_method(method, options.delete(:filters) || default_numeric_filters)
  current_filter = current_numeric_scope(klass, filters)
  label_content = options[:title] || options[:label] || "#{method.to_s.titlecase}" unless options[:label] == false

  content = []
  content << label(field_name, label_content) unless label_content.blank?
  content << select_tag('', options_for_select(filters, current_filter),
    {:onchange => "document.getElementById('#{method}_numeric').name = '' + this.value + '';"}.merge(options[:input_html] || {}))
  content << " "
  content << text_field_tag(current_filter, params[current_filter] || '', {:size => 10, :id => field_name}.merge(options[:input_html] || {}))
  content.join("\n").html_safe
end

#filter_select_input(klass, method, options = {}) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'app/helpers/simple_admin/filter_helper.rb', line 95

def filter_select_input(klass, method, options = {})
  association_name = method.to_s.gsub(/_id$/, '').to_sym
  field_name = if reflection = reflection_for(klass, association_name)
    if [:has_and_belongs_to_many, :has_many].include?(reflection.macro)
      "#{association_name.to_s.singularize}_ids"
    else
      reflection.options[:foreign_key] || "#{association_name}_id"
    end
  else
    association_name
  end
  field_name = (field_name.to_s + "_eq")
  collection = find_collection_for_column(klass, association_name, options)
  label_content = options[:title] || options[:label] || "#{method.to_s.titlecase}" unless options[:label] == false

  content = []
  content << label(field_name, label_content) unless label_content.blank?
  content << select_tag(field_name, options_for_select(collection, params[field_name.to_sym]),
    {:include_blank => options[:include_blank] || 'Any'}.merge(options[:input_html] || {}))
  content.join("\n").html_safe
end

#filter_string_input(klass, method, options = {}) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'app/helpers/simple_admin/filter_helper.rb', line 38

def filter_string_input(klass, method, options = {})
  field_name = "#{method}_cont"
  label_content =  options[:title] || options[:label] || "Search #{method.to_s.titlecase}" unless options[:label] == false

  content = []
  content << label(field_name, label_content) unless label_content.blank?
  content << text_field_tag(field_name, params[field_name] || '', options[:input_html] || {})
  content.join("\n").html_safe
end

#find_collection_for_column(klass, column, options) ⇒ Object

:nodoc:



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/helpers/simple_admin/filter_helper.rb', line 129

def find_collection_for_column(klass, column, options) #:nodoc:
Rails.logger.info("******** find_collection_for_column #{klass}, #{column}, #{options.to_json}")
   collection = if options[:collection]
     collection = options.delete(:collection)
     collection = collection.to_a if collection.is_a?(Hash)
     collection.map { |o| [pretty_format(o.first), o.last] }
   elsif reflection = reflection_for(klass, column)
     options[:find_options] ||= {}
     if conditions = reflection.options[:conditions]
       options[:find_options][:conditions] = reflection.klass.merge_conditions(conditions, options[:find_options][:conditions])
     end
     collection = reflection.klass.find(:all, options[:find_options])
     collection.map { |o| [pretty_format(o), o.id] }
   else
     boolean_collection(klass, column, options)
   end
   collection
end

#generate_association_input_name(klass, method) ⇒ Object

:nodoc:



117
118
119
120
121
122
123
124
125
126
127
# File 'app/helpers/simple_admin/filter_helper.rb', line 117

def generate_association_input_name(klass, method) #:nodoc:
  if reflection = reflection_for(klass, method)
    if [:has_and_belongs_to_many, :has_many].include?(reflection.macro)
      "#{method.to_s.singularize}_ids"
    else
      reflection.options[:foreign_key] || "#{method}_id"
    end
  else
    method
  end.to_sym
end

#numeric_filters_for_method(method, filters) ⇒ Object



81
82
83
# File 'app/helpers/simple_admin/filter_helper.rb', line 81

def numeric_filters_for_method(method, filters)
  filters.collect{|scope| [scope[0], [method,scope[1]].join("_") ] }
end

#reflection_for(klass, method) ⇒ Object

Returns the association reflection for the method if it exists



213
214
215
# File 'app/helpers/simple_admin/filter_helper.rb', line 213

def reflection_for(klass, method)
  klass.reflect_on_association(method) if klass.respond_to?(:reflect_on_association)
end