-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
field.rb
129 lines (111 loc) · 4.54 KB
/
field.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright (c) 2008-2013 Michael Dvorkin and contributors.
#
# Fat Free CRM is freely distributable under the terms of MIT license.
# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php
#------------------------------------------------------------------------------
# == Schema Information
#
# Table name: fields
#
# id :integer not null, primary key
# type :string(255)
# field_group_id :integer
# position :integer
# pair_id :integer
# name :string(64)
# label :string(128)
# hint :string(255)
# placeholder :string(255)
# as :string(32)
# collection :text
# disabled :boolean
# required :boolean
# maxlength :integer
# created_at :datetime
# updated_at :datetime
#
class Field < ActiveRecord::Base
acts_as_list
serialize :collection, Array
serialize :settings, HashWithIndifferentAccess
belongs_to :field_group
scope :core_fields, -> { where(type: 'CoreField') }
scope :custom_fields, -> { where("type != 'CoreField'") }
scope :without_pairs, -> { where(pair_id: nil) }
delegate :klass, :klass_name, :klass_name=, to: :field_group
BASE_FIELD_TYPES = {
'string' => { klass: 'CustomField', type: 'string' },
'text' => { klass: 'CustomField', type: 'text' },
'email' => { klass: 'CustomField', type: 'string' },
'url' => { klass: 'CustomField', type: 'string' },
'tel' => { klass: 'CustomField', type: 'string' },
'select' => { klass: 'CustomField', type: 'string' },
'radio_buttons' => { klass: 'CustomField', type: 'string' },
'check_boxes' => { klass: 'CustomField', type: 'text' },
'boolean' => { klass: 'CustomField', type: 'boolean' },
'date' => { klass: 'CustomField', type: 'date' },
'datetime' => { klass: 'CustomField', type: 'timestamp' },
'decimal' => { klass: 'CustomField', type: 'decimal', column_options: { precision: 15, scale: 2 } },
'integer' => { klass: 'CustomField', type: 'integer' },
'float' => { klass: 'CustomField', type: 'float' }
}.with_indifferent_access
validates_presence_of :label, message: "^Please enter a field label."
validates_length_of :label, maximum: 64, message: "^The field name must be less than 64 characters in length."
validates_numericality_of :maxlength, only_integer: true, allow_blank: true, message: "^Max size can only be whole number."
validates_presence_of :as, message: "^Please specify a field type."
validates_inclusion_of :as, in: proc { field_types.keys }, message: "^Invalid field type.", allow_blank: true
def column_type(field_type = as)
(opts = Field.field_types[field_type]) ? opts[:type] : fail("Unknown field_type: #{field_type}")
end
def input_options
input_html = {}
attributes.reject do |k, v|
!%w(as collection disabled label placeholder required maxlength).include?(k) || v.blank?
end.symbolize_keys.merge(input_html)
end
def collection_string=(value)
self.collection = value.split("|").map(&:strip).reject(&:blank?)
end
def collection_string
collection.try(:join, "|")
end
def render_value(object)
render object.send(name)
end
def render(value)
case as
when 'checkbox'
value.to_s == '0' ? "no" : "yes"
when 'date'
value && value.strftime(I18n.t("date.formats.mmddyy"))
when 'datetime'
value && value.in_time_zone.strftime(I18n.t("time.formats.mmddyyyy_hhmm"))
when 'check_boxes'
value.select(&:present?).in_groups_of(2, false).map { |g| g.join(', ') }.join("<br />".html_safe) if Array === value
else
value.to_s
end
end
protected
class << self
# Provides access to registered field_types
#------------------------------------------------------------------------------
def field_types
@@field_types ||= BASE_FIELD_TYPES
end
# Register custom fields so they are available to the rest of the app
# Example options: :as => 'datepair', :type => 'date', :klass => 'CustomFieldDatePair'
#------------------------------------------------------------------------------
def register(options)
opts = options.dup
as = options.delete(:as)
(@@field_types ||= BASE_FIELD_TYPES).merge!(as => options)
end
# Returns class name given a key
#------------------------------------------------------------------------------
def lookup_class(as)
(@@field_types ||= BASE_FIELD_TYPES)[as][:klass]
end
end
ActiveSupport.run_load_hooks(:fat_free_crm_field, self)
end