presenting 2.0.0 → 2.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/LICENSE +20 -20
- data/README +10 -10
- data/Rakefile +22 -22
- data/app/assets/javascripts/search.js +13 -13
- data/app/assets/stylesheets/details-color.css +7 -7
- data/app/assets/stylesheets/details.css +10 -10
- data/app/assets/stylesheets/form.css +1 -1
- data/app/assets/stylesheets/grid-color.css +71 -71
- data/app/assets/stylesheets/grid.css +64 -64
- data/app/assets/stylesheets/search-color.css +16 -16
- data/app/assets/stylesheets/search.css +45 -45
- data/app/controllers/presentation/assets_controller.rb +42 -42
- data/app/views/presentations/_details.erb +11 -11
- data/app/views/presentations/_field_search.erb +14 -14
- data/app/views/presentations/_form.erb +20 -20
- data/app/views/presentations/_grid.erb +70 -70
- data/app/views/presentations/_search.erb +7 -7
- data/lib/presentation/base.rb +31 -31
- data/lib/presentation/details.rb +21 -21
- data/lib/presentation/field_search.rb +67 -67
- data/lib/presentation/form.rb +149 -149
- data/lib/presentation/grid.rb +162 -160
- data/lib/presentation/search.rb +9 -9
- data/lib/presenting/attribute.rb +51 -51
- data/lib/presenting/configurable.rb +10 -10
- data/lib/presenting/defaults.rb +10 -10
- data/lib/presenting/field_set.rb +26 -26
- data/lib/presenting/form_helpers.rb +51 -51
- data/lib/presenting/helpers.rb +114 -114
- data/lib/presenting/sanitize.rb +19 -19
- data/lib/presenting/search.rb +185 -185
- data/lib/presenting/sorting.rb +87 -87
- data/test/attribute_test.rb +61 -61
- data/test/configurable_test.rb +20 -20
- data/test/details_test.rb +68 -68
- data/test/field_search_test.rb +102 -102
- data/test/field_set_test.rb +46 -46
- data/test/grid_test.rb +246 -239
- data/test/helpers_test.rb +72 -72
- data/test/presenting_test.rb +15 -15
- data/test/r3/Gemfile +7 -7
- data/test/r3/Gemfile.lock +86 -82
- data/test/r3/config/application.rb +12 -12
- data/test/r3/config/boot.rb +6 -6
- data/test/r3/config/database.yml +22 -22
- data/test/r3/config/environment.rb +5 -5
- data/test/r3/config/environments/test.rb +35 -35
- data/test/r3/db/test.sqlite3 +0 -0
- data/test/r3/log/test.log +336 -0
- data/test/r3/public/javascripts/presenting/grid.js +0 -0
- data/test/r3/public/javascripts/presenting/search.js +13 -13
- data/test/r3/public/stylesheets/presenting/details-color.css +7 -7
- data/test/r3/public/stylesheets/presenting/details.css +10 -10
- data/test/r3/public/stylesheets/presenting/form.css +1 -1
- data/test/r3/public/stylesheets/presenting/grid-color.css +71 -71
- data/test/r3/public/stylesheets/presenting/grid.css +64 -64
- data/test/r3/public/stylesheets/presenting/search-color.css +16 -16
- data/test/r3/public/stylesheets/presenting/search.css +45 -45
- data/test/sanitize_test.rb +15 -15
- data/test/search_conditions_test.rb +137 -137
- data/test/search_test.rb +30 -30
- data/test/sorting_test.rb +63 -63
- metadata +74 -74
data/lib/presenting/attribute.rb
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
module Presenting
|
2
|
-
# represents an attribute meant to be read from a record
|
3
|
-
# used for things like Grid and Details.
|
4
|
-
# not intended for things like Form or FieldSearch
|
5
|
-
class Attribute
|
6
|
-
include Presenting::Configurable
|
7
|
-
|
8
|
-
def name=(val)
|
9
|
-
self.value ||= val # don't lazy define :value, because we're about to typecast here
|
10
|
-
if val.is_a? Symbol
|
11
|
-
@name = val.to_s.titleize
|
12
|
-
else
|
13
|
-
@name = val.to_s
|
14
|
-
end
|
15
|
-
end
|
16
|
-
attr_reader :name
|
17
|
-
|
18
|
-
# The short programmatic name for this field. Can be used as a CSS class, sorting name, etc.
|
19
|
-
def id=(val)
|
20
|
-
@id = val.to_s
|
21
|
-
end
|
22
|
-
|
23
|
-
def id
|
24
|
-
@id ||= name.to_s.underscore.gsub(/[^a-z0-9]/i, '_').gsub(/__+/, '_').sub(/_$/, '')
|
25
|
-
end
|
26
|
-
|
27
|
-
# Where a field's value comes from. Depends heavily on the data type you provide.
|
28
|
-
# - String: fixed value (as provided)
|
29
|
-
# - Symbol: a method on the record (no arguments)
|
30
|
-
# - Proc: a custom block that accepts the record as an argument
|
31
|
-
attr_accessor :value
|
32
|
-
|
33
|
-
def value_from(obj) #:nodoc:
|
34
|
-
case value
|
35
|
-
when Symbol: obj.is_a?(Hash) ? obj[value] : obj.send(value)
|
36
|
-
when String: value
|
37
|
-
when Proc: value.call(obj)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# whether html should be sanitize. right now this actually means html escaping.
|
42
|
-
# consider: by default, do not sanitize if value is a String?
|
43
|
-
attr_writer :sanitize
|
44
|
-
def sanitize?
|
45
|
-
unless defined? @sanitize
|
46
|
-
@sanitize = Presenting::Defaults.sanitize_fields
|
47
|
-
end
|
48
|
-
@sanitize
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
1
|
+
module Presenting
|
2
|
+
# represents an attribute meant to be read from a record
|
3
|
+
# used for things like Grid and Details.
|
4
|
+
# not intended for things like Form or FieldSearch
|
5
|
+
class Attribute
|
6
|
+
include Presenting::Configurable
|
7
|
+
|
8
|
+
def name=(val)
|
9
|
+
self.value ||= val # don't lazy define :value, because we're about to typecast here
|
10
|
+
if val.is_a? Symbol
|
11
|
+
@name = val.to_s.titleize
|
12
|
+
else
|
13
|
+
@name = val.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
# The short programmatic name for this field. Can be used as a CSS class, sorting name, etc.
|
19
|
+
def id=(val)
|
20
|
+
@id = val.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def id
|
24
|
+
@id ||= name.to_s.underscore.gsub(/[^a-z0-9]/i, '_').gsub(/__+/, '_').sub(/_$/, '')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Where a field's value comes from. Depends heavily on the data type you provide.
|
28
|
+
# - String: fixed value (as provided)
|
29
|
+
# - Symbol: a method on the record (no arguments)
|
30
|
+
# - Proc: a custom block that accepts the record as an argument
|
31
|
+
attr_accessor :value
|
32
|
+
|
33
|
+
def value_from(obj) #:nodoc:
|
34
|
+
case value
|
35
|
+
when Symbol: obj.is_a?(Hash) ? obj[value] : obj.send(value)
|
36
|
+
when String: value
|
37
|
+
when Proc: value.call(obj)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# whether html should be sanitize. right now this actually means html escaping.
|
42
|
+
# consider: by default, do not sanitize if value is a String?
|
43
|
+
attr_writer :sanitize
|
44
|
+
def sanitize?
|
45
|
+
unless defined? @sanitize
|
46
|
+
@sanitize = Presenting::Defaults.sanitize_fields
|
47
|
+
end
|
48
|
+
@sanitize
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
module Presenting
|
2
|
-
module Configurable
|
3
|
-
def initialize(options = {}, &block)
|
4
|
-
options.each do |k, v|
|
5
|
-
self.send("#{k}=", v)
|
6
|
-
end
|
7
|
-
yield self if block_given?
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
1
|
+
module Presenting
|
2
|
+
module Configurable
|
3
|
+
def initialize(options = {}, &block)
|
4
|
+
options.each do |k, v|
|
5
|
+
self.send("#{k}=", v)
|
6
|
+
end
|
7
|
+
yield self if block_given?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/lib/presenting/defaults.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
module Presenting::Defaults
|
2
|
-
# Whether the columns in the Grid should be sortable by default
|
3
|
-
mattr_accessor :grid_is_sortable
|
4
|
-
self.grid_is_sortable = true
|
5
|
-
|
6
|
-
# Whether fields should be sanitized by default
|
7
|
-
mattr_accessor :sanitize_fields
|
8
|
-
self.sanitize_fields = true
|
9
|
-
end
|
10
|
-
|
1
|
+
module Presenting::Defaults
|
2
|
+
# Whether the columns in the Grid should be sortable by default
|
3
|
+
mattr_accessor :grid_is_sortable
|
4
|
+
self.grid_is_sortable = true
|
5
|
+
|
6
|
+
# Whether fields should be sanitized by default
|
7
|
+
mattr_accessor :sanitize_fields
|
8
|
+
self.sanitize_fields = true
|
9
|
+
end
|
10
|
+
|
data/lib/presenting/field_set.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
class Presenting::FieldSet < Array
|
2
|
-
def initialize(field_class, primary, secondary)
|
3
|
-
@klass = field_class
|
4
|
-
@primary_attribute = primary
|
5
|
-
@secondary_attribute = secondary
|
6
|
-
end
|
7
|
-
|
8
|
-
def <<(field)
|
9
|
-
if field.is_a? Hash
|
10
|
-
k, v = *field.to_a.first
|
11
|
-
opts = v.is_a?(Hash) ? v : {@secondary_attribute => v}
|
12
|
-
opts[@primary_attribute] = k
|
13
|
-
else
|
14
|
-
opts = {@primary_attribute => field}
|
15
|
-
end
|
16
|
-
super @klass.new(opts)
|
17
|
-
end
|
18
|
-
|
19
|
-
def [](key)
|
20
|
-
detect{|i| i.send(@primary_attribute) == key}
|
21
|
-
end
|
22
|
-
|
23
|
-
def []=(key, val)
|
24
|
-
self << {key => val}
|
25
|
-
end
|
26
|
-
end
|
1
|
+
class Presenting::FieldSet < Array
|
2
|
+
def initialize(field_class, primary, secondary)
|
3
|
+
@klass = field_class
|
4
|
+
@primary_attribute = primary
|
5
|
+
@secondary_attribute = secondary
|
6
|
+
end
|
7
|
+
|
8
|
+
def <<(field)
|
9
|
+
if field.is_a? Hash
|
10
|
+
k, v = *field.to_a.first
|
11
|
+
opts = v.is_a?(Hash) ? v : {@secondary_attribute => v}
|
12
|
+
opts[@primary_attribute] = k
|
13
|
+
else
|
14
|
+
opts = {@primary_attribute => field}
|
15
|
+
end
|
16
|
+
super @klass.new(opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](key)
|
20
|
+
detect{|i| i.send(@primary_attribute) == key}
|
21
|
+
end
|
22
|
+
|
23
|
+
def []=(key, val)
|
24
|
+
self << {key => val}
|
25
|
+
end
|
26
|
+
end
|
@@ -1,51 +1,51 @@
|
|
1
|
-
module Presenting::FormHelpers
|
2
|
-
def present(field)
|
3
|
-
send("present_#{field.type}_input", field)
|
4
|
-
end
|
5
|
-
|
6
|
-
def present_readonly_input(field)
|
7
|
-
text_field field.name, :disabled => true, :value => field.value_from(object)
|
8
|
-
end
|
9
|
-
|
10
|
-
def present_string_input(field)
|
11
|
-
text_field field.name, :value => field.value_from(object)
|
12
|
-
end
|
13
|
-
|
14
|
-
def present_hidden_input(field)
|
15
|
-
hidden_field field.name, :value => field.value_from(object)
|
16
|
-
end
|
17
|
-
|
18
|
-
def present_text_input(field)
|
19
|
-
text_area field.name, :value => field.value_from(object)
|
20
|
-
end
|
21
|
-
|
22
|
-
def present_password_input(field)
|
23
|
-
password_field field.name
|
24
|
-
end
|
25
|
-
|
26
|
-
def present_boolean_input(field)
|
27
|
-
check_box field.name
|
28
|
-
end
|
29
|
-
|
30
|
-
def present_dropdown_input(field)
|
31
|
-
view.select_tag "#{object_name}[#{field.name}]", view.options_for_select(field.type_options, object.send(field.name))
|
32
|
-
end
|
33
|
-
alias_method :present_select_input, :present_dropdown_input
|
34
|
-
|
35
|
-
def present_multi_select_input(field)
|
36
|
-
view.select_tag "#{object_name}[#{field.name}][]", view.options_for_select(field.type_options, object.send(field.name)), :multiple => true
|
37
|
-
end
|
38
|
-
|
39
|
-
def present_radios_input(field)
|
40
|
-
field.type_options.collect do |(display, value)|
|
41
|
-
label("#{field.name}_#{value}", display) +
|
42
|
-
radio_button(field.name, value)
|
43
|
-
end.join.html_safe
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def view
|
49
|
-
@template
|
50
|
-
end
|
51
|
-
end
|
1
|
+
module Presenting::FormHelpers
|
2
|
+
def present(field)
|
3
|
+
send("present_#{field.type}_input", field)
|
4
|
+
end
|
5
|
+
|
6
|
+
def present_readonly_input(field)
|
7
|
+
text_field field.name, :disabled => true, :value => field.value_from(object)
|
8
|
+
end
|
9
|
+
|
10
|
+
def present_string_input(field)
|
11
|
+
text_field field.name, :value => field.value_from(object)
|
12
|
+
end
|
13
|
+
|
14
|
+
def present_hidden_input(field)
|
15
|
+
hidden_field field.name, :value => field.value_from(object)
|
16
|
+
end
|
17
|
+
|
18
|
+
def present_text_input(field)
|
19
|
+
text_area field.name, :value => field.value_from(object)
|
20
|
+
end
|
21
|
+
|
22
|
+
def present_password_input(field)
|
23
|
+
password_field field.name
|
24
|
+
end
|
25
|
+
|
26
|
+
def present_boolean_input(field)
|
27
|
+
check_box field.name
|
28
|
+
end
|
29
|
+
|
30
|
+
def present_dropdown_input(field)
|
31
|
+
view.select_tag "#{object_name}[#{field.name}]", view.options_for_select(field.type_options, object.send(field.name))
|
32
|
+
end
|
33
|
+
alias_method :present_select_input, :present_dropdown_input
|
34
|
+
|
35
|
+
def present_multi_select_input(field)
|
36
|
+
view.select_tag "#{object_name}[#{field.name}][]", view.options_for_select(field.type_options, object.send(field.name)), :multiple => true
|
37
|
+
end
|
38
|
+
|
39
|
+
def present_radios_input(field)
|
40
|
+
field.type_options.collect do |(display, value)|
|
41
|
+
label("#{field.name}_#{value}", display) +
|
42
|
+
radio_button(field.name, value)
|
43
|
+
end.join.html_safe
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def view
|
49
|
+
@template
|
50
|
+
end
|
51
|
+
end
|
data/lib/presenting/helpers.rb
CHANGED
@@ -1,114 +1,114 @@
|
|
1
|
-
module Presenting
|
2
|
-
module Helpers
|
3
|
-
def presentation_stylesheets(*args)
|
4
|
-
warn "[DEPRECATION] presentation_stylesheets is deprecated. Please use the stylesheets" <<
|
5
|
-
"that are copied to public/stylesheets/presenting/* on boot."
|
6
|
-
stylesheet_link_tag presentation_stylesheet_path(args.sort.join(','), :format => 'css')
|
7
|
-
end
|
8
|
-
|
9
|
-
def presentation_javascript(*args)
|
10
|
-
warn "[DEPRECATION] presentation_javascript is deprecated. Please use the javascripts" <<
|
11
|
-
"that are copied to public/javascripts/presenting/* on boot."
|
12
|
-
javascript_include_tag presentation_javascript_path(args.sort.join(','), :format => 'js')
|
13
|
-
end
|
14
|
-
|
15
|
-
def present(*args, &block)
|
16
|
-
options = args.length > 1 ? args.extract_options! : {}
|
17
|
-
|
18
|
-
if args.first.is_a? Symbol
|
19
|
-
object, presentation = nil, args.first
|
20
|
-
else
|
21
|
-
object, presentation = args.first, args.second
|
22
|
-
end
|
23
|
-
|
24
|
-
if presentation
|
25
|
-
klass = "Presentation::#{presentation.to_s.camelcase}".constantize rescue nil
|
26
|
-
if klass
|
27
|
-
instance = klass.new(options, &block)
|
28
|
-
instance.presentable = object
|
29
|
-
instance.controller = controller
|
30
|
-
instance.render
|
31
|
-
elsif respond_to?(method_name = "present_#{presentation}")
|
32
|
-
send(method_name, object, options)
|
33
|
-
else
|
34
|
-
raise ArgumentError, "unknown presentation `#{presentation}'"
|
35
|
-
end
|
36
|
-
elsif object.respond_to?(:loaded?) # AssociationProxy
|
37
|
-
present_association(object, options)
|
38
|
-
else
|
39
|
-
present_by_class(object, options)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# presents a text search widget for the given field (a Presentation::FieldSearch::Field, probably)
|
44
|
-
def present_text_search(field, options = {})
|
45
|
-
current_value = (params[:search][field.param][:value] rescue nil)
|
46
|
-
text_field_tag options[:name], h(current_value)
|
47
|
-
end
|
48
|
-
|
49
|
-
# presents a checkbox search widget for the given field (a Presentation::FieldSearch::Field, probably)
|
50
|
-
def present_checkbox_search(field, options = {})
|
51
|
-
current_value = (params[:search][field.param][:value] rescue nil)
|
52
|
-
check_box_tag options[:name], '1', current_value.to_s == '1'
|
53
|
-
end
|
54
|
-
|
55
|
-
# presents a dropdown/select search widget for the given field (a Presentation::FieldSearch::Field, probably)
|
56
|
-
def present_dropdown_search(field, options = {})
|
57
|
-
current_value = (params[:search][field.param][:value] rescue nil)
|
58
|
-
select_tag options[:name], options_for_select(normalize_dropdown_options_to_strings(field.options), current_value)
|
59
|
-
end
|
60
|
-
|
61
|
-
protected
|
62
|
-
|
63
|
-
# We want to normalize the value elements of the dropdown options to strings so that
|
64
|
-
# they will match against params[:search].
|
65
|
-
#
|
66
|
-
# Need to handle the three different dropdown options formats:
|
67
|
-
# * array of strings
|
68
|
-
# * array of arrays
|
69
|
-
# * hash
|
70
|
-
def normalize_dropdown_options_to_strings(options)
|
71
|
-
options.to_a.map do |element|
|
72
|
-
if element.is_a? String
|
73
|
-
[element, element]
|
74
|
-
else
|
75
|
-
[element.first, element.last.to_s]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# TODO: special handling for associations (displaying activerecords)
|
81
|
-
def present_association(object, options = {})
|
82
|
-
present_by_class(object, options)
|
83
|
-
end
|
84
|
-
|
85
|
-
def present_by_class(object, options = {})
|
86
|
-
case object
|
87
|
-
when Array
|
88
|
-
content_tag "ol" do
|
89
|
-
object.collect do |i|
|
90
|
-
content_tag "li", present(i, options)
|
91
|
-
end.join.html_safe
|
92
|
-
end
|
93
|
-
|
94
|
-
when Hash
|
95
|
-
# sort by keys
|
96
|
-
content_tag "dl" do
|
97
|
-
object.keys.sort.collect do |k|
|
98
|
-
content_tag("dt", k) +
|
99
|
-
content_tag("dd", present(object[k], options))
|
100
|
-
end.join.html_safe
|
101
|
-
end
|
102
|
-
|
103
|
-
when TrueClass, FalseClass
|
104
|
-
object ? "True" : "False"
|
105
|
-
|
106
|
-
when Date, Time, DateTime
|
107
|
-
l(object, :format => :default)
|
108
|
-
|
109
|
-
else
|
110
|
-
options[:raw] ? object.to_s.html_safe : object.to_s
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
1
|
+
module Presenting
|
2
|
+
module Helpers
|
3
|
+
def presentation_stylesheets(*args)
|
4
|
+
warn "[DEPRECATION] presentation_stylesheets is deprecated. Please use the stylesheets" <<
|
5
|
+
"that are copied to public/stylesheets/presenting/* on boot."
|
6
|
+
stylesheet_link_tag presentation_stylesheet_path(args.sort.join(','), :format => 'css')
|
7
|
+
end
|
8
|
+
|
9
|
+
def presentation_javascript(*args)
|
10
|
+
warn "[DEPRECATION] presentation_javascript is deprecated. Please use the javascripts" <<
|
11
|
+
"that are copied to public/javascripts/presenting/* on boot."
|
12
|
+
javascript_include_tag presentation_javascript_path(args.sort.join(','), :format => 'js')
|
13
|
+
end
|
14
|
+
|
15
|
+
def present(*args, &block)
|
16
|
+
options = args.length > 1 ? args.extract_options! : {}
|
17
|
+
|
18
|
+
if args.first.is_a? Symbol
|
19
|
+
object, presentation = nil, args.first
|
20
|
+
else
|
21
|
+
object, presentation = args.first, args.second
|
22
|
+
end
|
23
|
+
|
24
|
+
if presentation
|
25
|
+
klass = "Presentation::#{presentation.to_s.camelcase}".constantize rescue nil
|
26
|
+
if klass
|
27
|
+
instance = klass.new(options, &block)
|
28
|
+
instance.presentable = object
|
29
|
+
instance.controller = controller
|
30
|
+
instance.render
|
31
|
+
elsif respond_to?(method_name = "present_#{presentation}")
|
32
|
+
send(method_name, object, options)
|
33
|
+
else
|
34
|
+
raise ArgumentError, "unknown presentation `#{presentation}'"
|
35
|
+
end
|
36
|
+
elsif object.respond_to?(:loaded?) # AssociationProxy
|
37
|
+
present_association(object, options)
|
38
|
+
else
|
39
|
+
present_by_class(object, options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# presents a text search widget for the given field (a Presentation::FieldSearch::Field, probably)
|
44
|
+
def present_text_search(field, options = {})
|
45
|
+
current_value = (params[:search][field.param][:value] rescue nil)
|
46
|
+
text_field_tag options[:name], h(current_value)
|
47
|
+
end
|
48
|
+
|
49
|
+
# presents a checkbox search widget for the given field (a Presentation::FieldSearch::Field, probably)
|
50
|
+
def present_checkbox_search(field, options = {})
|
51
|
+
current_value = (params[:search][field.param][:value] rescue nil)
|
52
|
+
check_box_tag options[:name], '1', current_value.to_s == '1'
|
53
|
+
end
|
54
|
+
|
55
|
+
# presents a dropdown/select search widget for the given field (a Presentation::FieldSearch::Field, probably)
|
56
|
+
def present_dropdown_search(field, options = {})
|
57
|
+
current_value = (params[:search][field.param][:value] rescue nil)
|
58
|
+
select_tag options[:name], options_for_select(normalize_dropdown_options_to_strings(field.options), current_value)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
# We want to normalize the value elements of the dropdown options to strings so that
|
64
|
+
# they will match against params[:search].
|
65
|
+
#
|
66
|
+
# Need to handle the three different dropdown options formats:
|
67
|
+
# * array of strings
|
68
|
+
# * array of arrays
|
69
|
+
# * hash
|
70
|
+
def normalize_dropdown_options_to_strings(options)
|
71
|
+
options.to_a.map do |element|
|
72
|
+
if element.is_a? String
|
73
|
+
[element, element]
|
74
|
+
else
|
75
|
+
[element.first, element.last.to_s]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# TODO: special handling for associations (displaying activerecords)
|
81
|
+
def present_association(object, options = {})
|
82
|
+
present_by_class(object, options)
|
83
|
+
end
|
84
|
+
|
85
|
+
def present_by_class(object, options = {})
|
86
|
+
case object
|
87
|
+
when Array
|
88
|
+
content_tag "ol" do
|
89
|
+
object.collect do |i|
|
90
|
+
content_tag "li", present(i, options)
|
91
|
+
end.join.html_safe
|
92
|
+
end
|
93
|
+
|
94
|
+
when Hash
|
95
|
+
# sort by keys
|
96
|
+
content_tag "dl" do
|
97
|
+
object.keys.sort.collect do |k|
|
98
|
+
content_tag("dt", k) +
|
99
|
+
content_tag("dd", present(object[k], options))
|
100
|
+
end.join.html_safe
|
101
|
+
end
|
102
|
+
|
103
|
+
when TrueClass, FalseClass
|
104
|
+
object ? "True" : "False"
|
105
|
+
|
106
|
+
when Date, Time, DateTime
|
107
|
+
l(object, :format => :default)
|
108
|
+
|
109
|
+
else
|
110
|
+
options[:raw] ? object.to_s.html_safe : object.to_s
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/presenting/sanitize.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
module Presenting::Sanitize
|
2
|
-
class << self
|
3
|
-
include ERB::Util
|
4
|
-
|
5
|
-
# escape but preserve Arrays and Hashes
|
6
|
-
def h(val)
|
7
|
-
case val
|
8
|
-
when Array
|
9
|
-
val.map{|i| h(i)}
|
10
|
-
|
11
|
-
when Hash
|
12
|
-
val.clone.each{|k, v| val[h(k)] = h(v)}
|
13
|
-
|
14
|
-
else
|
15
|
-
html_escape(val)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
1
|
+
module Presenting::Sanitize
|
2
|
+
class << self
|
3
|
+
include ERB::Util
|
4
|
+
|
5
|
+
# escape but preserve Arrays and Hashes
|
6
|
+
def h(val)
|
7
|
+
case val
|
8
|
+
when Array
|
9
|
+
val.map{|i| h(i)}
|
10
|
+
|
11
|
+
when Hash
|
12
|
+
val.clone.each{|k, v| val[h(k)] = h(v)}
|
13
|
+
|
14
|
+
else
|
15
|
+
html_escape(val)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|