class CckForms::ParameterTypeClass::Checkboxes

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

Public Class Methods

demongoize_value(value, parameter_type_class=nil) click to toggle source
'kazakh', 'english'

-> {'kazakh' => 1, 'russain' => 0, 'english' => 1}

(for for builders)

# 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) click to toggle source

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).

# 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

Public Instance Methods

build_form(form_builder, options) click to toggle source

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
# 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
mongoize() click to toggle source

{kazakh: '1', russian: '0', english: '1'} -> ['kazakh', 'english']

# 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
to_s(options = nil) click to toggle source

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, ..."
# 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

Private Instance Methods

build_select_form(form_builder, options) click to toggle source

options:

only      - see #to_s
except    - see #to_s
required  - HTML required attr
# File lib/cck_forms/parameter_type_class/checkboxes.rb, line 193
def build_select_form(form_builder, options)
  set_value_in_hash options

  values = valid_values_enum
  if options[:only]
    options[:only] = [options[:only]] unless options[:only].is_a? Array
    values.select! { |o| o[1].in? options[:only] }
  end

  if options[:except]
    options[:except] = [options[:except]] unless options[:except].is_a? Array
    values.reject! { |o| o[1].in? options[:except] }
  end

  form_builder.select :value, values, {selected: options[:value], required: options[:required], include_blank: !options[:required]}, class: 'form-control'
end
extract_data_for_key(request_key, data) click to toggle source
# File lib/cck_forms/parameter_type_class/checkboxes.rb, line 210
def extract_data_for_key(request_key, data)
  data.reduce({}) do |r, (key, values)|
    r[key] = values[request_key] if values[request_key]
    r
  end
end