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