Class: CckForms::ParameterTypeClass::Checkboxes

Inherits:
Object
  • Object
show all
Includes:
Base
Defined in:
lib/cck_forms/parameter_type_class/checkboxes.rb

Overview

Represents a series of checkboxes. The values are take from valid_values, see base.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.demongoize_value(value, parameter_type_class = nil) ⇒ Object

‘kazakh’, ‘english’

-> => 1, ‘russain’ => 0, ‘english’ => 1

(for for builders)



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/cck_forms/parameter_type_class/checkboxes.rb', line 27

def self.demongoize_value(value, parameter_type_class=nil)
  value.present? or return {}

  valid_values = parameter_type_class.try!(:valid_values) || value.map { |x| [x, nil] }
  valid_values = valid_values.reduce({}) do |r, (key, _)|
    r[key] = value.include?(key) ? '1' : '0'
    r
  end

  valid_values    = valid_values.dup
  priority_values = valid_values.extract!(*(value.respond_to?(:keys) ? value.keys : value))
  priority_values.merge valid_values
end

.emit_map_reduce(field_name) ⇒ Object

Construct emit func for map/reduce to emit on each array value in MongoDB. For example, for object:

cck_params.city: ['almaty', 'astana']

we will emit(‘almaty’, 1); emit(‘astana’, 1).



127
128
129
130
131
132
133
134
# File 'lib/cck_forms/parameter_type_class/checkboxes.rb', line 127

def self.emit_map_reduce(field_name)
  field_name = 'this.' + field_name
  return "if(#{field_name} && #{field_name} instanceof Array) {
    #{field_name}.forEach(function(key) {
      emit(key, 1)
    })
  }"
end

Instance Method Details

#build_form(form_builder, options) ⇒ Object

options:

block   - sprintf template for each entry (input, label)
map     - convert entry labels, e.g. 'long label text' => 'sh.txt'
data    - data-attrs for label, Hash (e.g. capital: {almaty: 'yes', astana: 'no'})
as      - if :select, construct a SELECT, not a checkboxes list
only    - see #to_s
except  - see #to_s
for     - if :search, do not add false-value checkbox


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/cck_forms/parameter_type_class/checkboxes.rb', line 145

def build_form(form_builder, options)
  return '' unless valid_values.is_a?(Hash) || valid_values.is_a?(Array)

  if options.is_a? Hash and options[:as] == :select
    return build_select_form(form_builder, options.except(:for, :as))
  end

  options = {block: '<div class="form_check_box_block">%s %s</div>', map: {}}.merge(options)

  set_value_in_hash options
  val = options[:value]

  result          = ''
  valid_values    = self.valid_values.dup
  valid_values    = valid_values.is_a?(Hash) ? valid_values : valid_values.zip([])
  priority_values = valid_values.extract!(*(value.respond_to?(:keys) ? value.keys : value))

  priority_values.merge(valid_values).each_pair do |k, v|
    next if options[:only] && options[:only] != k && !options[:only].try(:include?, k)

    result += form_builder.fields_for :value do |ff|

      begin
        checked = !val.try(:[], k).to_i.zero?
      rescue
        checked = false
      end

      v = options[:map][v] || v

      # skip `required` since form will not be submitted unless a user checks all the checkboxes
      data = options[:data] ? extract_data_for_key(k, options[:data]) : nil
      sprintf(options[:block], ff.check_box(k.to_sym, {checked: checked}, '1', options[:for] == :search ? nil : '0'), ff.label(k.to_sym, v, data: data)).html_safe
    end
  end

  sprintf '<div class="checkboxes" id="%1$s">%2$s</div><script type="text/javascript">$(function() {$("#%1$s").checkboxes()})</script>', form_builder_name_to_id(form_builder), result
end

#mongoizeObject

‘1’, russian: ‘0’, english: ‘1’ -> [‘kazakh’, ‘english’]



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/cck_forms/parameter_type_class/checkboxes.rb', line 7

def mongoize
  resulting_set = []

  if value.is_a? Array
    return value
  elsif value.is_a?(String) || value.is_a?(Symbol)
    return [value.to_s]
  elsif !value.is_a?(Hash)
    return []
  end

  value.each do |key, value|
    resulting_set << key if value.to_s == '1'
  end

  resulting_set
end

#search(selectable, field, query) ⇒ Object

Construct Mongoid query from our internal. If query is a Hash, find all objects where field has ALL of the Hash keys. Key ‘all’ selected all objects.

Otherwise, use usual where(field => query).



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/cck_forms/parameter_type_class/checkboxes.rb', line 102

def search(selectable, field, query)
  if query.respond_to? :each_pair
    keys = []
    query.each_pair do |key, value|
      if value.present? && value != '0'
        if key == 'any'
          selectable = selectable.where(field.to_sym.ne => [])
        else
          keys << key
        end
      end
    end
    selectable = selectable.where(field.to_sym.all => keys) if keys.any?
  else
    selectable = selectable.where(field.to_s => query)
  end

  selectable
end

#to_s(options = nil) ⇒ Object

Comma-separated list of checked entries. Options:

block   - sprintf template for each entry
only    - leave only these keys (array/string)
except  - reverse of :only
glue    - use instead of ', ' for .join
short   - make the string shorter, if possible: if all variants are checked, returns string "all selected"
          if few are not checked, returns "all except xxx, yyy, ..."


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/cck_forms/parameter_type_class/checkboxes.rb', line 49

def to_s(options = nil)
  checked_keys, checked_elements = [], []
  return '' if value.blank?

  template = '%s'
  if options
    options = {block: options} unless options.is_a? Hash
    template = options[:block] if options[:block]
  else
    options = {}
  end

  if value.respond_to? :each_pair
    value.each_pair do |k, v|
      include = v == '1' && (!options[:only] || options[:only] && options[:only] == k)
      exclude = options[:except] && options[:except] == k
      if include && !exclude
        checked_elements << sprintf(template, valid_values[k])
        checked_keys << k
      end
    end
  elsif value.respond_to? :each
    value.each do |k|
      exclude = options[:except] && options[:except] == k
      unless exclude
        checked_elements << sprintf(template, valid_values[k])
        checked_keys << k
      end
    end
  end

  glue = options[:glue] || ', '
  if options[:short] && checked_keys
    all_keys        = valid_values.keys
    unchecked_keys  = all_keys - checked_keys
    unchecked_num   = unchecked_keys.count

    param_title = cck_parameter ? " «#{cck_parameter.title}»" : ''

    if unchecked_num == 0
      return I18n.t('cck_forms.checkboxes.all_values', param_title: param_title)
    elsif unchecked_num < checked_keys.count./(2).round
      return I18n.t('cck_forms.checkboxes.all_values_except', param_title: param_title) + ' ' + valid_values.values_at(*unchecked_keys).map { |x| sprintf(template, x) }.join(glue)
    end
  end

  checked_elements.join glue
end