formize 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/{LICENSE.txt → MIT-LICENSE} +0 -0
- data/README.rdoc +19 -3
- data/VERSION +1 -1
- data/lib/assets/javascripts/formize.js +23 -5
- data/lib/formize.rb +14 -10
- data/lib/formize/{action_pack.rb → action_controller.rb} +6 -5
- data/lib/formize/definition.rb +9 -5
- data/lib/formize/definition/field.rb +55 -53
- data/lib/formize/definition/field_set.rb +52 -27
- data/lib/formize/definition/form.rb +97 -83
- data/lib/formize/definition/form_element.rb +98 -114
- data/lib/formize/engine.rb +5 -0
- data/lib/formize/generator.rb +520 -484
- data/lib/formize/helpers.rb +8 -0
- data/lib/formize/helpers/asset_tag_helper.rb +33 -0
- data/lib/formize/helpers/form_helper.rb +131 -0
- data/lib/formize/helpers/tag_helper.rb +14 -0
- data/lib/formize/railtie.rb +17 -0
- metadata +22 -27
- data/.document +0 -5
- data/.travis.yml +0 -8
- data/Rakefile +0 -54
- data/ci/Gemfile.rails-3.0.x +0 -11
- data/ci/Gemfile.rails-3.1.x +0 -11
- data/formize.gemspec +0 -150
- data/lib/formize/definition/element.rb +0 -56
- data/lib/formize/form_helper.rb +0 -150
- data/test/helper.rb +0 -9
- data/test/test_formize.rb +0 -9
data/{LICENSE.txt → MIT-LICENSE}
RENAMED
File without changes
|
data/README.rdoc
CHANGED
@@ -4,21 +4,37 @@ Simple form DSL with dynamic interactions for Rails.
|
|
4
4
|
|
5
5
|
== Installation
|
6
6
|
|
7
|
-
Add
|
7
|
+
Add to your Gemfile these fllowing lines:
|
8
8
|
gem "jquery-rails" # Need to be explicitly specified
|
9
9
|
gem "formize"
|
10
10
|
|
11
|
+
== Assets incorporation (JavaScripts and Stylesheets)
|
12
|
+
Formize comes with basic scripts and stylesheets which must be included in the layout (at least at the start).
|
13
|
+
|
14
|
+
=== In Rails 3.0.x
|
11
15
|
Formize requires the gem +jquery-rails+, so if you don't already use it:
|
12
16
|
rails generate jquery:install
|
13
17
|
|
14
18
|
Then install +formize+ in your app like +jquery-rails+:
|
15
19
|
rails generate formize:install
|
16
20
|
|
17
|
-
|
18
|
-
|
21
|
+
These previous commands install all the needed files in your +public/+ directory.
|
22
|
+
Then the files can be included with an helper:
|
23
|
+
# app/views/layouts/application.html.erb
|
24
|
+
<%= formize_include_tag -%>
|
25
|
+
|
26
|
+
=== In Rails ≥ 3.1
|
27
|
+
With the asset pipeline, there is no need to run generators or copy files. So for stylesheets:
|
28
|
+
# app/assets/stylesheets/application.css
|
29
|
+
*= require formize
|
30
|
+
|
31
|
+
And for javascripts:
|
32
|
+
# app/assets/javascripts/application.js
|
33
|
+
*= require formize
|
19
34
|
|
20
35
|
== Usage
|
21
36
|
|
37
|
+
|
22
38
|
In controller:
|
23
39
|
|
24
40
|
class OrdersController < ApplicationController
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.11
|
@@ -103,6 +103,7 @@ Formize.Dialog = {
|
|
103
103
|
},
|
104
104
|
|
105
105
|
submitForm: function(form) {
|
106
|
+
var form = $(this);
|
106
107
|
var dialog_id = form.attr('data-dialog');
|
107
108
|
var dialog = $('#'+dialog_id);
|
108
109
|
|
@@ -121,7 +122,7 @@ Formize.Dialog = {
|
|
121
122
|
$(document).trigger("dom:update", dialog.attr('id'));
|
122
123
|
} else {
|
123
124
|
// Refresh element with its refresh URL
|
124
|
-
|
125
|
+
var updated_id = '#'+dialog.attr('data-dialog-update'), updated = $(updated_id);
|
125
126
|
if (updated[0] !== undefined) {
|
126
127
|
var url = updated.attr('data-refresh');
|
127
128
|
$.ajax(url, {
|
@@ -129,6 +130,7 @@ Formize.Dialog = {
|
|
129
130
|
success: function(data2, textStatus2, request2) {
|
130
131
|
updated.replaceWith(request2.responseText);
|
131
132
|
$(document).trigger("dom:update");
|
133
|
+
$(updated_id+' input').trigger("emulated:change");
|
132
134
|
}
|
133
135
|
});
|
134
136
|
}
|
@@ -171,6 +173,20 @@ Formize.refreshDependents = function (event) {
|
|
171
173
|
return false;
|
172
174
|
}
|
173
175
|
|
176
|
+
Formize.Toggles = {
|
177
|
+
|
178
|
+
ifChecked: function () {
|
179
|
+
if (this.checked) {
|
180
|
+
$($(this).attr('data-show')).slideDown();
|
181
|
+
$($(this).attr('data-hide')).slideUp();
|
182
|
+
} else {
|
183
|
+
$($(this).attr('data-show')).slideUp();
|
184
|
+
$($(this).attr('data-hide')).slideDown();
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
}
|
189
|
+
|
174
190
|
|
175
191
|
/**
|
176
192
|
* Special method which is a sharthand to bind every element
|
@@ -279,14 +295,16 @@ behave("a[data-close-dialog]", "click", function() {
|
|
279
295
|
});
|
280
296
|
|
281
297
|
// Submits dialog forms
|
282
|
-
behave("form[data-dialog]", "submit",
|
283
|
-
return Formize.Dialog.submitForm($(this));
|
284
|
-
});
|
298
|
+
behave("form[data-dialog]", "submit", Formize.Dialog.submitForm);
|
285
299
|
|
300
|
+
// Refresh dependents on changes
|
286
301
|
behave("*[data-dependents]", "change", Formize.refreshDependents);
|
302
|
+
behave("*[data-dependents]", "emulated:change", Formize.refreshDependents);
|
287
303
|
// Compensate for changes made with keyboard
|
288
304
|
behave("select[data-dependents]", "keypress", Formize.refreshDependents);
|
289
|
-
|
305
|
+
|
306
|
+
behave("input[data-show], input[data-hide]", "load", Formize.Toggles.ifChecked);
|
307
|
+
behave("input[data-show], input[data-hide]", "change", Formize.Toggles.ifChecked);
|
290
308
|
|
291
309
|
// Resizes the overlay automatically
|
292
310
|
$(window).resize(function() {
|
data/lib/formize.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require
|
3
|
-
require 'active_support'
|
4
|
-
|
1
|
+
# require 'rubygems'
|
2
|
+
# require 'bundler/setup'
|
3
|
+
# require 'active_support'
|
4
|
+
require 'formize/railtie' if defined?(::Rails)
|
5
|
+
require 'formize/engine' if defined?(::Rails)
|
6
|
+
|
7
|
+
# :include: ../README.rdoc
|
5
8
|
module Formize
|
9
|
+
extend ActiveSupport::Autoload
|
6
10
|
|
7
|
-
def self.configure(name, value = nil)
|
11
|
+
def self.configure(name, value = nil) # :nodoc:
|
8
12
|
unless self.respond_to?("#{name}=")
|
9
13
|
# mattr_accessor(name)
|
10
14
|
code = "unless defined?(@@#{name})\n"
|
@@ -37,11 +41,11 @@ module Formize
|
|
37
41
|
# How many select options can be displayed before to become a +unroll+
|
38
42
|
configure :select_count_max, 7
|
39
43
|
|
44
|
+
autoload :Definition
|
45
|
+
autoload :Helpers
|
46
|
+
autoload :ActionController
|
47
|
+
autoload :Generator
|
40
48
|
end
|
41
49
|
|
42
|
-
require 'action_view'
|
43
|
-
require 'formize/definition'
|
44
|
-
require 'formize/generator'
|
45
|
-
require 'formize/form_helper'
|
46
|
-
require 'formize/action_pack'
|
50
|
+
# require 'action_view'
|
47
51
|
|
@@ -21,13 +21,14 @@ module Formize
|
|
21
21
|
options[:view_form_method_name] = "_#{self.controller_name}_formize_form_#{name}_tag"
|
22
22
|
options[:view_fields_method_name] = "_#{self.controller_name}_formize_fields_#{name}_tag"
|
23
23
|
options[:method_name] = options[:view_fields_method_name]
|
24
|
-
|
24
|
+
options[:best_name] = "#{self.controller_name}#{'_'+name.to_s if name != self.controller_name.to_sym}"
|
25
|
+
form = Formize::Definition::Form.new(name, model, options)
|
25
26
|
if block_given?
|
26
27
|
yield form
|
27
28
|
else
|
28
29
|
formize_by_default(form)
|
29
30
|
end
|
30
|
-
generator = Formize::Generator.new(form, self)
|
31
|
+
generator = Formize::Generator::Base.new(form, self)
|
31
32
|
class_eval(generator.controller_code, "#{__FILE__}:#{__LINE__}")
|
32
33
|
ActionView::Base.send(:class_eval, generator.view_code, "#{__FILE__}:#{__LINE__}")
|
33
34
|
end
|
@@ -40,7 +41,7 @@ module Formize
|
|
40
41
|
for column in form.model.columns
|
41
42
|
next if column.name =~ /_count$/ or [:id, :created_at, :updated_at, :lock_version, :type, :creator_id, :updater_id].include?(column.name.to_sym)
|
42
43
|
if column.name =~ /_id$/
|
43
|
-
reflections = form.model.reflections.select{|k, x| x.primary_key_name.to_s == column.name.to_s }
|
44
|
+
reflections = form.model.reflections.select{ |k, x| x.primary_key_name.to_s == column.name.to_s }
|
44
45
|
if reflections.size == 1
|
45
46
|
f.field(column.name.gsub(/_id$/, ''), :choices=>:all, :source=>:foreign_class, :new=>true)
|
46
47
|
# elsif reflections.size > 1 # AMBIGUITY
|
@@ -60,5 +61,5 @@ module Formize
|
|
60
61
|
|
61
62
|
end
|
62
63
|
|
63
|
-
require 'action_controller'
|
64
|
-
ActionController::Base.send(:include, Formize::ActionController)
|
64
|
+
# require 'action_controller'
|
65
|
+
# ActionController::Base.send(:include, Formize::ActionController)
|
data/lib/formize/definition.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Formize
|
2
|
+
# @private
|
3
|
+
module Definition
|
4
|
+
autoload :Form, 'formize/definition/form'
|
5
|
+
autoload :FormElement, 'formize/definition/form_element'
|
6
|
+
autoload :FieldSet, 'formize/definition/field_set'
|
7
|
+
autoload :Field, 'formize/definition/field'
|
8
|
+
end
|
9
|
+
end
|
@@ -1,65 +1,67 @@
|
|
1
1
|
module Formize
|
2
2
|
|
3
|
+
module Definition
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
# Represents the field element
|
6
|
+
class Field < FormElement
|
7
|
+
attr_reader :name, :column, :record_name, :method, :type, :required, :choices, :input_id, :source, :item_label, :field_id, :reflection, :html_options, :default, :search_attributes
|
7
8
|
|
8
|
-
|
9
|
+
TYPES = [:check_box, :choice, :date, :datetime, :label, :numeric, :password, :mono_choice, :string, :text_area].freeze
|
9
10
|
|
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
|
-
|
11
|
+
def initialize(form, parent, name, options={})
|
12
|
+
super(form, parent, options)
|
13
|
+
@name = name.to_s
|
14
|
+
@column = form.model.columns_hash[@name]
|
15
|
+
@record_name = form.record_name
|
16
|
+
@method = @name
|
17
|
+
unless @options[:default].nil?
|
18
|
+
@default = @options.delete(:default) # (@options[:default].is_a?(String) ? Formize::Generator::Code.new(@options[:default]) : @options[:default])
|
19
|
+
end
|
20
|
+
@html_options = @options.delete(:html_options)||{}
|
21
|
+
@depend_on = @options.delete(:depend_on)
|
22
|
+
raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.all_fields[@depend_on].nil?
|
23
|
+
if type = @options.delete(:as)
|
24
|
+
raise ArgumentError.new("Unknown field type (got #{@options[:as].inspect}, expects #{TYPES.join(', ')})") unless TYPES.include? type
|
25
|
+
@type = type
|
26
|
+
else
|
27
|
+
@type = :password if @name.to_s.match /password/
|
28
|
+
if @choices = @options.delete(:choices)
|
29
|
+
if @choices.is_a? Array
|
30
|
+
@type = :choice
|
31
|
+
elsif [Symbol, Hash].include? @choices.class
|
32
|
+
@type = :mono_choice
|
33
|
+
@reflection = form.model.reflections[@method.to_sym]
|
34
|
+
@source = @options.delete(:source) # || @reflection.class_name
|
35
|
+
@is_method = true if @options[:new]
|
36
|
+
@method_name = self.form.unique_name + "_inf_" + @name
|
37
|
+
@method = @reflection.primary_key_name
|
38
|
+
unless @item_label = @options.delete(:item_label)
|
39
|
+
model = @reflection.class_name.constantize
|
40
|
+
available_methods = (model.columns_hash.keys+model.instance_methods).collect{|x| x.to_s}
|
41
|
+
@item_label = [:label, :name, :title, :code, :number, :inspect].detect{|x| available_methods.include?(x.to_s)}
|
42
|
+
end
|
43
|
+
@search_attributes = @options[:search] || @reflection.class_name.constantize.content_columns.select{|c| c.type != :boolean and ![:created_at, :updated_at, :lock_version].include?(c.name.to_sym)}.collect{|c| c.name.to_sym}
|
44
|
+
else
|
45
|
+
raise ArgumentError.new("Option :choices must be Array, Symbol or Hash (got #{@choices.class.name})")
|
42
46
|
end
|
43
|
-
@search_attributes = @options[:search] || @reflection.class_name.constantize.content_columns.select{|c| c.type != :boolean and ![:created_at, :updated_at, :lock_version].include?(c.name.to_sym)}.collect{|c| c.name.to_sym}
|
44
|
-
else
|
45
|
-
raise ArgumentError.new("Option :choices must be Array, Symbol or Hash (got #{@choices.class.name})")
|
46
47
|
end
|
48
|
+
if column
|
49
|
+
@type = :check_box if column.type == :boolean
|
50
|
+
@type = :date if column.type == :date
|
51
|
+
@type = :datetime if column.type==:datetime or column.type==:timestamp
|
52
|
+
@type = :numeric if [:integer, :float, :decimal].include? column.type
|
53
|
+
@type = :text_area if column.type == :text
|
54
|
+
end
|
55
|
+
@type = :label if @form.model.readonly_attributes.include? @record_name
|
56
|
+
@type ||= :string
|
47
57
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
@type = :text_area if column.type == :text
|
54
|
-
end
|
55
|
-
@type = :label if @form.model.readonly_attributes.include? @record_name
|
56
|
-
@type ||= :string
|
58
|
+
@required = false
|
59
|
+
@required = !@column.null if @column
|
60
|
+
@required = true if @options.delete(:required).is_a?(TrueClass)
|
61
|
+
@input_id = form.model.name.underscore << '_' << method.to_s
|
62
|
+
@field_id = "ff" << Time.now.to_i.to_s(36) << rand.to_s[2..-1].to_i.to_s(36)
|
57
63
|
end
|
58
|
-
|
59
|
-
@required = !@column.null if @column
|
60
|
-
@required = true if @options.delete(:required).is_a?(TrueClass)
|
61
|
-
@input_id = form.model.name.underscore << '_' << method.to_s
|
62
|
-
@field_id = "ff" << Time.now.to_i.to_s(36) << rand.to_s[2..-1].to_i.to_s(36)
|
64
|
+
|
63
65
|
end
|
64
66
|
|
65
67
|
end
|
@@ -1,40 +1,65 @@
|
|
1
1
|
module Formize
|
2
|
+
|
3
|
+
module Definition
|
2
4
|
|
5
|
+
# Represents a group of fields which can depend on other fields
|
6
|
+
class Group < FormElement
|
7
|
+
attr_reader :name, :options, :html_options
|
8
|
+
|
9
|
+
def initialize(form, parent, name=nil, options={})
|
10
|
+
super(form, parent, options)
|
11
|
+
@name = if name.blank?
|
12
|
+
rand.to_s[2..-1].to_i.to_s(36)
|
13
|
+
else
|
14
|
+
raise ArgumentError.new("Name of group must be written only with a-z and 0-9 and _ (not #{name.inspect})") unless name.to_s == name.to_s.downcase.gsub(/[^a-z0-9\_]/, '')
|
15
|
+
name.to_s
|
16
|
+
end
|
17
|
+
@depend_on = options.delete(:depend_on)
|
18
|
+
raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.all_fields[@depend_on].nil?
|
19
|
+
@html_options = @options.delete(:html_options)||{}
|
20
|
+
end
|
3
21
|
|
4
22
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
super(form, parent)
|
11
|
-
@title = nil
|
12
|
-
@name = if name.blank?
|
13
|
-
rand.to_s[2..-1].to_i.to_s(36)
|
14
|
-
else
|
15
|
-
raise ArgumentError.new("Name of field_set must be written only with a-z and 0-9 and _ (not #{name.inspect})") unless name.to_s == name.to_s.downcase.gsub(/[^a-z0-9\_]/, '')
|
16
|
-
@title = name
|
17
|
-
name.to_s
|
18
|
-
end
|
19
|
-
@depend_on = options.delete(:depend_on)
|
20
|
-
raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.fields[@depend_on].nil?
|
21
|
-
@options = (options.is_a?(Hash) ? options : {})
|
22
|
-
@html_options = @options.delete(:html_options)||{}
|
23
|
-
end
|
23
|
+
def field_set(name=nil, options={}, &block)
|
24
|
+
raise ArgumentError.new("Missing block") unless block_given?
|
25
|
+
field_set = self.new_child(FieldSet, name, options)
|
26
|
+
yield field_set
|
27
|
+
end
|
24
28
|
|
29
|
+
def group(name=nil, options={}, &block)
|
30
|
+
raise ArgumentError.new("Missing block") unless block_given?
|
31
|
+
name, options = nil, name if name.is_a? Hash
|
32
|
+
group = self.new_child(Group, name, options)
|
33
|
+
yield group
|
34
|
+
end
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
36
|
+
def field(name, options={})
|
37
|
+
self.new_child(Field, name, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def fields(*args)
|
41
|
+
options = {}
|
42
|
+
options = args.delete_at(-1) if args[-1].is_a?(Hash)
|
43
|
+
for name in args
|
44
|
+
self.new_child(Field, name, options)
|
45
|
+
end
|
46
|
+
end
|
31
47
|
|
32
|
-
def field(name, options={})
|
33
|
-
self.new_child(Field, name, options)
|
34
48
|
end
|
35
49
|
|
36
|
-
end
|
37
50
|
|
51
|
+
# Represents a set of fields which can depend on other fields
|
52
|
+
# It can be used with a title
|
53
|
+
class FieldSet < Group
|
54
|
+
attr_reader :title
|
55
|
+
|
56
|
+
def initialize(form, parent, name=nil, options={})
|
57
|
+
super(form, parent, name, options)
|
58
|
+
@title = name
|
59
|
+
end
|
38
60
|
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
39
64
|
|
40
65
|
end
|
@@ -1,89 +1,103 @@
|
|
1
|
-
module Formize
|
2
|
-
|
3
|
-
# Represents an environment for a form or list of fields of one Record
|
4
|
-
class Form
|
5
|
-
attr_reader :model, :elements, :record_name, :unique_name, :options, :id
|
6
|
-
@@count = 0
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(name, model, options={})
|
10
|
-
@name = name
|
11
|
-
@model = model
|
12
|
-
@options = options
|
13
|
-
@elements = []
|
14
|
-
@@count += 1
|
15
|
-
@id = @@count.to_s(36)
|
16
|
-
@unique_name = @options.delete(:unique_name) unless @options[:unique_name].blank?
|
17
|
-
@unique_name ||= "_formize#{@id}"
|
18
|
-
@record_name = @model.name.underscore
|
19
|
-
end
|
20
|
-
|
21
|
-
def field_set(name=nil, options={}, &block)
|
22
|
-
raise ArgumentError.new("Missing block") unless block_given?
|
23
|
-
field_set = new_element(FieldSet, name, options)
|
24
|
-
yield field_set
|
25
|
-
end
|
26
|
-
|
27
|
-
def field(name, options={})
|
28
|
-
return new_element(Field, name, options)
|
29
|
-
end
|
30
|
-
|
31
|
-
# def inner_method_code(options={})
|
32
|
-
# varh = options[:html_variable] || 'html'
|
33
|
-
# code = "#{varh} = ''\n"
|
34
|
-
# for child in children
|
35
|
-
# code << "#{varh} << " << child.method_call_code << "\n"
|
36
|
-
# end
|
37
|
-
# code << "return #{varh}\n"
|
38
|
-
# return code
|
39
|
-
# end
|
40
|
-
|
41
|
-
def controller_method_name
|
42
|
-
@options[:controller_method_name] || "formize_#{model.underscore}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def view_method_name
|
46
|
-
@options[:method_name] || "_form_#{model.underscore}"
|
47
|
-
end
|
48
|
-
|
49
|
-
def action_name
|
50
|
-
@options[:action_name] || :formize
|
51
|
-
end
|
52
|
-
|
53
|
-
# def methodics
|
54
|
-
# return elements.collect{|e| e.methodics}.flatten
|
55
|
-
# end
|
56
|
-
|
57
|
-
def mono_choices
|
58
|
-
return elements.collect{|e| e.mono_choices}.flatten
|
59
|
-
end
|
60
|
-
|
61
|
-
def fields
|
62
|
-
return elements.inject(HashWithIndifferentAccess.new){|h, e| h.merge!(e.fields)}
|
63
|
-
end
|
64
|
-
|
65
|
-
def dependents
|
66
|
-
return elements.collect{|e| e.dependents}.flatten
|
67
|
-
end
|
68
|
-
|
69
|
-
def all_elements
|
70
|
-
return elements.collect{|e| e.all_elements}.flatten
|
71
|
-
end
|
72
|
-
|
73
|
-
def dependents_on(element)
|
74
|
-
return elements.collect{|e| e.dependents_on(element)}.flatten
|
75
|
-
end
|
76
1
|
|
2
|
+
module Formize
|
77
3
|
|
78
|
-
|
4
|
+
module Definition
|
5
|
+
# Represents an environment for a form or list of fields of one Record
|
6
|
+
class Form
|
7
|
+
attr_reader :elements, :model, :name, :record_name, :unique_name, :options, :id
|
8
|
+
@@count = 0
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(name, model, options={})
|
12
|
+
@name = name
|
13
|
+
@model = model
|
14
|
+
@options = options
|
15
|
+
@elements = []
|
16
|
+
@@count += 1
|
17
|
+
@id = @@count.to_s(36)
|
18
|
+
@unique_name = @options.delete(:unique_name) unless @options[:unique_name].blank?
|
19
|
+
@unique_name ||= "_formize#{@id}"
|
20
|
+
@record_name = @model.name.underscore
|
21
|
+
end
|
22
|
+
|
23
|
+
def field_set(name=nil, options={}, &block)
|
24
|
+
raise ArgumentError.new("Missing block") unless block_given?
|
25
|
+
field_set = new_element(FieldSet, name, options)
|
26
|
+
yield field_set
|
27
|
+
end
|
28
|
+
|
29
|
+
def group(name, options={}, &block)
|
30
|
+
raise ArgumentError.new("Missing block") unless block_given?
|
31
|
+
name, options = nil, name if name.is_a? Hash
|
32
|
+
group = new_element(Group, name, options)
|
33
|
+
yield group
|
34
|
+
end
|
35
|
+
|
36
|
+
def field(name, options={})
|
37
|
+
return new_element(Field, name, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def fields(*args)
|
41
|
+
options = {}
|
42
|
+
options = args.delete_at(-1) if args[-1].is_a?(Hash)
|
43
|
+
for name in args
|
44
|
+
new_element(Field, name, options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# protected
|
50
|
+
|
51
|
+
def controller_method_name
|
52
|
+
@options[:controller_method_name] || "formize_#{model.underscore}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def view_method_name
|
56
|
+
@options[:method_name] || "_form_#{model.underscore}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def action_name
|
60
|
+
@options[:action_name] || :formize
|
61
|
+
end
|
62
|
+
|
63
|
+
def mono_choices
|
64
|
+
return elements.collect{|e| e.mono_choices}.flatten
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_fields
|
68
|
+
return elements.inject(HashWithIndifferentAccess.new){|h, e| h.merge!(e.all_fields)}
|
69
|
+
end
|
70
|
+
|
71
|
+
def dependents
|
72
|
+
return elements.collect{|e| e.dependents}.flatten
|
73
|
+
end
|
74
|
+
|
75
|
+
def all_elements
|
76
|
+
return elements.collect{|e| e.all_elements}.flatten
|
77
|
+
end
|
78
|
+
|
79
|
+
def dependents_on(element)
|
80
|
+
return elements.collect{|e| e.dependents_on(element)}.flatten
|
81
|
+
end
|
82
|
+
|
83
|
+
def shown_if(element)
|
84
|
+
return elements.collect{|e| e.shown_if(element)}.flatten
|
85
|
+
end
|
86
|
+
|
87
|
+
def hidden_if(element)
|
88
|
+
return elements.collect{|e| e.hidden_if(element)}.flatten
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def new_element(klass, *args)
|
95
|
+
raise ArgumentError.new("Bad child type: #{klass.name} (#{klass.ancestors.inspect}). Must be an Formize::Definition::FormElement") unless klass < Formize::Definition::FormElement # klass.ancestors.include? Formize::FormElement
|
96
|
+
element = klass.new(self, nil, *args)
|
97
|
+
@elements << element
|
98
|
+
return element
|
99
|
+
end
|
79
100
|
|
80
|
-
def new_element(klass, *args)
|
81
|
-
raise ArgumentError.new("Bad child type (#{klass.name}). Must be an Formize::FormElement") unless klass < FormElement
|
82
|
-
element = klass.new(self, nil, *args)
|
83
|
-
@elements << element
|
84
|
-
return element
|
85
101
|
end
|
86
|
-
|
87
102
|
end
|
88
|
-
|
89
103
|
end
|