formbuilder-rb 0.0.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +219 -0
- data/Guardfile +17 -0
- data/{MIT-LICENSE → LICENSE.md} +1 -1
- data/README.md +86 -0
- data/app/controllers/formbuilder/concerns/forms_controller.rb +59 -0
- data/app/models/formbuilder/entry_attachment.rb +2 -8
- data/app/models/formbuilder/form.rb +53 -0
- data/app/models/formbuilder/response_field.rb +23 -10
- data/app/models/formbuilder/response_field_address.rb +12 -1
- data/app/models/formbuilder/response_field_checkboxes.rb +38 -0
- data/app/models/formbuilder/response_field_date.rb +7 -1
- data/app/models/formbuilder/response_field_dropdown.rb +2 -1
- data/app/models/formbuilder/response_field_email.rb +14 -2
- data/app/models/formbuilder/response_field_file.rb +75 -20
- data/app/models/formbuilder/response_field_number.rb +9 -2
- data/app/models/formbuilder/response_field_page_break.rb +13 -0
- data/app/models/formbuilder/response_field_paragraph.rb +19 -3
- data/app/models/formbuilder/response_field_price.rb +10 -6
- data/app/models/formbuilder/response_field_radio.rb +11 -2
- data/app/models/formbuilder/response_field_section_break.rb +12 -2
- data/app/models/formbuilder/response_field_table.rb +222 -0
- data/app/models/formbuilder/response_field_text.rb +9 -2
- data/app/models/formbuilder/response_field_time.rb +8 -1
- data/app/models/formbuilder/response_field_website.rb +26 -2
- data/app/uploaders/formbuilder/entry_attachment_uploader.rb +11 -1
- data/bin/rails +8 -0
- data/circle.yml +9 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20130924185815_create_formbuilder_entry_attachments.rb +1 -0
- data/formbuilder-rb.gemspec +41 -0
- data/formbuilder-rb.sublime-project +20 -0
- data/lib/formbuilder.rb +8 -3
- data/lib/formbuilder/entry.rb +102 -159
- data/lib/formbuilder/entry_validator.rb +13 -6
- data/lib/formbuilder/version.rb +1 -1
- data/lib/formbuilder/views/entry_dl.rb +56 -0
- data/lib/formbuilder/views/form.rb +81 -0
- data/lib/formbuilder/views/form_field.rb +45 -0
- data/spec/controllers/formbuilder/forms_controller_spec.rb +40 -0
- data/spec/dummy/.ruby-gemset +1 -0
- data/spec/dummy/.ruby-version +1 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/forms_controller.rb +3 -0
- data/spec/dummy/app/controllers/test_controller.rb +57 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/entry.rb +7 -0
- data/spec/dummy/app/models/entry_with_alternate_column_name.rb +11 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/test/_form.rb +2 -0
- data/spec/dummy/app/views/test/render_entry.html.erb +1 -0
- data/spec/dummy/app/views/test/show_form.html.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +25 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml.ci +15 -0
- data/spec/dummy/config/database.yml.example +15 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +52 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +12 -0
- data/spec/dummy/db/migrate/20130924182939_create_entries.rb +13 -0
- data/spec/dummy/db/migrate/20130924192151_create_formbuilder_forms.formbuilder.rb +11 -0
- data/spec/dummy/db/migrate/20130924192152_create_formbuilder_response_fields.formbuilder.rb +17 -0
- data/spec/dummy/db/migrate/20130926205845_create_formbuilder_entry_attachments.formbuilder.rb +12 -0
- data/spec/dummy/db/migrate/20140128000000_create_entry_with_alternate_column_names.rb +13 -0
- data/spec/dummy/db/schema.rb +64 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/test/fixtures/entries.yml +9 -0
- data/spec/dummy/test/fixtures/response_fields.yml +19 -0
- data/spec/dummy/test/models/entry_test.rb +7 -0
- data/spec/dummy/test/models/response_field_test.rb +7 -0
- data/spec/factories/formbuilder_forms.rb +45 -0
- data/spec/features/form_renderer_spec.rb +30 -0
- data/spec/features/submitting_an_entry_spec.rb +79 -0
- data/spec/fixtures/test_files/text.txt +1 -0
- data/spec/fixtures/test_files/text2.txt +1 -0
- data/spec/lib/formbuilder/entry_spec.rb +199 -0
- data/spec/lib/formbuilder/entry_validator_spec.rb +215 -0
- data/spec/lib/formbuilder/entry_with_alternate_column_name_spec.rb +37 -0
- data/spec/lib/formbuilder/views/entry_dl_spec.rb +38 -0
- data/spec/models/formbuilder/entry_attachment_spec.rb +17 -0
- data/spec/models/formbuilder/form_spec.rb +100 -0
- data/spec/models/formbuilder/response_field_address_spec.rb +25 -0
- data/spec/models/formbuilder/response_field_checkboxes_spec.rb +57 -0
- data/spec/models/formbuilder/response_field_file_spec.rb +80 -0
- data/spec/models/formbuilder/response_field_paragraph_spec.rb +22 -0
- data/spec/models/formbuilder/response_field_radio_spec.rb +30 -0
- data/spec/models/formbuilder/response_field_spec.rb +21 -0
- data/spec/models/formbuilder/response_field_table_spec.rb +124 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/database_cleaner.rb +21 -0
- data/spec/support/submitting_an_entry_spec_helper.rb +151 -0
- metadata +286 -44
- data/app/controllers/formbuilder/forms_controller.rb +0 -53
- data/lib/formbuilder/entry_renderer.rb +0 -47
- data/lib/formbuilder/entry_table_renderer.rb +0 -58
- data/lib/formbuilder/form_renderer.rb +0 -102
data/bin/rails
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/formbuilder/engine', __FILE__)
|
|
6
|
+
|
|
7
|
+
require 'rails/all'
|
|
8
|
+
require 'rails/engine/commands'
|
data/circle.yml
ADDED
data/config/spring.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Spring.application_root = './spec/dummy'
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
2
|
+
|
|
3
|
+
# Maintain your gem's version:
|
|
4
|
+
require "formbuilder/version"
|
|
5
|
+
|
|
6
|
+
# Describe your gem and declare its dependencies:
|
|
7
|
+
Gem::Specification.new do |s|
|
|
8
|
+
s.name = "formbuilder-rb"
|
|
9
|
+
s.version = Formbuilder::VERSION
|
|
10
|
+
s.authors = ["Adam Becker"]
|
|
11
|
+
s.email = ["adam@dobt.co"]
|
|
12
|
+
s.homepage = "https://github.com/dobtco/formbuilder-rb"
|
|
13
|
+
s.summary = "Build and save custom forms."
|
|
14
|
+
s.description = "This is a Rails Engine for https://github.com/dobtco/formbuilder."
|
|
15
|
+
s.license = "MIT"
|
|
16
|
+
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {features,spec}/*`.split("\n")
|
|
19
|
+
|
|
20
|
+
s.add_dependency "rails", "4.1.0.rc1"
|
|
21
|
+
|
|
22
|
+
s.add_dependency 'carrierwave'
|
|
23
|
+
s.add_dependency 'erector-rails4'
|
|
24
|
+
s.add_dependency 'geocoder'
|
|
25
|
+
s.add_dependency 'pg'
|
|
26
|
+
s.add_dependency 'rinku'
|
|
27
|
+
s.add_dependency 'rmagick'
|
|
28
|
+
|
|
29
|
+
s.add_development_dependency 'capybara'
|
|
30
|
+
s.add_development_dependency 'database_cleaner'
|
|
31
|
+
s.add_development_dependency 'factory_girl_rails'
|
|
32
|
+
s.add_development_dependency 'guard-rspec'
|
|
33
|
+
s.add_development_dependency 'launchy'
|
|
34
|
+
s.add_development_dependency 'rspec-rails'
|
|
35
|
+
s.add_development_dependency 'spring'
|
|
36
|
+
s.add_development_dependency 'spring-commands-rspec'
|
|
37
|
+
s.add_development_dependency 'terminal-notifier-guard'
|
|
38
|
+
s.add_development_dependency 'thin'
|
|
39
|
+
s.add_development_dependency 'coveralls'
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"folders":
|
|
3
|
+
[
|
|
4
|
+
{
|
|
5
|
+
"path": ".",
|
|
6
|
+
"folder_exclude_patterns": ["coverage", "log", "tmp"],
|
|
7
|
+
"file_exclude_patterns": ["*.sublime-workspace", "*.sql"]
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
|
|
11
|
+
"settings":
|
|
12
|
+
{
|
|
13
|
+
// indentation
|
|
14
|
+
"tab_size": 2,
|
|
15
|
+
"translate_tabs_to_spaces": true,
|
|
16
|
+
"trim_trailing_white_space_on_save": true,
|
|
17
|
+
// ensure line endings is linux style (even when on Windows)
|
|
18
|
+
"default_line_ending": "LF"
|
|
19
|
+
}
|
|
20
|
+
}
|
data/lib/formbuilder.rb
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
# Require dependencies explicitly
|
|
2
|
+
require 'carrierwave'
|
|
3
|
+
require 'erector'
|
|
4
|
+
require 'geocoder'
|
|
5
|
+
|
|
1
6
|
require "formbuilder/engine"
|
|
2
7
|
require "formbuilder/entry"
|
|
3
|
-
require "formbuilder/entry_renderer"
|
|
4
|
-
require "formbuilder/entry_table_renderer"
|
|
5
8
|
require "formbuilder/entry_validator"
|
|
6
|
-
require "formbuilder/
|
|
9
|
+
require "formbuilder/views/form"
|
|
10
|
+
require "formbuilder/views/form_field"
|
|
11
|
+
require "formbuilder/views/entry_dl"
|
|
7
12
|
|
|
8
13
|
module Formbuilder
|
|
9
14
|
def self.root
|
data/lib/formbuilder/entry.rb
CHANGED
|
@@ -3,33 +3,82 @@ module Formbuilder
|
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
4
|
|
|
5
5
|
included do
|
|
6
|
-
attr_accessor :
|
|
7
|
-
|
|
6
|
+
attr_accessor :skip_validation, :only_validate_page
|
|
7
|
+
|
|
8
|
+
before_validation :normalize_responses
|
|
8
9
|
validates_with Formbuilder::EntryValidator
|
|
9
|
-
before_save :calculate_responses_text, if: :
|
|
10
|
-
|
|
10
|
+
before_save :calculate_responses_text, if: :responses_column_changed?
|
|
11
|
+
|
|
12
|
+
scope :order_by_response_field_value, -> (response_field, direction) {
|
|
13
|
+
if response_field.sort_as_numeric
|
|
14
|
+
order("(responses -> '#{response_field.id}_sortable_value') ::numeric #{direction} NULLS LAST")
|
|
15
|
+
else
|
|
16
|
+
order("LOWER(responses -> '#{response_field.id}_sortable_value') #{direction} NULLS LAST")
|
|
17
|
+
end
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
scope :order_by_response_field_checkbox_value, -> (response_field, option, direction) {
|
|
21
|
+
order("(CASE WHEN (responses -> '#{response_field.id}_sortable_values_#{option}') = 'true' THEN
|
|
22
|
+
1
|
|
23
|
+
ELSE
|
|
24
|
+
0
|
|
25
|
+
END) #{direction}".squish)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
scope :order_by_response_field_table_sum, -> (response_field, column, direction) {
|
|
29
|
+
order("(responses -> '#{response_field.id}_sum_#{column}') ::numeric #{direction}")
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def valid_page?(x)
|
|
34
|
+
self.valid?
|
|
35
|
+
!self.errors_on_page?(x)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def first_page_with_errors
|
|
39
|
+
if (i = pages_with_errors.find_index { |x| x == true })
|
|
40
|
+
i + 1
|
|
41
|
+
else
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def pages_with_errors
|
|
47
|
+
form.response_fields_by_page.map do |page|
|
|
48
|
+
page.find { |response_field| self.error_for(response_field).present? } ? true : false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def errors_on_page?(x)
|
|
53
|
+
pages_with_errors[x - 1] # 0-indexed
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def responses_column
|
|
57
|
+
@responses_column || 'responses'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def responses_column=(x)
|
|
61
|
+
@responses_column = x
|
|
11
62
|
end
|
|
12
63
|
|
|
13
|
-
def
|
|
14
|
-
|
|
64
|
+
def get_responses
|
|
65
|
+
send(responses_column)
|
|
66
|
+
end
|
|
15
67
|
|
|
16
|
-
|
|
68
|
+
def set_responses(x)
|
|
69
|
+
send("#{responses_column}=", x)
|
|
70
|
+
end
|
|
17
71
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
skip_validation: true # don't validate twice
|
|
21
|
-
)
|
|
72
|
+
def mark_responses_as_changed!
|
|
73
|
+
send("#{responses_column}_will_change!")
|
|
22
74
|
end
|
|
23
75
|
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
submitted_at: nil,
|
|
27
|
-
skip_validation: true
|
|
28
|
-
)
|
|
76
|
+
def responses_column_changed?
|
|
77
|
+
send("#{responses_column}_changed?")
|
|
29
78
|
end
|
|
30
79
|
|
|
31
|
-
def
|
|
32
|
-
|
|
80
|
+
def responses_column_was
|
|
81
|
+
send("#{responses_column}_was")
|
|
33
82
|
end
|
|
34
83
|
|
|
35
84
|
def value_present?(response_field)
|
|
@@ -49,13 +98,8 @@ module Formbuilder
|
|
|
49
98
|
return false
|
|
50
99
|
end
|
|
51
100
|
|
|
52
|
-
# checkboxes can have no values, yet still need to show up as unchecked
|
|
53
|
-
def value_present_or_checkboxes?(response_field)
|
|
54
|
-
response_field.field_type == 'checkboxes' || value_present?(response_field)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
101
|
def response_value(response_field)
|
|
58
|
-
value =
|
|
102
|
+
value = get_responses[response_field.id.to_s]
|
|
59
103
|
|
|
60
104
|
if value
|
|
61
105
|
response_field.serialized ? YAML::load(value) : value
|
|
@@ -66,176 +110,75 @@ module Formbuilder
|
|
|
66
110
|
end
|
|
67
111
|
end
|
|
68
112
|
|
|
69
|
-
def save_responses(response_field_params, response_fields)
|
|
70
|
-
|
|
71
|
-
self.responses = {}
|
|
113
|
+
def save_responses(response_field_params, response_fields, opts = {})
|
|
114
|
+
set_responses({}) unless opts[:partial_update]
|
|
72
115
|
|
|
73
|
-
response_fields.
|
|
74
|
-
self.save_response(response_field_params
|
|
116
|
+
response_fields.select { |rf| rf.input_field }.each do |response_field|
|
|
117
|
+
self.save_response(response_field_params[response_field.id.to_s], response_field, response_field_params)
|
|
75
118
|
end
|
|
76
119
|
end
|
|
77
120
|
|
|
78
121
|
def save_response(raw_value, response_field, response_field_params = {})
|
|
79
|
-
value =
|
|
80
|
-
when "checkboxes"
|
|
81
|
-
# transform checkboxes into {label => on/off} pairs
|
|
82
|
-
values = {}
|
|
83
|
-
|
|
84
|
-
(response_field[:field_options]["options"] || []).each_with_index do |option, index|
|
|
85
|
-
label = response_field.field_options["options"][index]["label"]
|
|
86
|
-
values[option["label"]] = raw_value && raw_value[index.to_s] == "on"
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
if raw_value && raw_value['other_checkbox'] == 'on'
|
|
90
|
-
values['Other'] = raw_value['other']
|
|
91
|
-
else
|
|
92
|
-
values.delete('Other') # @todo this might cause unexpected behavior to the user. we should hide/show the other field in the frontend, too
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Save 'other' value
|
|
96
|
-
responses["#{response_field.id}_other"] = raw_value && raw_value['other_checkbox'] == 'on' ?
|
|
97
|
-
true :
|
|
98
|
-
nil
|
|
99
|
-
|
|
100
|
-
values
|
|
101
|
-
|
|
102
|
-
when "file"
|
|
103
|
-
# if the file is already uploaded and we're not uploading another,
|
|
104
|
-
# be sure to keep it
|
|
105
|
-
if raw_value.blank?
|
|
106
|
-
if old_responses && old_responses[response_field.id.to_s]
|
|
107
|
-
old_responses[response_field.id.to_s]
|
|
108
|
-
end
|
|
109
|
-
else
|
|
110
|
-
remove_entry_attachment(responses[response_field.id.to_s]) if responses
|
|
111
|
-
attachment = EntryAttachment.create(upload: raw_value)
|
|
112
|
-
attachment.id
|
|
113
|
-
end
|
|
114
|
-
when "radio"
|
|
115
|
-
# Save 'other' value
|
|
116
|
-
responses["#{response_field.id}_other"] = raw_value == 'Other' ?
|
|
117
|
-
response_field_params["#{response_field.id}_other"] :
|
|
118
|
-
nil
|
|
119
|
-
|
|
120
|
-
raw_value
|
|
121
|
-
else
|
|
122
|
-
raw_value
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
self.responses ||= {}
|
|
122
|
+
value = response_field.transform_raw_value(raw_value, self, response_field_params: response_field_params)
|
|
126
123
|
|
|
127
124
|
if value.present?
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
get_responses["#{response_field.id}"] = response_field.serialized ? value.to_yaml : value
|
|
126
|
+
get_responses["#{response_field.id}_sortable_value"] = response_field.sortable_value(value)
|
|
127
|
+
else
|
|
128
|
+
get_responses.delete("#{response_field.id}")
|
|
129
|
+
get_responses.delete("#{response_field.id}_sortable_value")
|
|
130
130
|
end
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
mark_responses_as_changed!
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def destroy_response(response_field)
|
|
136
|
-
|
|
137
|
-
when "file"
|
|
138
|
-
self.remove_entry_attachment(responses[response_field.id.to_s])
|
|
139
|
-
end
|
|
140
|
-
|
|
136
|
+
response_field.before_response_destroyed(self)
|
|
141
137
|
id = response_field.id.to_s
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
self.responses_will_change! # hack to make sure column is marked as dirty
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def remove_entry_attachment(entry_attachment_id)
|
|
149
|
-
return unless entry_attachment_id.present?
|
|
150
|
-
EntryAttachment.where(id: entry_attachment_id).first.try(:destroy)
|
|
138
|
+
set_responses get_responses.reject { |k, v| k.in?([id, "#{id}_sortable_value"]) }
|
|
139
|
+
mark_responses_as_changed!
|
|
151
140
|
end
|
|
152
141
|
|
|
153
142
|
def error_for(response_field)
|
|
154
|
-
(self.errors.messages[:"
|
|
143
|
+
Array(self.errors.messages[:"#{responses_column}_#{response_field.id}"]).first
|
|
155
144
|
end
|
|
156
145
|
|
|
157
146
|
def calculate_responses_text
|
|
158
|
-
return unless self.respond_to?(:"
|
|
159
|
-
|
|
160
|
-
self.responses_text = selected_responses.values.join(' ')
|
|
147
|
+
return unless self.respond_to?(:"#{responses_column}_text=")
|
|
148
|
+
self.send(:"#{responses_column}_text=", get_responses.select { |k, v| Integer(k) rescue nil }.values.join(' '))
|
|
161
149
|
end
|
|
162
150
|
|
|
163
|
-
#
|
|
151
|
+
# for manual use, maybe when migrating
|
|
164
152
|
def calculate_sortable_values
|
|
165
|
-
response_fieldable.
|
|
166
|
-
|
|
153
|
+
response_fieldable.input_fields.each do |response_field|
|
|
154
|
+
if (x = response_value(response_field)).present?
|
|
155
|
+
get_responses["#{response_field.id}_sortable_value"] = response_field.sortable_value(x)
|
|
156
|
+
end
|
|
167
157
|
end
|
|
168
158
|
|
|
169
|
-
|
|
159
|
+
mark_responses_as_changed!
|
|
170
160
|
end
|
|
171
161
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
next unless value.present?
|
|
162
|
+
# Normalizations get run before validation.
|
|
163
|
+
def normalize_responses
|
|
164
|
+
return if form.blank?
|
|
176
165
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
coords = Geocoder.coordinates("#{value['street']} #{value['city']} #{value['state']} #{value['zipcode']} #{value['country']}")
|
|
181
|
-
self.responses["#{response_field.id}_x"] = coords[0]
|
|
182
|
-
self.responses["#{response_field.id}_y"] = coords[1]
|
|
183
|
-
rescue
|
|
184
|
-
self.responses["#{response_field.id}_x"] = nil
|
|
185
|
-
self.responses["#{response_field.id}_y"] = nil
|
|
186
|
-
end
|
|
166
|
+
form.response_fields.each do |response_field|
|
|
167
|
+
if (x = self.response_value(response_field))
|
|
168
|
+
response_field.normalize_response(x, get_responses)
|
|
187
169
|
end
|
|
188
170
|
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# def normalize_responses
|
|
192
|
-
# response_fieldable.response_fields.reject { |rf| !rf.input_field }.each do |response_field|
|
|
193
|
-
# value = response_value(response_field)
|
|
194
|
-
# next unless value.present?
|
|
195
171
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# unless value[/^http:\/\//] || value[/^https:\/\//]
|
|
199
|
-
# save_response("http://#{value}", response_field)
|
|
200
|
-
# end
|
|
201
|
-
# end
|
|
202
|
-
# end
|
|
203
|
-
# end
|
|
172
|
+
mark_responses_as_changed!
|
|
173
|
+
end
|
|
204
174
|
|
|
175
|
+
# Audits get run explicitly.
|
|
205
176
|
def audit_responses
|
|
206
177
|
form.response_fields.each do |response_field|
|
|
207
|
-
response_field.audit_response(self.response_value(response_field),
|
|
178
|
+
response_field.audit_response(self.response_value(response_field), get_responses)
|
|
208
179
|
end
|
|
209
|
-
end
|
|
210
180
|
|
|
211
|
-
|
|
212
|
-
return unless value.present?
|
|
213
|
-
|
|
214
|
-
self.responses["#{response_field.id}_sortable_value"] = case response_field.field_type
|
|
215
|
-
when "date"
|
|
216
|
-
['year', 'month', 'day'].each { |x| return 0 unless value[x] && !value[x].blank? }
|
|
217
|
-
DateTime.new(value['year'].to_i, value['month'].to_i, value['day'].to_i).to_i rescue 0
|
|
218
|
-
when "time"
|
|
219
|
-
hours = value['hours'].to_i
|
|
220
|
-
hours += 12 if value['am_pm'] && value['am_pm'] == 'PM'
|
|
221
|
-
(hours*60*60) + (value['minutes'].to_i * 60) + value['seconds'].to_i
|
|
222
|
-
when "file"
|
|
223
|
-
value ? 1 : 0
|
|
224
|
-
when "checkboxes"
|
|
225
|
-
calculate_sortable_value_for_checkboxes(response_field, value)
|
|
226
|
-
return nil
|
|
227
|
-
when "price"
|
|
228
|
-
"#{value['dollars'] || '0'}.#{value['cents'] || '0'}".to_f
|
|
229
|
-
else
|
|
230
|
-
# do we really need to sort more than the first 10 characters of a string?
|
|
231
|
-
value[0..10]
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def calculate_sortable_value_for_checkboxes(response_field, value)
|
|
236
|
-
(response_field.field_options['options'] || []).each do |option|
|
|
237
|
-
self.responses["#{response_field.id}_sortable_values_#{option['label']}"] = value[option['label']]
|
|
238
|
-
end
|
|
181
|
+
mark_responses_as_changed!
|
|
239
182
|
end
|
|
240
183
|
|
|
241
184
|
end
|
|
@@ -6,15 +6,22 @@ module Formbuilder
|
|
|
6
6
|
@record = record
|
|
7
7
|
|
|
8
8
|
# I guess it's valid if there's no form?
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
# It's also valid if it has already been submitted
|
|
12
|
-
return if record.submitted_at_was
|
|
9
|
+
return if record.form.blank?
|
|
13
10
|
|
|
14
11
|
# we can also skip validation by setting this flag
|
|
15
12
|
return if record.skip_validation
|
|
16
13
|
|
|
17
|
-
record.form.
|
|
14
|
+
record.form.show_blind = true
|
|
15
|
+
|
|
16
|
+
if record.only_validate_page
|
|
17
|
+
query = record.form.response_fields_for_page(record.only_validate_page)
|
|
18
|
+
else
|
|
19
|
+
query = record.form.filtered_response_fields
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
query = query.reject { |rf| !rf.input_field }
|
|
23
|
+
|
|
24
|
+
query.each do |response_field|
|
|
18
25
|
@response_field = response_field
|
|
19
26
|
@value = @record.response_value(@response_field)
|
|
20
27
|
|
|
@@ -37,7 +44,7 @@ module Formbuilder
|
|
|
37
44
|
private
|
|
38
45
|
def add_error(msg)
|
|
39
46
|
return unless msg.present?
|
|
40
|
-
@record.errors["
|
|
47
|
+
@record.errors["#{@record.responses_column}_#{@response_field.id}"] << msg
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
def run_validation(method_name)
|