maiha-active_record_view 0.1
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/README +25 -0
- data/Rakefile +22 -0
- data/arv/properties/boolean +4 -0
- data/arv/properties/date +5 -0
- data/arv/properties/datetime +5 -0
- data/arv/properties/default +3 -0
- data/arv/properties/integer +6 -0
- data/arv/properties/string +4 -0
- data/arv/properties/text +7 -0
- data/arv/properties/time +5 -0
- data/arv/properties/timestamp +5 -0
- data/arv/property.erb +19 -0
- data/init.rb +0 -0
- data/install.rb +1 -0
- data/lib/active_record_view.rb +2 -0
- data/lib/active_record_view/controller.rb +9 -0
- data/lib/active_record_view/default_actions.rb +29 -0
- data/lib/active_record_view/engines.rb +68 -0
- data/lib/active_record_view/helper.rb +152 -0
- data/lib/active_record_view/record_identifier.rb +42 -0
- data/lib/active_record_view/render_arv.rb +51 -0
- data/lib/active_record_view/write_exception.rb +11 -0
- data/lib/localized/model.rb +103 -0
- data/lib/localized/view_property.rb +337 -0
- data/spec/fixtures/card.rb +12 -0
- data/spec/fixtures/card/equip.rb +13 -0
- data/spec/fixtures/card/magic.rb +13 -0
- data/spec/fixtures/card/member.rb +13 -0
- data/spec/fixtures/card/unit.rb +13 -0
- data/spec/fixtures/deck.rb +2 -0
- data/spec/localized/decks.yml +39 -0
- data/spec/migrate/001_create_cards.rb +16 -0
- data/spec/migrate/002_create_decks.rb +5 -0
- data/spec/models/active_record_view_helper_spec.rb +393 -0
- data/spec/models/render_spec.rb +220 -0
- data/spec/schema.rb +30 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +27 -0
- data/tasks/active_record_view_tasks.rake +37 -0
- data/test/active_record_view_test.rb +8 -0
- data/uninstall.rb +1 -0
- metadata +93 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module ActiveRecordView
|
|
2
|
+
module RenderArv
|
|
3
|
+
def render(*args, &block)
|
|
4
|
+
options = args.first
|
|
5
|
+
if options.is_a?(Hash) and options[:arv]
|
|
6
|
+
arv = options.delete(:arv)
|
|
7
|
+
render_arv(arv, options)
|
|
8
|
+
else
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def render_arv(arv, options = {})
|
|
14
|
+
path, arv_name = partial_pieces(arv.to_s)
|
|
15
|
+
root = Pathname(RAILS_ROOT).cleanpath.to_s + "/"
|
|
16
|
+
file = "app/views/%s/%s.arv" % [path, arv_name]
|
|
17
|
+
rhtml = arv_erb_code(File.read(root + file), arv_name, options)
|
|
18
|
+
ActiveRecord::Base.logger.debug "Rendering %s" % file.inspect
|
|
19
|
+
render :inline=>rhtml
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
def arv_erb_code(buffer, arv_name, options)
|
|
24
|
+
html = ''
|
|
25
|
+
array = buffer.scan(/^([^#]\S+?)\s*=(.*?)$/m)
|
|
26
|
+
names = array.map(&:first)
|
|
27
|
+
leads = array.map{|a| a.last.to_s.strip}
|
|
28
|
+
|
|
29
|
+
names.each_with_index do |name, i|
|
|
30
|
+
next if (lead = leads[i]).blank? and (i > 0)
|
|
31
|
+
colspan = 1 + (leads[i+1..-1].map(&:blank?)+[false]).index(false)
|
|
32
|
+
html << "<th class='%s' colspan=%d>%s</th>" % [name, colspan, lead]
|
|
33
|
+
end
|
|
34
|
+
options[:class] = "arv-list #{arv_name} #{options[:class]}".strip
|
|
35
|
+
content_tag(:table, <<-ERB, options)
|
|
36
|
+
<thead><tr>#{html}</tr></thead>
|
|
37
|
+
<%= collection_tbody_for(@#{arv_name}, %w( #{names.join(' ')} )) %>
|
|
38
|
+
ERB
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# derived from Rails1.2 for Rails2.1
|
|
42
|
+
def partial_pieces(partial_path)
|
|
43
|
+
if partial_path.include?('/')
|
|
44
|
+
return File.dirname(partial_path), File.basename(partial_path)
|
|
45
|
+
else
|
|
46
|
+
return controller.class.controller_path, partial_path
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module ActiveRecordView::WriteException
|
|
2
|
+
def write_exception_logger
|
|
3
|
+
ActionController::Base.logger
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def write_exception(error, size = 5)
|
|
7
|
+
user_backtrace = error.application_backtrace.reject{|i| i =~ %r{^\#\{RAILS_ROOT\}/vendor/}}
|
|
8
|
+
trace = user_backtrace[0,size - 1].join("\n")
|
|
9
|
+
write_exception_logger.error "%s: %s (%s)" % [error.class, error.message, trace]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
class Localized::Model
|
|
2
|
+
attr_reader :yaml_path, :active_record
|
|
3
|
+
delegate :logger, :to=>"ActiveRecord::Base"
|
|
4
|
+
cattr_accessor :yaml_path
|
|
5
|
+
if defined?(RAILS_ROOT)
|
|
6
|
+
self.yaml_path = File.join(RAILS_ROOT, "db/localized")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class ConfigurationError < ActionView::ActionViewError; end
|
|
10
|
+
class << self
|
|
11
|
+
def [](model_name)
|
|
12
|
+
klass = active_record_class_for(model_name)
|
|
13
|
+
@localized_models ||= {}
|
|
14
|
+
@localized_models[klass.table_name] ||= new(klass)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def active_record_class_for(klass)
|
|
18
|
+
case klass
|
|
19
|
+
when Class
|
|
20
|
+
# nop
|
|
21
|
+
when ActiveRecord::Base
|
|
22
|
+
klass = klass.class
|
|
23
|
+
else
|
|
24
|
+
klass = klass.to_s.classify.constantize
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
klass.ancestors.include?(ActiveRecord::Base) or
|
|
28
|
+
raise ConfigurationError, "#{name}[] expects ActiveRecord class, but got #{klass.name}"
|
|
29
|
+
|
|
30
|
+
return klass
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def human_value(record, column_name)
|
|
34
|
+
self[record.class].view_property(column_name).human_value(record[column_name])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def masters(model_name, column_name)
|
|
38
|
+
self[model_name].view_property(column_name).masters
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def initialize(active_record)
|
|
43
|
+
@active_record = active_record
|
|
44
|
+
@table_name = @active_record.table_name
|
|
45
|
+
@view_properties = {}
|
|
46
|
+
@yaml = YAML::load_file(absolute_yaml_path)
|
|
47
|
+
logger.debug("Loaded localized setting from '#{absolute_yaml_path}'")
|
|
48
|
+
rescue Errno::ENOENT
|
|
49
|
+
raise ConfigurationError, "Cannot read YAML data from #{absolute_yaml_path}.\nRun 'rake arv:create:view %s'" % @active_record
|
|
50
|
+
rescue ArgumentError => err
|
|
51
|
+
logger.debug("Localize Error: YAML #{err} in #{yaml_path}")
|
|
52
|
+
@load_error = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def [] (group_name, attr_name = nil)
|
|
56
|
+
return nil if load_error?
|
|
57
|
+
localized_name = @yaml[group_name.to_s]
|
|
58
|
+
localized_name = localized_name[attr_name] if attr_name
|
|
59
|
+
return localized_name
|
|
60
|
+
rescue => err
|
|
61
|
+
logger.debug("Localize Error: for (%s,%s). %s" % [group_name, attr_name, err])
|
|
62
|
+
return nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def instance_name
|
|
66
|
+
self[:names][:instance]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def masters
|
|
70
|
+
pkey = active_record.primary_key
|
|
71
|
+
options = active_record.columns_hash[instance_name.to_s] && {:select=>"#{pkey},#{instance_name}"} || {}
|
|
72
|
+
active_record.find(:all, options.merge(:order=>pkey)).collect{|r| [r[pkey], localize_instance(r)]}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def localize_instance (record)
|
|
76
|
+
name = instance_name
|
|
77
|
+
case name
|
|
78
|
+
when NilClass ; return nil
|
|
79
|
+
when Symbol ; return record.send(name)
|
|
80
|
+
when String ; return name.gsub('%d', record.id.to_s)
|
|
81
|
+
else
|
|
82
|
+
raise TypeError, "got %s, expected Symbol or String. Check '%s'" % [name.class, yaml_path]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def load_error?
|
|
87
|
+
@load_error
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def view_property(column_name)
|
|
91
|
+
@view_properties[column_name] ||= Localized::ViewProperty.new(self, column_name, self["property_#{column_name}"])
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
def absolute_yaml_path
|
|
96
|
+
@absolute_yaml_path ||= (Pathname(self.class.yaml_path) + yaml_path).cleanpath
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def yaml_path
|
|
100
|
+
"#{@table_name}.yml"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
class Localized::ViewProperty
|
|
2
|
+
attr_reader :options, :model, :master_class, :column_name, :master_hash
|
|
3
|
+
|
|
4
|
+
class << self
|
|
5
|
+
def [](model_name, column_name)
|
|
6
|
+
model = find_model(model_name)
|
|
7
|
+
if model
|
|
8
|
+
model.view_property(column_name)
|
|
9
|
+
else
|
|
10
|
+
nil
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
def find_model(name)
|
|
16
|
+
@cached_models ||= {}
|
|
17
|
+
case (model = @cached_models[name])
|
|
18
|
+
when :missing
|
|
19
|
+
return nil
|
|
20
|
+
when Localized::Model
|
|
21
|
+
return model
|
|
22
|
+
when NilClass
|
|
23
|
+
begin
|
|
24
|
+
return @cached_models[name] = Localized::Model[name]
|
|
25
|
+
rescue Localized::Model::ConfigurationError
|
|
26
|
+
@cached_models[name] = :missing
|
|
27
|
+
return nil
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
raise "[BUG] Localized::ViewProperty is broken! (cannot find model for #{name})"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def initialize(model, column_name, hash = nil)
|
|
36
|
+
hash ||= {}
|
|
37
|
+
|
|
38
|
+
@blank = true if hash.blank?
|
|
39
|
+
@model = model
|
|
40
|
+
@column_name = column_name
|
|
41
|
+
@yaml_data = hash
|
|
42
|
+
@options = hash[:options] || {}
|
|
43
|
+
@master_array = []
|
|
44
|
+
@master_hash = {}
|
|
45
|
+
@master_class = nil
|
|
46
|
+
|
|
47
|
+
parse_master
|
|
48
|
+
@include_blank = @master_array.first.first.to_s.empty? rescue false
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def blank?
|
|
52
|
+
@blank
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
protected
|
|
56
|
+
def parse_master
|
|
57
|
+
master = @yaml_data[:masters]
|
|
58
|
+
@master_array = []
|
|
59
|
+
@master_hash = {}
|
|
60
|
+
@master_class = nil
|
|
61
|
+
|
|
62
|
+
case master
|
|
63
|
+
when NilClass
|
|
64
|
+
when String
|
|
65
|
+
model = Localized::Model[master]
|
|
66
|
+
@master_class = model.active_record
|
|
67
|
+
@master_array = model.masters
|
|
68
|
+
@master_array.each do |key, val|
|
|
69
|
+
@master_hash[key] = val
|
|
70
|
+
end
|
|
71
|
+
when Array
|
|
72
|
+
master.each do |hash|
|
|
73
|
+
key, val = hash.to_a.first
|
|
74
|
+
@master_array << [key, val]
|
|
75
|
+
@master_hash[key] = val
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
raise Localized::Model::ConfigurationError,
|
|
79
|
+
"Cannot accept '%s' as master. It should be an Array or :belongs_to or a String(ActiveRecord class name). Check %s." % [master.class, @model.yaml_path]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
public
|
|
84
|
+
def [](key)
|
|
85
|
+
@yaml_data[key]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def masters
|
|
89
|
+
@master_array
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def master(value)
|
|
93
|
+
@master_hash[value]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def reload_master
|
|
97
|
+
parse_master
|
|
98
|
+
return masters
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def has_master?
|
|
102
|
+
not masters.empty?
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def include_blank?
|
|
106
|
+
@include_blank
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def has_time_format?
|
|
110
|
+
self[:time_format]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def has_format?(postfix = nil)
|
|
114
|
+
self["format#{postfix}".intern] || self[:format]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def has_column_type?
|
|
118
|
+
self[:column_type].is_a?(Symbol)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def column_type
|
|
122
|
+
(has_column_type? && self[:column_type]) || (has_master? && :master) || nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def system_column_type
|
|
126
|
+
column = klass.columns_hash[column_name.to_s]
|
|
127
|
+
column ? column.type : nil
|
|
128
|
+
rescue
|
|
129
|
+
nil
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def klass
|
|
133
|
+
model.active_record
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# TODO: split to property model and rendering engine
|
|
138
|
+
include ActionView::Helpers::TagHelper # for content_tag
|
|
139
|
+
include ActionView::Helpers::FormHelper # for check_box
|
|
140
|
+
include ActionView::Helpers::FormTagHelper # for check_box_tag
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
######################################################################
|
|
144
|
+
### Rendering
|
|
145
|
+
|
|
146
|
+
def human_value (value, controller = nil)
|
|
147
|
+
controller &&= controller.is_a?(ActionController::Base) ? controller : controller.controller
|
|
148
|
+
|
|
149
|
+
case column_type
|
|
150
|
+
when :acts_as_bits
|
|
151
|
+
aab_names = klass.send("#{column_name.to_s.singularize}_names")
|
|
152
|
+
checkeds = Hash[*aab_names.zip(value.to_s.split(//)).flatten]
|
|
153
|
+
|
|
154
|
+
aab_masters = self.masters
|
|
155
|
+
aab_masters = klass.send("#{column_name.to_s.singularize}_names_with_labels") if aab_masters.blank?
|
|
156
|
+
|
|
157
|
+
type = :button
|
|
158
|
+
case type
|
|
159
|
+
when :button
|
|
160
|
+
lis = aab_masters.map{|(name, title)|
|
|
161
|
+
style = (checkeds[name].to_i == 1) ? "checked" : "unchecked"
|
|
162
|
+
span = content_tag(:span, title || name)
|
|
163
|
+
content_tag(:li, span, :class=>style)
|
|
164
|
+
}
|
|
165
|
+
return content_tag(:ul, lis.join(' '), :class=>"aab")
|
|
166
|
+
when :checkbox
|
|
167
|
+
options = (options||{}).merge(:disabled=>"disabled")
|
|
168
|
+
html = masters.map{|(name, title)|
|
|
169
|
+
check = check_box_tag("aab", 1, (checkeds[name].to_i==1), options)
|
|
170
|
+
label = h(title || name)
|
|
171
|
+
'<span style="white-space: nowrap;">%s %s</span>' % [check, label]
|
|
172
|
+
}.join(" ")
|
|
173
|
+
return html
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
if has_master?
|
|
178
|
+
html = master(value)
|
|
179
|
+
elsif has_time_format?
|
|
180
|
+
html = [Date, Time].include?(value.class) ? value.strftime(self[:time_format]) : ''
|
|
181
|
+
elsif controller && format = has_format?("_" + controller.action_name)
|
|
182
|
+
html = format % ERB::Util.html_escape(value)
|
|
183
|
+
elsif (column_type || system_column_type) == :text
|
|
184
|
+
html = ERB::Util.html_escape(value.strip.to_s).gsub(/\r?\n/,'<BR>')
|
|
185
|
+
else
|
|
186
|
+
html = ERB::Util.html_escape(value)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def human_edit(singular_name, view, opts = {})
|
|
192
|
+
record = opts.delete(:record) || view.instance_variable_get("@#{singular_name}")
|
|
193
|
+
options = self.options.merge(opts)
|
|
194
|
+
options[:class] = "#{column_name} #{options[:class]}".strip
|
|
195
|
+
|
|
196
|
+
if time_format = has_time_format?
|
|
197
|
+
value = record.send(column_name)
|
|
198
|
+
if edit_format = has_format?("_edit")
|
|
199
|
+
return human_edit_time_text_field_with_format(view, edit_format, value, singular_name)
|
|
200
|
+
else
|
|
201
|
+
return human_edit_time_with_format(view, time_format, value, singular_name)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
case column_type
|
|
206
|
+
when :acts_as_bits
|
|
207
|
+
aab_masters = self.masters
|
|
208
|
+
aab_masters = klass.send("#{column_name.to_s.singularize}_names_with_labels") if aab_masters.blank?
|
|
209
|
+
|
|
210
|
+
html = aab_masters.map{|(name, title)|
|
|
211
|
+
check = view.check_box(singular_name, name, options) rescue "(#{name}?)"
|
|
212
|
+
label = view.send(:h, title || name)
|
|
213
|
+
label = view.send(:content_tag, :label, label, :for=>"#{singular_name}_#{name}")
|
|
214
|
+
'<span style="white-space: nowrap;">%s %s</span>' % [check, label]
|
|
215
|
+
}.join(" ")
|
|
216
|
+
when :acts_as_tree
|
|
217
|
+
value = record.send(column_name)
|
|
218
|
+
record = master_class.find(value) rescue nil
|
|
219
|
+
html = view.acts_as_tree_field(singular_name, column_name, master_class, record)
|
|
220
|
+
when :checkbox, :check_box
|
|
221
|
+
html = view.check_box(singular_name, column_name, options)
|
|
222
|
+
when :radio, :radio_button
|
|
223
|
+
separater = " "
|
|
224
|
+
delimiter = " "
|
|
225
|
+
html = masters.map{|key,val|
|
|
226
|
+
[
|
|
227
|
+
view.radio_button(singular_name, column_name, key, options).to_s,
|
|
228
|
+
# content_tag(:label, val.to_s, :for=>"#{singular_name}_#{column_name}_#{key}")
|
|
229
|
+
val.to_s
|
|
230
|
+
].join(separater)
|
|
231
|
+
} * delimiter
|
|
232
|
+
|
|
233
|
+
# add following line to your css to avoid blocked radio button in AR error
|
|
234
|
+
# div.fieldWithErrors .radio-group {border:1px solid #FF0000;}
|
|
235
|
+
# .radio-group div.fieldWithErrors {display : inline;}
|
|
236
|
+
|
|
237
|
+
html = content_tag :div, html, :class=>"radio-group"
|
|
238
|
+
html = content_tag :div, html, :class=>"fieldWithErrors" if record.errors.on(column_name)
|
|
239
|
+
|
|
240
|
+
when :master
|
|
241
|
+
html = view.collection_select(singular_name, column_name, masters, :first, :last, options)
|
|
242
|
+
when :time
|
|
243
|
+
tag = ActionView::Helpers::InstanceTag.new(singular_name, column_name, view)
|
|
244
|
+
html = tag.to_time_select_tag(options)
|
|
245
|
+
when NilClass
|
|
246
|
+
if system_column_type
|
|
247
|
+
tag = ActionView::Helpers::InstanceTag.new(singular_name, column_name, view, view, record)
|
|
248
|
+
html = tag.to_tag(options)
|
|
249
|
+
else
|
|
250
|
+
if view.respond_to?(column_name)
|
|
251
|
+
view.send(column_name, record)
|
|
252
|
+
else
|
|
253
|
+
view.text_field_tag "#{singular_name}[#{column_name}]", record[column_name]
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
else
|
|
257
|
+
tag = ActionView::Helpers::InstanceTag.new(singular_name, column_name, view, view, record)
|
|
258
|
+
tag.instance_eval("def column_type; :%s; end" % self[:column_type])
|
|
259
|
+
html = tag.to_tag(options)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# if format = has_format?("_" + view.controller.action_name)
|
|
263
|
+
# html = format % html
|
|
264
|
+
# end
|
|
265
|
+
|
|
266
|
+
return html
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
protected
|
|
270
|
+
def human_edit_time_with_format(view, time_format, value, singular_name)
|
|
271
|
+
used = Set.new
|
|
272
|
+
opts = Proc.new { |position|
|
|
273
|
+
used << position
|
|
274
|
+
options.merge(:prefix => singular_name, :field_name=>"#{column_name}(#{position}i)")}
|
|
275
|
+
|
|
276
|
+
html = time_format.gsub(/%([YmdHMS])/) do
|
|
277
|
+
case $1
|
|
278
|
+
when 'Y'; view.select_year(value, opts.call(1))
|
|
279
|
+
when 'm'; view.select_month(value, opts.call(2))
|
|
280
|
+
when 'd'; view.select_day(value, opts.call(3))
|
|
281
|
+
when 'H'; view.select_hour(value, opts.call(4))
|
|
282
|
+
when 'M'; view.select_minute(value, opts.call(5))
|
|
283
|
+
when 'S'; view.select_second(value, opts.call(6))
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
hidden = (1...used.min).map{|i|
|
|
288
|
+
name = "%s[%s]" % opts.call(i).values_at(:prefix, :field_name)
|
|
289
|
+
view.hidden_field_tag(name, 1)}.join
|
|
290
|
+
return hidden + html
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def human_edit_time_text_field_with_format(view, time_format, value, singular_name)
|
|
294
|
+
used = Set.new
|
|
295
|
+
name = Proc.new { |position|
|
|
296
|
+
used << position
|
|
297
|
+
"%s[%s(%di)]" % [singular_name, column_name, position]}
|
|
298
|
+
time = Proc.new { |time_object, method, zero|
|
|
299
|
+
begin
|
|
300
|
+
val = time_object.__send__(method).to_i
|
|
301
|
+
val = "%02d" % val if zero
|
|
302
|
+
val
|
|
303
|
+
rescue
|
|
304
|
+
''
|
|
305
|
+
end
|
|
306
|
+
}
|
|
307
|
+
opts = proc {|*args| size, klass = args
|
|
308
|
+
hash = options.merge(:style=>"width:#{size}px;")
|
|
309
|
+
hash.merge!(:class=>"#{hash[:class]} #{klass}") if klass
|
|
310
|
+
hash
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
html = time_format.gsub(/%(0?)(\d*)([YmdHMS])/) do
|
|
314
|
+
zero = !$1.blank?
|
|
315
|
+
size = ($2.blank? ? 2 : $2).to_i*10+5
|
|
316
|
+
case $3
|
|
317
|
+
when 'Y'; view.text_field_tag(name.call(1), time.call(value,:year,zero), opts.call(size))
|
|
318
|
+
when 'm'; view.text_field_tag(name.call(2), time.call(value,:month,zero), opts.call(size))
|
|
319
|
+
when 'd'; view.text_field_tag(name.call(3), time.call(value,:day,zero), opts.call(size))
|
|
320
|
+
when 'H'; view.text_field_tag(name.call(4), time.call(value,:hour,zero), opts.call(size, "time-hour"))
|
|
321
|
+
when 'M'; view.text_field_tag(name.call(5), time.call(value,:min,zero), opts.call(size, "time-minute"))
|
|
322
|
+
when 'S'; view.text_field_tag(name.call(6), time.call(value,:sec,zero), opts.call(size))
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
hidden = (1...used.min).map{|i| view.hidden_field_tag(name.call(i), 1)}.join
|
|
327
|
+
return hidden + html
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def configuration_error(message)
|
|
331
|
+
raise Localized::Model::ConfigurationError, "%s (check 'property_%s' in %s)" %
|
|
332
|
+
[message, column_name, model.yaml_path]
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|