dynamic_fieldsets 0.0.3 → 0.0.4
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.
- data/CHANGELOG +7 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +1 -0
- data/README.rdoc +15 -2
- data/Rakefile +24 -4
- data/VERSION +1 -1
- data/app/controllers/dynamic_fieldsets/fields_controller.rb +25 -0
- data/app/controllers/dynamic_fieldsets/fieldset_children_controller.rb +57 -0
- data/app/controllers/dynamic_fieldsets/fieldsets_controller.rb +91 -5
- data/app/helpers/dynamic_fieldsets/fields_helper.rb +1 -15
- data/app/helpers/dynamic_fieldsets/fieldset_children_helper.rb +5 -0
- data/app/helpers/dynamic_fieldsets/nested_model_helper.rb +18 -0
- data/app/helpers/dynamic_fieldsets_helper.rb +70 -44
- data/app/models/dynamic_fieldsets/dependency.rb +76 -0
- data/app/models/dynamic_fieldsets/dependency_clause.rb +32 -0
- data/app/models/dynamic_fieldsets/dependency_group.rb +108 -0
- data/app/models/dynamic_fieldsets/field.rb +17 -12
- data/app/models/dynamic_fieldsets/field_default.rb +27 -1
- data/app/models/dynamic_fieldsets/field_record.rb +19 -4
- data/app/models/dynamic_fieldsets/fieldset.rb +35 -30
- data/app/models/dynamic_fieldsets/fieldset_associator.rb +52 -8
- data/app/models/dynamic_fieldsets/fieldset_child.rb +148 -0
- data/app/views/dynamic_fieldsets/fields/_disable_field_form.html.erb +4 -0
- data/app/views/dynamic_fieldsets/fields/_field_default_fields.html.erb +1 -1
- data/app/views/dynamic_fieldsets/fields/_form.html.erb +9 -27
- data/app/views/dynamic_fieldsets/fields/index.html.erb +8 -5
- data/app/views/dynamic_fieldsets/fields/new.html.erb +5 -1
- data/app/views/dynamic_fieldsets/fields/show.html.erb +1 -13
- data/app/views/dynamic_fieldsets/fieldset_children/_dependency_clause_fields.html.erb +25 -0
- data/app/views/dynamic_fieldsets/fieldset_children/_dependency_fields.html.erb +12 -0
- data/app/views/dynamic_fieldsets/fieldset_children/_dependency_group_fields.html.erb +16 -0
- data/app/views/dynamic_fieldsets/fieldset_children/_form.html.erb +34 -0
- data/app/views/dynamic_fieldsets/fieldset_children/edit.html.erb +6 -0
- data/app/views/dynamic_fieldsets/fieldsets/_associate_child.html.erb +4 -0
- data/app/views/dynamic_fieldsets/fieldsets/_child.html.erb +41 -0
- data/app/views/dynamic_fieldsets/fieldsets/_form.html.erb +2 -8
- data/app/views/dynamic_fieldsets/fieldsets/children.html.erb +47 -39
- data/app/views/dynamic_fieldsets/fieldsets/index.html.erb +4 -4
- data/app/views/dynamic_fieldsets/fieldsets/new.html.erb +5 -1
- data/app/views/dynamic_fieldsets/fieldsets/reorder.html.erb +4 -0
- data/app/views/dynamic_fieldsets/fieldsets/show.html.erb +1 -12
- data/app/views/dynamic_fieldsets/shared/_javascript_watcher.html.erb +255 -0
- data/app/views/dynamic_fieldsets/shared/_nested_model_javascript.html.erb +35 -0
- data/config/.routes.rb.swp +0 -0
- data/config/routes.rb +11 -0
- data/dynamic_fieldsets.gemspec +41 -4
- data/lib/dynamic_fieldsets/dynamic_fieldsets_in_model.rb +141 -14
- data/lib/generators/dynamic_fieldsets/templates/migrations/install_migration.rb +39 -5
- data/spec/dummy/app/controllers/information_forms_controller.rb +2 -1
- data/spec/dummy/app/models/information_form.rb +1 -1
- data/spec/dummy/app/views/information_forms/dynamic_view.html.erb +18 -0
- data/spec/dummy/app/views/information_forms/show.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +9 -1
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/db/migrate/{20110726215814_create_dynamic_fieldsets_tables.rb → 20110809161724_create_dynamic_fieldsets_tables.rb} +39 -5
- data/spec/dummy/db/schema.rb +40 -11
- data/spec/dummy/features/field.feature +17 -2
- data/spec/dummy/features/fieldset.feature +1 -21
- data/spec/dummy/features/fieldset_children.feature +50 -0
- data/spec/dummy/features/javascript_tests.feature +91 -0
- data/spec/dummy/features/step_definitions/field_steps.rb +9 -5
- data/spec/dummy/features/step_definitions/fieldset_associator_steps.rb +3 -1
- data/spec/dummy/features/step_definitions/fieldset_children_steps.rb +65 -0
- data/spec/dummy/features/step_definitions/fieldset_steps.rb +0 -27
- data/spec/dummy/features/step_definitions/javascript_steps.rb +208 -0
- data/spec/dummy/features/step_definitions/web_steps.rb +5 -0
- data/spec/dummy/features/support/paths.rb +10 -1
- data/spec/dummy/features/support/selectors.rb +2 -0
- data/spec/dummy/public/javascripts/jquery-1.6.2.min.js +18 -0
- data/spec/dummy/public/javascripts/jquery-ui-1.8.15.custom.min.js +111 -0
- data/spec/dummy/public/javascripts/jquery-ui-nestedSortable.js +356 -0
- data/spec/dummy/public/stylesheets/scaffold.css +101 -0
- data/spec/dynamic_fieldsets_helper_spec.rb +236 -55
- data/spec/dynamic_fieldsets_in_model_spec.rb +122 -4
- data/spec/models/dependency_clause_spec.rb +55 -0
- data/spec/models/dependency_group_spec.rb +237 -0
- data/spec/models/dependency_spec.rb +173 -0
- data/spec/models/field_default_spec.rb +49 -0
- data/spec/models/field_record_spec.rb +11 -2
- data/spec/models/field_spec.rb +30 -6
- data/spec/models/fieldset_associator_spec.rb +138 -25
- data/spec/models/fieldset_child_spec.rb +122 -0
- data/spec/models/fieldset_spec.rb +78 -80
- data/spec/support/dependency_group_helper.rb +9 -0
- data/spec/support/dependency_helper.rb +13 -0
- data/spec/support/field_helper.rb +0 -2
- data/spec/support/fieldset_child_helper.rb +10 -0
- data/spec/support/fieldset_helper.rb +2 -18
- metadata +51 -5
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
== 0.0.4
|
|
2
|
+
|
|
3
|
+
* A very simple version of the spec completely works
|
|
4
|
+
* The backend is done including a nice system for organizaing and ordering fieldsets
|
|
5
|
+
* The front end is done including dependencies and form and show helpers
|
|
6
|
+
* Additional work is needed for multiple fieldsets on the same page or model, date based dependencies, resuing fieldsets, etc
|
|
7
|
+
|
|
1
8
|
== 0.0.3
|
|
2
9
|
|
|
3
10
|
* Removed ActionView::Helpers from the include. There were errors when it is included twice.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
=
|
|
1
|
+
= dynamic_fieldsets
|
|
2
2
|
|
|
3
3
|
User defined fieldsets for dynamic questions in forms.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
I recommend not using this until a 0.1 release.j
|
|
6
|
+
|
|
7
|
+
= how to use
|
|
8
|
+
|
|
9
|
+
Install the gem, run the install generator
|
|
10
|
+
|
|
11
|
+
Add the mixin to your model. There are some configuration options here.
|
|
12
|
+
|
|
13
|
+
There is a view helper you need to add to your application helper and call from the form view and the show view.
|
|
14
|
+
|
|
15
|
+
The backend is automatically added to your project using the rails engine system. At some point, there will be a controller generator to generate them out so you can add permissions/pagination/whatever else you need on your controllers.
|
|
16
|
+
|
|
17
|
+
== Contributing to dynamic_fieldsets
|
|
6
18
|
|
|
19
|
+
* honestly, hold off for a 0.1 release before even thinking about this
|
|
7
20
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
|
8
21
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
|
9
22
|
* Fork the project
|
data/Rakefile
CHANGED
|
@@ -20,7 +20,7 @@ Jeweler::Tasks.new do |gem|
|
|
|
20
20
|
gem.summary = %Q{Dynamic fieldsets for rails controllers}
|
|
21
21
|
gem.description = %Q{Dynamic fieldsets for rails controllers}
|
|
22
22
|
gem.email = "jeremiah@cloudspace.com"
|
|
23
|
-
gem.authors = ["Jeremiah Hemphill", "Ethan Pemble"]
|
|
23
|
+
gem.authors = ["Jeremiah Hemphill", "Ethan Pemble", "John Carter"]
|
|
24
24
|
# dependencies defined in Gemfile
|
|
25
25
|
end
|
|
26
26
|
Jeweler::RubygemsDotOrgTasks.new
|
|
@@ -62,8 +62,28 @@ namespace :hudson do
|
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
#general cucumber rake
|
|
65
|
+
#general cucumber rake tasks
|
|
66
66
|
require 'cucumber/rake/task'
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
namespace :cucumber do
|
|
68
|
+
Cucumber::Rake::Task.new(:all, 'run features that should pass') do |t|
|
|
69
|
+
t.cucumber_opts = "spec/dummy/features --format progress"
|
|
70
|
+
end
|
|
71
|
+
Cucumber::Rake::Task.new(:no_js, 'run features that should pass') do |t|
|
|
72
|
+
t.cucumber_opts = "spec/dummy/features --format progress --tags ~@javascript"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
task :setup_js_with_vnc4server do
|
|
76
|
+
puts "Cucumber test with vnc4server"
|
|
77
|
+
ENV['DISPLAY'] = ":99"
|
|
78
|
+
%x{vncserver :99 2>/dev/null >/dev/null &}
|
|
79
|
+
%x{DISPLAY=:99 firefox 2>/dev/null >/dev/null &}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
task :kill_js do
|
|
83
|
+
puts "Killing vnc, xvfb, and ff processes"
|
|
84
|
+
%x{killall Xvnc4}
|
|
85
|
+
%x{killall Xvfb}
|
|
86
|
+
%x{killall firefox}
|
|
87
|
+
end
|
|
69
88
|
end
|
|
89
|
+
task :cucumber => ['cucumber:setup_js_with_vnc4server', 'cucumber:all', 'cucumber:kill_js']
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.4
|
|
@@ -35,12 +35,37 @@ module DynamicFieldsets
|
|
|
35
35
|
@field = DynamicFieldsets::Field.find(params[:id])
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# Custom controller action to set the enabled field on the field object
|
|
39
|
+
# Expects a url with an id field and a form with the value [:dynamic_fieldsets_field][:enabled]
|
|
40
|
+
# On success or failure, redirects to the index page with a notice
|
|
41
|
+
#
|
|
42
|
+
# This should never fail the save unless the field was initially saved without validations
|
|
43
|
+
def enable
|
|
44
|
+
@field = DynamicFieldsets::Field.find(params[:id])
|
|
45
|
+
@field.enabled = params[:dynamic_fieldsets_field][:enabled]
|
|
46
|
+
respond_to do |format|
|
|
47
|
+
if @field.save
|
|
48
|
+
format.html { redirect_to(dynamic_fieldsets_fields_path, :notice => 'Successfully updated a new field.') }
|
|
49
|
+
else
|
|
50
|
+
format.html { redirect_to(dynamic_fieldsets_fields_path, :notice => 'Did not update the field successfully.') }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
38
55
|
# POST /dynamic_fieldsets/fields
|
|
39
56
|
def create
|
|
57
|
+
parent_id = params[:parent]
|
|
40
58
|
@field = DynamicFieldsets::Field.new(params[:dynamic_fieldsets_field])
|
|
41
59
|
|
|
42
60
|
respond_to do |format|
|
|
43
61
|
if @field.save
|
|
62
|
+
if !parent_id.empty?
|
|
63
|
+
parent = DynamicFieldsets::Fieldset.find_by_id(parent_id)
|
|
64
|
+
DynamicFieldsets::FieldsetChild.create( :fieldset => parent, :child => @field )
|
|
65
|
+
#relation = @fieldset.fieldset_children.build( :fieldset => parent )
|
|
66
|
+
#relation.child = @field
|
|
67
|
+
#relation.save
|
|
68
|
+
end
|
|
44
69
|
format.html { redirect_to(@field, :notice => 'Successfully created a new field.') }
|
|
45
70
|
else
|
|
46
71
|
format.html { render :action => "new" }
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module DynamicFieldsets
|
|
2
|
+
# Controller for handling editing of fieldset children
|
|
3
|
+
# Most of this is done through the fieldsets#children action
|
|
4
|
+
# Dependencies are done here
|
|
5
|
+
class FieldsetChildrenController < ApplicationController
|
|
6
|
+
unloadable
|
|
7
|
+
|
|
8
|
+
# this view doesn't exist
|
|
9
|
+
def index
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Show a record and all children
|
|
13
|
+
def show
|
|
14
|
+
@fieldset_child = DynamicFieldsets::FieldsetChild.find_by_id params[:id]
|
|
15
|
+
@fieldset = DynamicFieldsets::Fieldset.find_by_id @fieldset_child.fieldset_id
|
|
16
|
+
|
|
17
|
+
respond_to do |format|
|
|
18
|
+
format.html
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def edit
|
|
23
|
+
@fieldset_child = DynamicFieldsets::FieldsetChild.find(params[:id])
|
|
24
|
+
respond_to do |format|
|
|
25
|
+
format.html
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# updates the fieldset_child and uses accepts_nested_attributes_for to setup a dependency system
|
|
30
|
+
def update
|
|
31
|
+
@fieldset_child = DynamicFieldsets::FieldsetChild.find(params[:id])
|
|
32
|
+
|
|
33
|
+
respond_to do |format|
|
|
34
|
+
if @fieldset_child.update_attributes(params[:dynamic_fieldsets_fieldset_child])
|
|
35
|
+
format.html { redirect_to(dynamic_fieldsets_children_dynamic_fieldsets_fieldset_path(@fieldset_child.root_fieldset), :notice => "Successfully updated a child")}
|
|
36
|
+
else
|
|
37
|
+
format.html { render :action => "edit" }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# deletes the fieldset child and redirects to its root fieldset page
|
|
43
|
+
def remove
|
|
44
|
+
@fieldset_child = DynamicFieldsets::FieldsetChild.find(params[:id])
|
|
45
|
+
root = @fieldset_child.root_fieldset
|
|
46
|
+
|
|
47
|
+
respond_to do |format|
|
|
48
|
+
if @fieldset_child.destroy
|
|
49
|
+
notice_text = "Successfully removed the child"
|
|
50
|
+
else
|
|
51
|
+
notice_text = "Child was not able to be removed"
|
|
52
|
+
end
|
|
53
|
+
format.html { redirect_to(dynamic_fieldsets_children_dynamic_fieldsets_fieldset_path(root), :notice => notice_text)}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -3,7 +3,7 @@ module DynamicFieldsets
|
|
|
3
3
|
class FieldsetsController < ApplicationController
|
|
4
4
|
unloadable
|
|
5
5
|
|
|
6
|
-
# Show all
|
|
6
|
+
# Show all fieldsets
|
|
7
7
|
def index
|
|
8
8
|
@fieldsets = DynamicFieldsets::Fieldset.all
|
|
9
9
|
|
|
@@ -12,7 +12,16 @@ module DynamicFieldsets
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# Show
|
|
15
|
+
# Show all root fieldsets
|
|
16
|
+
def roots
|
|
17
|
+
@fieldsets = DynamicFieldsets::Fieldset.roots
|
|
18
|
+
|
|
19
|
+
respond_to do |format|
|
|
20
|
+
format.html { render action: 'index' }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Show single fieldset
|
|
16
25
|
def show
|
|
17
26
|
@fieldset = DynamicFieldsets::Fieldset.find_by_id(params[:id])
|
|
18
27
|
|
|
@@ -21,7 +30,7 @@ module DynamicFieldsets
|
|
|
21
30
|
end
|
|
22
31
|
end
|
|
23
32
|
|
|
24
|
-
# Create new
|
|
33
|
+
# Create new fieldset
|
|
25
34
|
def new
|
|
26
35
|
@fieldset = DynamicFieldsets::Fieldset.new()
|
|
27
36
|
|
|
@@ -41,20 +50,97 @@ module DynamicFieldsets
|
|
|
41
50
|
|
|
42
51
|
# Show a record and all children
|
|
43
52
|
def children
|
|
44
|
-
@
|
|
45
|
-
@parent_fieldset = DynamicFieldsets::Fieldset.find_by_id(params[:id])
|
|
53
|
+
@fieldset = DynamicFieldsets::Fieldset.find_by_id params[:id]
|
|
46
54
|
|
|
47
55
|
respond_to do |format|
|
|
48
56
|
format.html
|
|
49
57
|
end
|
|
50
58
|
end
|
|
59
|
+
|
|
60
|
+
# associates a field or fieldset with the given fieldset by creating a fieldset child
|
|
61
|
+
def associate_child
|
|
62
|
+
@fieldset = DynamicFieldsets::Fieldset.find_by_id(params[:id])
|
|
63
|
+
@field = DynamicFieldsets::Field.find_by_id(params[:field])
|
|
64
|
+
|
|
65
|
+
@fieldset_child = DynamicFieldsets::FieldsetChild.where(:child_id => @field.id, :child_type => @field.class.name, :fieldset_id => @fieldset.id).first
|
|
66
|
+
if(@fieldset_child.nil?)
|
|
67
|
+
@fieldset_child = DynamicFieldsets::FieldsetChild.new(
|
|
68
|
+
:child_id => @field.id,
|
|
69
|
+
:child_type => @field.class.name,
|
|
70
|
+
:fieldset_id => @fieldset.id,
|
|
71
|
+
:order_num => DynamicFieldsets::FieldsetChild.where(:fieldset_id => @fieldset.id).count + 1)
|
|
72
|
+
else
|
|
73
|
+
child_already_exists = true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
respond_to do |format|
|
|
77
|
+
if @fieldset_child.save
|
|
78
|
+
if child_already_exists
|
|
79
|
+
notice_text = "Field was already associated with the fieldset"
|
|
80
|
+
else
|
|
81
|
+
notice_text = "Successfully associated a field"
|
|
82
|
+
end
|
|
83
|
+
format.html { redirect_to(dynamic_fieldsets_children_dynamic_fieldsets_fieldset_path(@fieldset), :notice => notice_text )}
|
|
84
|
+
else
|
|
85
|
+
format.html { redirect_to(dynamic_fieldsets_children_dynamic_fieldsets_fieldset_path(@fieldset), :notice => "Field was not successsfully associated." )}
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# ...
|
|
91
|
+
def reorder
|
|
92
|
+
root = params[:id]
|
|
93
|
+
parent_child_pairs = params[:child].inject({}) do |hash,(key,val)|
|
|
94
|
+
if val.eql? 'root' then hash[key.to_i] = root.to_i
|
|
95
|
+
else hash[key.to_i] = val.to_i
|
|
96
|
+
end
|
|
97
|
+
hash
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
@order = {}
|
|
101
|
+
parent_child_pairs.each do |key,val|
|
|
102
|
+
if @order.keys.include? val
|
|
103
|
+
then @order[val].push key
|
|
104
|
+
else @order.merge! val=>[key]
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# e.g. { 1 => [6], 6 => [7,8] }
|
|
109
|
+
# First number is always the root Fieldset id.
|
|
110
|
+
# The rest are FieldsetChild ids.
|
|
111
|
+
@order.each do |parent_identifier,children|
|
|
112
|
+
if parent_identifier.eql? @order.first[0] # This is the first number:
|
|
113
|
+
then parent_id = parent_identifier # the root fieldset id.
|
|
114
|
+
# Otherwise, we need to retrieve the parent fieldset_id from the FieldsetChild's child_id.
|
|
115
|
+
else parent_id = DynamicFieldsets::FieldsetChild.find_by_id(parent_identifier).child_id
|
|
116
|
+
end
|
|
117
|
+
children.each_with_index do |fieldset_child_id,index|
|
|
118
|
+
fieldset_child = DynamicFieldsets::FieldsetChild.find_by_id fieldset_child_id
|
|
119
|
+
fieldset_child.fieldset_id = parent_id
|
|
120
|
+
fieldset_child.order_num = index+1
|
|
121
|
+
fieldset_child.save
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
respond_to do |format|
|
|
126
|
+
format.json { render :json => @order }
|
|
127
|
+
end
|
|
128
|
+
end
|
|
51
129
|
|
|
52
130
|
# Save new record
|
|
53
131
|
def create
|
|
132
|
+
parent_id = params[:parent]
|
|
54
133
|
@fieldset = DynamicFieldsets::Fieldset.new(params[:dynamic_fieldsets_fieldset])
|
|
55
134
|
|
|
56
135
|
respond_to do |format|
|
|
57
136
|
if @fieldset.save
|
|
137
|
+
if !parent_id.empty?
|
|
138
|
+
parent = DynamicFieldsets::Fieldset.find_by_id(parent_id)
|
|
139
|
+
DynamicFieldsets::FieldsetChild.create( :fieldset => parent, :child => @fieldset )
|
|
140
|
+
#relation = @fieldset.fieldset_children.build( :fieldset => parent )
|
|
141
|
+
#relation.child = @fieldset
|
|
142
|
+
#relation.save
|
|
143
|
+
end
|
|
58
144
|
format.html { redirect_to( dynamic_fieldsets_fieldset_path(@fieldset), :notice => "Successfully created a new fieldset" )}
|
|
59
145
|
else
|
|
60
146
|
format.html { render :action => "new" }
|
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
module DynamicFieldsets
|
|
2
2
|
module FieldsHelper
|
|
3
|
-
|
|
4
|
-
# returns a link with an onclick call to remove_fields using link_to_function
|
|
5
|
-
def link_to_remove_fields(name, f)
|
|
6
|
-
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
# returns a link with an onclick call to add_fields
|
|
10
|
-
# the field information is rendered from a partial and stored as a string until it is needed
|
|
11
|
-
def link_to_add_fields(name, f, association)
|
|
12
|
-
new_object = f.object.class.reflect_on_association(association).klass.new
|
|
13
|
-
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
|
|
14
|
-
render(association.to_s.singularize + "_fields", :f => builder)
|
|
15
|
-
end
|
|
16
|
-
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
|
|
17
|
-
end
|
|
3
|
+
include NestedModelHelper
|
|
18
4
|
end
|
|
19
5
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module DynamicFieldsets
|
|
2
|
+
module NestedModelHelper
|
|
3
|
+
# returns a link with an onclick call to remove_fields using link_to_function
|
|
4
|
+
def link_to_remove_fields(name, f)
|
|
5
|
+
f.hidden_field(:_destroy) + link_to_function(name, {:onclick => "remove_fields(this)"})
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# returns a link with an onclick call to add_fields
|
|
9
|
+
# the field information is rendered from a partial and stored as a string until it is needed
|
|
10
|
+
def link_to_add_fields(name, f, association, method = "add_fields")
|
|
11
|
+
new_object = f.object.class.reflect_on_association(association).klass.new
|
|
12
|
+
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
|
|
13
|
+
render(association.to_s.singularize + "_fields", {:f => builder, :obj => new_object})
|
|
14
|
+
end
|
|
15
|
+
link_to_function(name, {:class => name.underscore.gsub(' ', '_'), :onclick => "#{method}(this, '#{association}', '#{escape_javascript(fields)}')"})
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
module DynamicFieldsetsHelper
|
|
2
2
|
#include ActionView::Helpers
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
# Builds HTML for the provided field.
|
|
5
5
|
# @param [FieldsetAssociator] fsa parent FieldsetAssociator
|
|
6
|
-
# @param [
|
|
6
|
+
# @param [FieldsetChild] fieldset_child The FieldsetChild to render
|
|
7
7
|
# @param [Array] values Saved values for the field
|
|
8
8
|
# @return [Array] The HTML elements for the field
|
|
9
|
-
def field_renderer(fsa,
|
|
9
|
+
def field_renderer(fsa, fieldset_child, values = [], form_type)
|
|
10
10
|
if form_type == "form"
|
|
11
|
-
return field_form_renderer(fsa,
|
|
11
|
+
return field_form_renderer(fsa, fieldset_child, values)
|
|
12
12
|
else
|
|
13
|
-
return field_show_renderer(fsa,
|
|
13
|
+
return field_show_renderer(fsa, fieldset_child, values)
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
# Builds HTML for the provided field for a show page.
|
|
19
19
|
# @param [FieldsetAssociator] fsa parent FieldsetAssociator
|
|
20
|
-
# @param [
|
|
20
|
+
# @param [FieldsetChild] fieldset_child The FieldsetChild to render
|
|
21
21
|
# @param [Array] values Saved values for the field
|
|
22
22
|
# @return [Array] The HTML elements for the field
|
|
23
|
-
def field_show_renderer(fsa,
|
|
23
|
+
def field_show_renderer(fsa, fieldset_child, values = [])
|
|
24
|
+
field = fieldset_child.child
|
|
24
25
|
lines = []
|
|
25
26
|
lines.push "<div class='dynamic_fieldsets_field'>"
|
|
26
27
|
lines.push "<div class='dynamic_fieldsets_field_label'>#{field.label}</div>"
|
|
27
28
|
lines.push "<div class='dynamic_fieldsets_field_value'>"
|
|
28
29
|
if values
|
|
29
|
-
if field.field_type == "multiple_select" || field.field_type == "
|
|
30
|
+
if field.field_type == "multiple_select" || field.field_type == "checkbox"
|
|
30
31
|
values.each do |value|
|
|
31
32
|
lines.push value.to_s + "<br />"
|
|
32
33
|
end
|
|
@@ -45,57 +46,61 @@ module DynamicFieldsetsHelper
|
|
|
45
46
|
|
|
46
47
|
# Builds HTML for the provided field for a form.
|
|
47
48
|
# @param [FieldsetAssociator] fsa parent FieldsetAssociator
|
|
48
|
-
# @param [
|
|
49
|
+
# @param [FieldsetChild] fieldset_child The FieldsetChild to render
|
|
49
50
|
# @param [Array] values Saved values for the field
|
|
50
51
|
# @return [Array] The HTML elements for the field
|
|
51
|
-
def field_form_renderer(fsa,
|
|
52
|
+
def field_form_renderer(fsa, fieldset_child, values = [])
|
|
53
|
+
field = fieldset_child.child
|
|
52
54
|
classes = "#{field.field_type} "
|
|
53
55
|
classes += ( field.required ? 'required' : 'optional' )
|
|
54
56
|
|
|
55
|
-
field_markup = ["<li class='#{classes}' id='field
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
field_markup = ["<li class='#{classes}' id='input-field-#{field.id}-child-#{fieldset_child.id}'>"]
|
|
58
|
+
|
|
59
|
+
if !field.field_type.eql?('instruction')
|
|
60
|
+
field_markup.push "<label for='field-#{field.id}'>"
|
|
61
|
+
field_markup.push "#{field.label}: "
|
|
62
|
+
field_markup.push "<abbr title='required'>*</abbr>" if field.required?
|
|
63
|
+
field_markup.push "</label>"
|
|
64
|
+
end
|
|
60
65
|
|
|
61
|
-
attrs = { :id => "field-#{field.id}" }
|
|
62
|
-
field.field_html_attributes.each{ |a| attrs.merge
|
|
66
|
+
attrs = { :id => "field-#{field.id}-child-#{fieldset_child.id}" }
|
|
67
|
+
field.field_html_attributes.each{ |a| attrs.merge! a.attribute_name.to_sym => a.value } if !field.field_html_attributes.empty?
|
|
63
68
|
|
|
64
69
|
case field.field_type.to_sym
|
|
65
70
|
when :select
|
|
66
71
|
selected = populate(field,values).to_i # should return the ID of the saved or default option
|
|
67
|
-
field_markup.push select_tag "fsa-#{fsa.id}[field-#{
|
|
72
|
+
field_markup.push select_tag "fsa-#{fsa.id}[field-#{fieldset_child.id}]", options_from_collection_for_select( field.options, :id, :name, selected ), attrs
|
|
68
73
|
|
|
69
74
|
when :multiple_select
|
|
70
|
-
attrs.merge! multiple:
|
|
75
|
+
attrs.merge! multiple: true
|
|
71
76
|
opts = populate( field, values )
|
|
72
77
|
opts = [opts] if !opts.is_a? Array
|
|
73
78
|
selected = opts.map( &:to_i ) if !opts.empty? # array of option IDs, saved > default
|
|
74
|
-
field_markup.push select_tag "fsa-#{fsa.id}[field-#{
|
|
79
|
+
field_markup.push select_tag "fsa-#{fsa.id}[field-#{fieldset_child.id}]", options_from_collection_for_select( field.options, :id, :name, selected ), attrs
|
|
75
80
|
|
|
76
81
|
when :radio
|
|
77
|
-
field_markup.push "<div id='field-#{field.id}'>"
|
|
82
|
+
field_markup.push "<div id='field-#{field.id}-child-#{fieldset_child.id}'>"
|
|
78
83
|
field.options.each do |option|
|
|
79
84
|
attrs[:id] = "field-#{field.id}-#{option.name.parameterize}"
|
|
80
85
|
these_attrs = attrs
|
|
81
86
|
these_attrs = attrs.merge checked: true if populate(field,values).to_i.eql? option.id
|
|
82
|
-
field_markup.push "<label for='#{
|
|
83
|
-
field_markup.push radio_button "fsa-#{fsa.id}", "field-#{
|
|
87
|
+
field_markup.push "<label for='#{these_attrs[:id]}'>"
|
|
88
|
+
field_markup.push radio_button "fsa-#{fsa.id}", "field-#{fieldset_child.id}", option.id, these_attrs
|
|
84
89
|
field_markup.push "#{option.name}"
|
|
85
90
|
field_markup.push "</label>"
|
|
86
91
|
end
|
|
87
92
|
field_markup.push "</div>"
|
|
88
93
|
|
|
89
94
|
when :checkbox
|
|
90
|
-
field_markup.push "<div id='field-#{field.id}'>"
|
|
95
|
+
field_markup.push "<div id='field-#{field.id}-child-#{fieldset_child.id}'>"
|
|
96
|
+
attrs[:name] = "fsa-#{fsa.id}[field-#{fieldset_child.id}][]"
|
|
91
97
|
opts = populate( field, values )
|
|
92
98
|
checked = []
|
|
93
99
|
checked = opts.map( &:to_i ) if !opts.empty? # array of option IDs, saved > default
|
|
94
100
|
field.options.each do |option|
|
|
95
101
|
attrs[:id] = "field-#{field.id}-#{option.name.underscore}"
|
|
96
|
-
attrs.merge! checked: true if checked.include? option.id
|
|
97
102
|
field_markup.push "<label for='#{attrs[:id]}'>"
|
|
98
|
-
field_markup.push
|
|
103
|
+
field_markup.push check_box_tag "#{attrs[:name]}", "#{option.id}", checked.include?(option.id), attrs
|
|
99
104
|
field_markup.push "#{option.name}"
|
|
100
105
|
field_markup.push "</label>"
|
|
101
106
|
end
|
|
@@ -103,33 +108,32 @@ module DynamicFieldsetsHelper
|
|
|
103
108
|
|
|
104
109
|
when :textfield
|
|
105
110
|
attrs.merge!( {:value => populate( field, values )} )
|
|
106
|
-
field_markup.push text_field "fsa-#{fsa.id}", "field-#{
|
|
111
|
+
field_markup.push text_field "fsa-#{fsa.id}", "field-#{fieldset_child.id}", attrs
|
|
107
112
|
|
|
108
113
|
when :textarea
|
|
109
114
|
attrs.merge! cols: '40' if !attrs.include? :cols
|
|
110
|
-
attrs.merge! rows: '
|
|
111
|
-
attrs.merge! name: "fsa-#{fsa.id}[field-#{
|
|
112
|
-
|
|
113
|
-
#
|
|
115
|
+
attrs.merge! rows: '6' if !attrs.include? :rows
|
|
116
|
+
attrs.merge! name: "fsa-#{fsa.id}[field-#{fieldset_child.id}]"
|
|
117
|
+
tag = "<textarea"
|
|
118
|
+
attrs.each{ |att,val| tag += " #{att}=\"#{val}\"" }
|
|
119
|
+
tag += ">"
|
|
120
|
+
field_markup.push tag
|
|
114
121
|
field_markup.push populate( field, values )
|
|
115
122
|
field_markup.push "</textarea>"
|
|
116
123
|
|
|
117
124
|
when :date
|
|
118
|
-
date_options = {
|
|
119
|
-
add_month_numbers: true,
|
|
120
|
-
start_year: Time.now.year - 70 }
|
|
125
|
+
date_options = { start_year: Time.now.year - 70 }
|
|
121
126
|
setdate = populate( field, values ) # date string if saved or default
|
|
122
127
|
date_options.merge! default: Time.parse( setdate ) if !setdate.empty?
|
|
123
128
|
# attrs.reject!{ |k| k.eql? :id }
|
|
124
|
-
field_markup.push date_select "fsa-#{fsa.id}", "field-#{
|
|
129
|
+
field_markup.push date_select "fsa-#{fsa.id}", "field-#{fieldset_child.id}", date_options, attrs
|
|
125
130
|
|
|
126
131
|
when :datetime
|
|
127
|
-
date_options = {
|
|
128
|
-
start_year: Time.now.year - 70 }
|
|
132
|
+
date_options = { start_year: Time.now.year - 70 }
|
|
129
133
|
setdate = populate( field, values ) # datetime string if saved or default
|
|
130
134
|
date_options.merge! default: Time.parse( setdate ) if !setdate.empty?
|
|
131
135
|
# attrs.reject!{ |k| k.eql? :id }
|
|
132
|
-
field_markup.push datetime_select "fsa-#{fsa.id}", "field-#{
|
|
136
|
+
field_markup.push datetime_select "fsa-#{fsa.id}", "field-#{fieldset_child.id}", date_options, attrs
|
|
133
137
|
|
|
134
138
|
when :instruction
|
|
135
139
|
field_markup.push "<p>#{field.label}</p>"
|
|
@@ -142,21 +146,24 @@ module DynamicFieldsetsHelper
|
|
|
142
146
|
|
|
143
147
|
# Builds HTML for the provided fieldset and its children.
|
|
144
148
|
# @param [FieldsetAssociator] fsa parent FieldsetAssociator
|
|
145
|
-
# @param [
|
|
149
|
+
# @param [Fieldset] fieldset The Fieldset to render
|
|
146
150
|
# @param [Hash] values Stored values for the fieldset
|
|
147
151
|
# @return [Array] The HTML elements for the fieldset
|
|
148
152
|
def fieldset_renderer(fsa, fieldset, values, form_type)
|
|
149
153
|
lines = ["<div id='fieldset-#{fieldset.id}' class='inputs'>"]
|
|
154
|
+
lines.push "<h3 class='name'>#{fieldset.name}</h3>"
|
|
150
155
|
lines.push "<ol>"
|
|
151
156
|
fieldset.children.each do |child|
|
|
152
157
|
if child.is_a? DynamicFieldsets::Field then
|
|
153
|
-
|
|
158
|
+
fieldset_child = DynamicFieldsets::FieldsetChild.where( :child_id => child.id, :fieldset_id => fieldset.id, :child_type => child.class.name ).first
|
|
159
|
+
lines += field_renderer( fsa, fieldset_child, values[fieldset_child.id], form_type )
|
|
154
160
|
else # child.is_a? Fieldset
|
|
155
161
|
lines += fieldset_renderer( fsa, child, values, form_type )
|
|
156
162
|
end
|
|
157
163
|
end
|
|
158
164
|
lines.push "</ol>"
|
|
159
165
|
lines.push "</div>"
|
|
166
|
+
|
|
160
167
|
return lines
|
|
161
168
|
end
|
|
162
169
|
|
|
@@ -171,17 +178,21 @@ module DynamicFieldsetsHelper
|
|
|
171
178
|
# @param [FieldsetAssociator] The fieldset associator for the dynamic fieldset to render
|
|
172
179
|
# @return [String] The HTML for the entire dynamic fieldset
|
|
173
180
|
def dynamic_fieldset_form_renderer(fsa)
|
|
174
|
-
return dynamic_fieldset_renderer(fsa, "form")
|
|
181
|
+
return dynamic_fieldset_renderer(fsa, "form") << javascript_renderer(fsa)
|
|
175
182
|
end
|
|
176
183
|
|
|
177
184
|
# Builds HTML for a specific dynamic fieldset in a form.
|
|
178
185
|
# @param [FieldsetAssociator] The fieldset associator for the dynamic fieldset to render
|
|
179
186
|
# @return [String] The HTML for the entire dynamic fieldset
|
|
180
187
|
def dynamic_fieldset_renderer(fsa, form_type)
|
|
181
|
-
rendered_dynamic_fieldset = ""
|
|
188
|
+
rendered_dynamic_fieldset = "<div id='fsa-#{fsa.id}'>\n"
|
|
189
|
+
rendered_dynamic_fieldset += "<input type='hidden' name='fsa-#{fsa.id}[fieldset_id]' value='#{fsa.fieldset_id}' />\n"
|
|
190
|
+
rendered_dynamic_fieldset += "<input type='hidden' name='fsa-#{fsa.id}[fieldset_model_name]' value='#{fsa.fieldset_model_name}' />\n"
|
|
182
191
|
fieldset_renderer( fsa, fsa.fieldset, fsa.field_values, form_type ).each do |line|
|
|
183
192
|
rendered_dynamic_fieldset += line + "\n"
|
|
184
193
|
end
|
|
194
|
+
rendered_dynamic_fieldset += "</div>"
|
|
195
|
+
|
|
185
196
|
return rendered_dynamic_fieldset.html_safe
|
|
186
197
|
end
|
|
187
198
|
|
|
@@ -196,12 +207,27 @@ module DynamicFieldsetsHelper
|
|
|
196
207
|
return ""
|
|
197
208
|
elsif field.field_defaults.length > 1
|
|
198
209
|
return field.field_defaults.collect{ |d| d[:value] }
|
|
199
|
-
else
|
|
210
|
+
else
|
|
200
211
|
return field.field_defaults.first.value
|
|
201
212
|
end
|
|
202
213
|
else
|
|
203
214
|
return value
|
|
204
215
|
end
|
|
205
216
|
end
|
|
206
|
-
|
|
217
|
+
|
|
218
|
+
# Method that returns the javascript in string format to be pushed on with the rest of the
|
|
219
|
+
# generated form
|
|
220
|
+
#
|
|
221
|
+
# @params [FieldsetAssociator] The fieldset associator for the dynamic fieldset to render
|
|
222
|
+
# @return [String] The javascript variable that shows what fields have dependencies
|
|
223
|
+
def javascript_renderer(fsa)
|
|
224
|
+
unless fsa.id == nil
|
|
225
|
+
rendered_javascript = "<script type='text/javascript'> var json_holder = #{fsa.dependency_child_hash.to_json}; </script>"
|
|
226
|
+
rendered_javascript += render "dynamic_fieldsets/shared/javascript_watcher"
|
|
227
|
+
return rendered_javascript.html_safe
|
|
228
|
+
else
|
|
229
|
+
return ""
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
207
233
|
end
|