dynamic_fieldsets 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|