humpyard_form 0.0.1 → 0.0.2
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/Gemfile +6 -6
- data/README.rdoc +4 -0
- data/VERSION +1 -1
- data/app/views/humpyard_form/_boolean_input.html.haml +1 -0
- data/app/views/humpyard_form/_color_input.html.haml +1 -0
- data/app/views/humpyard_form/_date_input.html.haml +1 -0
- data/app/views/humpyard_form/_datetime_input.html.haml +1 -1
- data/app/views/humpyard_form/_email_input.html.haml +1 -0
- data/app/views/humpyard_form/_form_element.html.haml +3 -2
- data/app/views/humpyard_form/_month_input.html.haml +1 -0
- data/app/views/humpyard_form/_numeric_input.html.haml +1 -0
- data/app/views/humpyard_form/_password_input.html.haml +1 -0
- data/app/views/humpyard_form/_range_input.html.haml +5 -0
- data/app/views/humpyard_form/_search_input.html.haml +1 -0
- data/app/views/humpyard_form/_select_input.html.haml +1 -1
- data/app/views/humpyard_form/_string_input.html.haml +1 -1
- data/app/views/humpyard_form/_submit.html.haml +1 -1
- data/app/views/humpyard_form/_tel_input.html.haml +1 -0
- data/app/views/humpyard_form/_text_input.html.haml +1 -1
- data/app/views/humpyard_form/_time_input.html.haml +1 -0
- data/app/views/humpyard_form/_url_input.html.haml +1 -0
- data/app/views/humpyard_form/_week_input.html.haml +1 -0
- data/config/locales/en.yml +4 -1
- data/lib/humpyard_form/config.rb +5 -0
- data/lib/humpyard_form/form_builder.rb +146 -39
- metadata +53 -37
data/Gemfile
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
source 'http://gemcutter.org'
|
2
2
|
|
3
|
-
gem "rails",
|
4
|
-
gem 'haml',
|
5
|
-
gem 'compass',
|
3
|
+
gem "rails", '>= 3.0.0.beta3'
|
4
|
+
gem 'haml', '>= 3.0.0.rc.4'
|
5
|
+
gem 'compass', '>= 0.10.0.rc5'
|
6
6
|
|
7
7
|
group :test do
|
8
8
|
gem 'test-unit'
|
9
|
-
gem 'rspec-rails', '>= 2.0.0.beta.
|
9
|
+
gem 'rspec-rails', '>= 2.0.0.beta.8'
|
10
10
|
gem 'capybara', '>= 0.3.7'
|
11
11
|
gem 'database_cleaner', '>= 0.5.2'
|
12
|
-
gem 'cucumber'
|
13
|
-
gem 'cucumber
|
12
|
+
gem 'cucumber-rails'
|
13
|
+
gem 'cucumber', '0.7.2'
|
14
14
|
gem 'pickle', '>= 0.2.4'
|
15
15
|
gem 'capybara', '>= 0.3.5'
|
16
16
|
gem 'factory_girl', '>= 1.2.3'
|
data/README.rdoc
CHANGED
@@ -32,6 +32,10 @@ A HumpyardForm is doing fare control. So HumpyardForm is an authentication syste
|
|
32
32
|
* Commit, do not mess with rakefile, version, or history. If you want to have your own version, thats fine. But bump your version in a seperate commit that can be ignored when pulling.
|
33
33
|
* Send me a pull request. Bonus points for topic branches.
|
34
34
|
|
35
|
+
== Credits
|
36
|
+
|
37
|
+
We want to send our thanks to Justin French and his co-workers as formtastic deeply inspired this gem.
|
38
|
+
|
35
39
|
== Copyright
|
36
40
|
|
37
41
|
Copyright (c) 2010 Sven G. Brönstrup. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "checkbox", :name => "#{form.namespace}[#{name}]", :value => "#{options[:value] || 1}", :class => "boolean ui-widget-content ui-corner-all field-highlight", :checked => form.object.send(name) ? 'checked' : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "color", 'data-type' => "color", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "color-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off'}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "date", 'data-type' => "date", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "date-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min].strftime('%Y-%m-%d'), :max => options[:max].blank? ? false : options[:max].strftime('%Y-%m-%d'), :step => options[:step].blank? ? false : options[:step], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -1 +1 @@
|
|
1
|
-
%input{:type => "
|
1
|
+
%input{:type => "datetime", 'data-type' => "datetime", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "datetime-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min].iso8601, :max => options[:max].blank? ? false : options[:max].iso8601, :step => options[:step].blank? ? false : options[:step], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "email", 'data-type' => "email", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "email-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :size => options[:size].blank? ? false : options[:size], :pattern => options[:pattern].blank? ? false : options[:pattern], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -1,7 +1,8 @@
|
|
1
|
-
- puts name
|
2
1
|
.input{:class => "attr_#{name}"}
|
3
2
|
%div
|
4
|
-
|
3
|
+
- if options[:required].nil?
|
4
|
+
- options[:required] = form.object.class.validators_on(name.to_s).map(&:class).include?(ActiveModel::Validations::PresenceValidator)
|
5
|
+
%label{:class => options[:required] ? 'required' : false}
|
5
6
|
= form.object.class.human_attribute_name(name)
|
6
7
|
%span.field-errors.ui-state-error-text{:style => form.object.errors[name].first.nil? ? 'display:none;' : ''}
|
7
8
|
= form.object.errors[name].first
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "month", 'data-type' => "month", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "month-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min].strftime('%Y-%m'), :max => options[:max].blank? ? false : options[:max].strftime('%Y-%m'), :step => options[:step].blank? ? false : options[:step], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "number", 'data-type' => "number", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "number-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min], :max => options[:max].blank? ? false : options[:max], :step => options[:step].blank? ? false : options[:step], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "password", :name => "#{form.namespace}[#{name}]", :class => "password-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :size => options[:size].blank? ? false : options[:size], :pattern => options[:pattern].blank? ? false : options[:pattern], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
%input{:type => "range", 'data-type' => "range", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "range-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min], :max => options[:max].blank? ? false : options[:max], :step => options[:step].blank? ? false : options[:step], :required => options[:required] ? true : false, :list => options[:list].blank? ? false : "#{form.namespace}_#{name}_#{form.uuid}_list"}
|
2
|
+
- unless options[:list].blank?
|
3
|
+
%datalist{:id => "#{form.namespace}_#{name}_#{form.uuid}_list"}
|
4
|
+
- options[:list].each do |item|
|
5
|
+
%option{:value => item}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "search", 'data-type' => "search", :name => "#{form.namespace}[#{name}]", :value => "#{form.object.send(name)}", :class => "search-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :size => options[:size].blank? ? false : options[:size], :pattern => options[:pattern].blank? ? false : options[:pattern], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -1,4 +1,4 @@
|
|
1
1
|
%select{:name => "#{form.namespace}[#{name}]", :class => "select"}
|
2
|
-
- options
|
2
|
+
- form.find_collection_for_column(name, options).each do |option|
|
3
3
|
%option{:value => "#{option[1]}", :selected => (option[1] == form.object.send(name))}
|
4
4
|
= option[0] #form.object.send(name)
|
@@ -1 +1 @@
|
|
1
|
-
%input{:type => "text", :name => "#{form.namespace}[#{name}]", :value => "#{form.object.send(name)}", :class => "text ui-widget-content ui-corner-all field-highlight"}
|
1
|
+
%input{:type => "text", :name => "#{form.namespace}[#{name}]", :value => "#{form.object.send(name)}", :class => "text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :size => options[:size].blank? ? false : options[:size], :pattern => options[:pattern].blank? ? false : options[:pattern], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -1 +1 @@
|
|
1
|
-
%button
|
1
|
+
%button{:type => 'submit'}=I18n.t("humpyard_form.buttons.#{form.object.persisted? ? 'update' : 'create'}", :model => form.object.class.model_name.human)
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "tel", 'data-type' => "tel", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "tel-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :size => options[:size].blank? ? false : options[:size], :pattern => options[:pattern].blank? ? false : options[:pattern], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
%textarea{:name => "#{form.namespace}[#{name}]", :class => "text ui-widget-content ui-corner-all field-highlight"}
|
1
|
+
%textarea{:name => "#{form.namespace}[#{name}]", :class => "text ui-widget-content ui-corner-all field-highlight", :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :cols => options[:cols].blank? ? false : options[:cols], :rows => options[:rows].blank? ? false : options[:rows], :wrap => options[:wrap].blank? ? false : options[:wrap], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :disabled => options[:readonly] ? 'disabled' : false, :required => options[:required] ? true : false}
|
2
2
|
= preserve raw(form.object.send(name))
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "time", 'data-type' => "time", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "time-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min], :max => options[:max].blank? ? false : options[:max], :step => options[:step].blank? ? false : options[:step], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "url", 'data-type' => "url", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "url-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :maxlength => options[:maxlength].blank? ? false : options[:maxlength], :size => options[:size].blank? ? false : options[:size], :pattern => options[:pattern].blank? ? false : options[:pattern], :placeholder => options[:placeholder].blank? ? false : options[:placeholder], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:type => "week", 'data-type' => "week", :name => "#{form.namespace}[#{name}]", :value => form.object.send(name).blank? ? false : "#{form.object.send(name)}", :class => "week-field text ui-widget-content ui-corner-all field-highlight", :autocomplete => options[:autocomplete].nil? ? false : options[:autocomplete] ? 'on' : 'off', :min => options[:min].blank? ? false : options[:min].strftime('%Y-W%W'), :max => options[:max].blank? ? false : options[:max].strftime('%Y-W%W'), :step => options[:step].blank? ? false : options[:step], :readonly => options[:readonly] ? true : false, :required => options[:required] ? true : false}
|
data/config/locales/en.yml
CHANGED
data/lib/humpyard_form/config.rb
CHANGED
@@ -14,6 +14,8 @@ module HumpyardForm
|
|
14
14
|
# The default value is <tt>"admin"</tt>
|
15
15
|
|
16
16
|
class Config
|
17
|
+
attr_writer :collection_label_methods
|
18
|
+
|
17
19
|
def initialize(&block) #:nodoc:
|
18
20
|
configure(&block) if block_given?
|
19
21
|
end
|
@@ -38,5 +40,8 @@ module HumpyardForm
|
|
38
40
|
@locales ||= [:en]
|
39
41
|
end
|
40
42
|
|
43
|
+
def collection_label_methods
|
44
|
+
@collection_label_methods ||= %w[to_label display_name full_name name title username login value to_s]
|
45
|
+
end
|
41
46
|
end
|
42
47
|
end
|
@@ -34,41 +34,16 @@ module HumpyardForm
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def uuid
|
38
|
+
@uuid ||= rand(1000)
|
38
39
|
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
# options[:as] ||= default_input_type(method)
|
43
|
-
#
|
44
|
-
# html_class = [ options[:as], (options[:required] ? :required : :optional) ]
|
45
|
-
# html_class << 'error' if @object && @object.respond_to?(:errors) && !@object.errors[method.to_sym].blank?
|
46
|
-
#
|
47
|
-
# wrapper_html = options.delete(:wrapper_html) || {}
|
48
|
-
# wrapper_html[:id] ||= generate_html_id(method)
|
49
|
-
# wrapper_html[:class] = (html_class << wrapper_html[:class]).flatten.compact.join(' ')
|
50
|
-
#
|
51
|
-
# if options[:input_html] && options[:input_html][:id]
|
52
|
-
# options[:label_html] ||= {}
|
53
|
-
# options[:label_html][:for] ||= options[:input_html][:id]
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# input_parts = @@inline_order.dup
|
57
|
-
# input_parts.delete(:errors) if options[:as] == :hidden
|
58
|
-
#
|
59
|
-
# list_item_content = input_parts.map do |type|
|
60
|
-
# send(:"inline_#{type}_for", method, options)
|
61
|
-
# end.compact.join("\n")
|
62
|
-
#
|
63
|
-
# return template.content_tag(:li, list_item_content, wrapper_html)
|
64
|
-
# end
|
65
|
-
|
41
|
+
def inputs
|
42
|
+
end
|
66
43
|
|
67
44
|
def input(method, options={}) #:nodoc:
|
68
|
-
#options[:required] = method_required?(method) unless options.key?(:required)
|
69
45
|
options[:as] ||= default_input_type(method)
|
70
46
|
options[:translation_info] = translation_info(method)
|
71
|
-
#puts options.inspect
|
72
47
|
@renderer.render :partial => "/humpyard_form/form_element", :locals => {:form => self, :name => method, :options => options, :as => options[:as]}
|
73
48
|
end
|
74
49
|
|
@@ -90,15 +65,8 @@ module HumpyardForm
|
|
90
65
|
end
|
91
66
|
end
|
92
67
|
|
93
|
-
#
|
94
|
-
|
95
|
-
# cases it will simplify (like the case of :integer, :float & :decimal to :numeric), or do
|
96
|
-
# something different (like :password and :select).
|
97
|
-
#
|
98
|
-
# If there is no column for the method (eg "virtual columns" with an attr_accessor), the
|
99
|
-
# default is a :string, a similar behaviour to Rails' scaffolding.
|
100
|
-
#
|
101
|
-
def default_input_type(method) #:nodoc:
|
68
|
+
# Get Column infomation for methods
|
69
|
+
def column_info(method)
|
102
70
|
column = @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute)
|
103
71
|
|
104
72
|
# translated attributes dont have a column info at this point
|
@@ -109,6 +77,20 @@ module HumpyardForm
|
|
109
77
|
column = tx_info[:column]
|
110
78
|
end
|
111
79
|
end
|
80
|
+
|
81
|
+
column
|
82
|
+
end
|
83
|
+
|
84
|
+
# For methods that have a database column, take a best guess as to what the input method
|
85
|
+
# should be. In most cases, it will just return the column type (eg :string), but for special
|
86
|
+
# cases it will simplify (like the case of :integer, :float & :decimal to :numeric), or do
|
87
|
+
# something different (like :password and :select).
|
88
|
+
#
|
89
|
+
# If there is no column for the method (eg "virtual columns" with an attr_accessor), the
|
90
|
+
# default is a :string, a similar behaviour to Rails' scaffolding.
|
91
|
+
#
|
92
|
+
def default_input_type(method) #:nodoc:
|
93
|
+
column = column_info(method)
|
112
94
|
|
113
95
|
if column
|
114
96
|
# handle the special cases where the column type doesn't map to an input method
|
@@ -117,7 +99,7 @@ module HumpyardForm
|
|
117
99
|
return :datetime if column.type == :timestamp
|
118
100
|
return :numeric if [:integer, :float, :decimal].include?(column.type)
|
119
101
|
return :password if column.type == :string && method.to_s =~ /password/
|
120
|
-
return :country if column.type == :string && method.to_s =~ /country/
|
102
|
+
#return :country if column.type == :string && method.to_s =~ /country/
|
121
103
|
|
122
104
|
# otherwise assume the input name will be the same as the column type (eg string_input)
|
123
105
|
return column.type
|
@@ -140,6 +122,131 @@ module HumpyardForm
|
|
140
122
|
end
|
141
123
|
end
|
142
124
|
|
125
|
+
# Used by select and radio inputs. The collection can be retrieved by
|
126
|
+
# three ways:
|
127
|
+
#
|
128
|
+
# * Explicitly provided through :collection
|
129
|
+
# * Retrivied through an association
|
130
|
+
# * Or a boolean column, which will generate a localized { "Yes" => true, "No" => false } hash.
|
131
|
+
#
|
132
|
+
# If the collection is not a hash or an array of strings, fixnums or arrays,
|
133
|
+
# we use label_method and value_method to retreive an array with the
|
134
|
+
# appropriate label and value.
|
135
|
+
#
|
136
|
+
def find_collection_for_column(column, options) #:nodoc:
|
137
|
+
collection = find_raw_collection_for_column(column, options)
|
138
|
+
|
139
|
+
# Return if we have an Array of strings, fixnums or arrays
|
140
|
+
return collection if (collection.instance_of?(Array) || collection.instance_of?(Range)) &&
|
141
|
+
[Array, Fixnum, String, Symbol].include?(collection.first.class)
|
142
|
+
|
143
|
+
label, value = detect_label_and_value_method!(collection, options)
|
144
|
+
collection.map { |o| [send_or_call(label, o), send_or_call(value, o)] }
|
145
|
+
end
|
146
|
+
|
147
|
+
# As #find_collection_for_column but returns the collection without mapping the label and value
|
148
|
+
#
|
149
|
+
def find_raw_collection_for_column(column, options) #:nodoc:
|
150
|
+
collection = if options[:collection]
|
151
|
+
options.delete(:collection)
|
152
|
+
elsif reflection = self.reflection_for(column.to_s.gsub(/_id$/, '').to_sym)
|
153
|
+
options[:find_options] ||= {}
|
154
|
+
|
155
|
+
if conditions = reflection.options[:conditions]
|
156
|
+
options[:find_options][:conditions] = reflection.klass.merge_conditions(conditions, options[:find_options][:conditions])
|
157
|
+
end
|
158
|
+
|
159
|
+
reflection.klass.find(:all, options[:find_options])
|
160
|
+
else
|
161
|
+
create_boolean_collection(options)
|
162
|
+
end
|
163
|
+
|
164
|
+
collection = collection.to_a if collection.is_a?(Hash)
|
165
|
+
collection
|
166
|
+
end
|
167
|
+
|
168
|
+
# Detects the label and value methods from a collection values set in
|
169
|
+
# @@collection_label_methods. It will use and delete
|
170
|
+
# the options :label_method and :value_methods when present
|
171
|
+
#
|
172
|
+
def detect_label_and_value_method!(collection_or_instance, options = {}) #:nodoc
|
173
|
+
label = options.delete(:label_method) || detect_label_method(collection_or_instance)
|
174
|
+
value = options.delete(:value_method) || :id
|
175
|
+
[label, value]
|
176
|
+
end
|
177
|
+
|
178
|
+
# Detected the label collection method when none is supplied using the
|
179
|
+
# values set in @@collection_label_methods.
|
180
|
+
#
|
181
|
+
def detect_label_method(collection) #:nodoc:
|
182
|
+
HumpyardForm::config.collection_label_methods.detect { |m| collection.first.respond_to?(m) }
|
183
|
+
end
|
184
|
+
|
185
|
+
# Detects the method to call for fetching group members from the groups when grouping select options
|
186
|
+
#
|
187
|
+
def detect_group_association(method, group_by)
|
188
|
+
object_to_method_reflection = self.reflection_for(method)
|
189
|
+
method_class = object_to_method_reflection.klass
|
190
|
+
|
191
|
+
method_to_group_association = method_class.reflect_on_association(group_by)
|
192
|
+
group_class = method_to_group_association.klass
|
193
|
+
|
194
|
+
# This will return in the normal case
|
195
|
+
return method.to_s.pluralize.to_sym if group_class.reflect_on_association(method.to_s.pluralize)
|
196
|
+
|
197
|
+
# This is for belongs_to associations named differently than their class
|
198
|
+
# form.input :parent, :group_by => :customer
|
199
|
+
# eg.
|
200
|
+
# class Project
|
201
|
+
# belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
|
202
|
+
# belongs_to :customer
|
203
|
+
# end
|
204
|
+
# class Customer
|
205
|
+
# has_many :projects
|
206
|
+
# end
|
207
|
+
group_method = method_class.to_s.underscore.pluralize.to_sym
|
208
|
+
return group_method if group_class.reflect_on_association(group_method) # :projects
|
209
|
+
|
210
|
+
# This is for has_many associations named differently than their class
|
211
|
+
# eg.
|
212
|
+
# class Project
|
213
|
+
# belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id'
|
214
|
+
# belongs_to :customer
|
215
|
+
# end
|
216
|
+
# class Customer
|
217
|
+
# has_many :tasks, :class_name => 'Project', :foreign_key => 'customer_id'
|
218
|
+
# end
|
219
|
+
possible_associations = group_class.reflect_on_all_associations(:has_many).find_all{|assoc| assoc.klass == object_class}
|
220
|
+
return possible_associations.first.name.to_sym if possible_associations.count == 1
|
221
|
+
|
222
|
+
raise "Cannot infer group association for #{method} grouped by #{group_by}, there were #{possible_associations.empty? ? 'no' : possible_associations.size} possible associations. Please specify using :group_association"
|
223
|
+
end
|
224
|
+
|
225
|
+
# Returns a hash to be used by radio and select inputs when a boolean field
|
226
|
+
# is provided.
|
227
|
+
#
|
228
|
+
def create_boolean_collection(options) #:nodoc:
|
229
|
+
options[:true] ||= ::I18n.t(:yes)
|
230
|
+
options[:false] ||= ::I18n.t(:no)
|
231
|
+
options[:value_as_class] = true unless options.key?(:value_as_class)
|
232
|
+
|
233
|
+
[ [ options.delete(:true), true], [ options.delete(:false), false ] ]
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
# If an association method is passed in (f.input :author) try to find the
|
238
|
+
# reflection object.
|
239
|
+
#
|
240
|
+
def reflection_for(method) #:nodoc:
|
241
|
+
@object.class.reflect_on_association(method) if @object.class.respond_to?(:reflect_on_association)
|
242
|
+
end
|
143
243
|
|
244
|
+
def send_or_call(duck, object)
|
245
|
+
if duck.is_a?(Proc)
|
246
|
+
duck.call(object)
|
247
|
+
else
|
248
|
+
object.send(duck)
|
249
|
+
end
|
250
|
+
end
|
144
251
|
end
|
145
252
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Sven G. Broenstrup
|
@@ -15,25 +15,25 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-05-
|
18
|
+
date: 2010-05-07 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
22
23
|
name: builder
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
segments:
|
29
29
|
- 0
|
30
30
|
version: "0"
|
31
|
-
|
32
|
-
|
31
|
+
requirement: *id001
|
32
|
+
prerelease: false
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
+
type: :runtime
|
34
35
|
name: rails
|
35
|
-
|
36
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
@@ -41,42 +41,45 @@ dependencies:
|
|
41
41
|
- 3
|
42
42
|
- 0
|
43
43
|
- 0
|
44
|
-
-
|
45
|
-
version: 3.0.0.
|
46
|
-
|
47
|
-
|
44
|
+
- beta3
|
45
|
+
version: 3.0.0.beta3
|
46
|
+
requirement: *id002
|
47
|
+
prerelease: false
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
+
type: :runtime
|
49
50
|
name: haml
|
50
|
-
|
51
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
segments:
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
name: acts_as_tree
|
56
|
+
- 3
|
57
|
+
- 0
|
58
|
+
- 0
|
59
|
+
- rc
|
60
|
+
- 4
|
61
|
+
version: 3.0.0.rc.4
|
62
|
+
requirement: *id003
|
64
63
|
prerelease: false
|
65
|
-
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
type: :runtime
|
66
|
+
name: compass
|
67
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
66
68
|
requirements:
|
67
69
|
- - ">="
|
68
70
|
- !ruby/object:Gem::Version
|
69
71
|
segments:
|
70
72
|
- 0
|
71
|
-
-
|
72
|
-
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
- 10
|
74
|
+
- 0
|
75
|
+
- rc5
|
76
|
+
version: 0.10.0.rc5
|
77
|
+
requirement: *id004
|
78
|
+
prerelease: false
|
76
79
|
- !ruby/object:Gem::Dependency
|
80
|
+
type: :runtime
|
77
81
|
name: cancan
|
78
|
-
|
79
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
80
83
|
requirements:
|
81
84
|
- - ">="
|
82
85
|
- !ruby/object:Gem::Version
|
@@ -85,12 +88,12 @@ dependencies:
|
|
85
88
|
- 1
|
86
89
|
- 1
|
87
90
|
version: 1.1.1
|
88
|
-
|
89
|
-
|
91
|
+
requirement: *id005
|
92
|
+
prerelease: false
|
90
93
|
- !ruby/object:Gem::Dependency
|
94
|
+
type: :runtime
|
91
95
|
name: globalize2
|
92
|
-
|
93
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
94
97
|
requirements:
|
95
98
|
- - ">="
|
96
99
|
- !ruby/object:Gem::Version
|
@@ -99,8 +102,8 @@ dependencies:
|
|
99
102
|
- 2
|
100
103
|
- 0
|
101
104
|
version: 0.2.0
|
102
|
-
|
103
|
-
|
105
|
+
requirement: *id006
|
106
|
+
prerelease: false
|
104
107
|
description: HumpyardForm is an form builder for Rails 3 applications. It is developed as part of the humpyard cms
|
105
108
|
email: info@humpyard.org
|
106
109
|
executables: []
|
@@ -117,15 +120,28 @@ files:
|
|
117
120
|
- lib/humpyard_form/engine.rb
|
118
121
|
- lib/humpyard_form/form_builder.rb
|
119
122
|
- lib/humpyard_form.rb
|
123
|
+
- app/views/humpyard_form/_boolean_input.html.haml
|
124
|
+
- app/views/humpyard_form/_color_input.html.haml
|
125
|
+
- app/views/humpyard_form/_date_input.html.haml
|
120
126
|
- app/views/humpyard_form/_datetime_input.html.haml
|
127
|
+
- app/views/humpyard_form/_email_input.html.haml
|
121
128
|
- app/views/humpyard_form/_file_input.html.haml
|
122
129
|
- app/views/humpyard_form/_form.html.haml
|
123
130
|
- app/views/humpyard_form/_form_element.html.haml
|
124
131
|
- app/views/humpyard_form/_image_file_input.html.haml
|
132
|
+
- app/views/humpyard_form/_month_input.html.haml
|
133
|
+
- app/views/humpyard_form/_numeric_input.html.haml
|
134
|
+
- app/views/humpyard_form/_password_input.html.haml
|
135
|
+
- app/views/humpyard_form/_range_input.html.haml
|
136
|
+
- app/views/humpyard_form/_search_input.html.haml
|
125
137
|
- app/views/humpyard_form/_select_input.html.haml
|
126
138
|
- app/views/humpyard_form/_string_input.html.haml
|
127
139
|
- app/views/humpyard_form/_submit.html.haml
|
140
|
+
- app/views/humpyard_form/_tel_input.html.haml
|
128
141
|
- app/views/humpyard_form/_text_input.html.haml
|
142
|
+
- app/views/humpyard_form/_time_input.html.haml
|
143
|
+
- app/views/humpyard_form/_url_input.html.haml
|
144
|
+
- app/views/humpyard_form/_week_input.html.haml
|
129
145
|
- config/locales/en.yml
|
130
146
|
- VERSION
|
131
147
|
- README.rdoc
|