caisson 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README.md +13 -1
  2. data/app/assets/javascripts/caisson/base.coffee +4 -0
  3. data/app/assets/javascripts/caisson/form/fields/base.coffee +115 -0
  4. data/app/assets/javascripts/caisson/form/fields/checkbox.coffee +13 -0
  5. data/app/assets/javascripts/caisson/form/fields/select.coffee +14 -0
  6. data/app/assets/javascripts/caisson/form/fields/text_field.coffee +22 -0
  7. data/app/assets/javascripts/caisson/form/fields/validator.coffee +116 -0
  8. data/app/assets/javascripts/caisson/form/form.coffee +119 -0
  9. data/app/assets/javascripts/caisson/form/form_caisson.coffee +30 -0
  10. data/app/assets/javascripts/caisson/index.js +2 -0
  11. data/app/assets/javascripts/caisson/module.coffee +8 -0
  12. data/app/assets/javascripts/caisson/orbit-slider.coffee +2 -1
  13. data/app/assets/stylesheets/caisson/base.css.scss +7 -0
  14. data/app/assets/stylesheets/caisson/index.css +3 -0
  15. data/lib/caisson/helpers/form/base.rb +195 -0
  16. data/lib/caisson/helpers/form/builder/base.rb +72 -0
  17. data/lib/caisson/helpers/form/builder/field/base.rb +168 -0
  18. data/lib/caisson/helpers/form/builder/field/checkbox.rb +15 -0
  19. data/lib/caisson/helpers/form/builder/field/money.rb +13 -0
  20. data/lib/caisson/helpers/form/builder/field/password.rb +13 -0
  21. data/lib/caisson/helpers/form/builder/field/percent.rb +13 -0
  22. data/lib/caisson/helpers/form/builder/field/select.rb +41 -0
  23. data/lib/caisson/helpers/form/builder/field/text.rb +13 -0
  24. data/lib/caisson/helpers/form/builder/field/textarea.rb +13 -0
  25. data/lib/caisson/helpers/form/builder/field_builder/base.rb +81 -0
  26. data/lib/caisson/helpers/form/builder/field_builder/nature.rb +85 -0
  27. data/lib/caisson/helpers/form/builder/interpreti.rb +107 -0
  28. data/lib/caisson/helpers/form/button.rb +62 -0
  29. data/lib/caisson/helpers/form/field/base.rb +43 -0
  30. data/lib/caisson/helpers/form/field/checkbox.rb +39 -0
  31. data/lib/caisson/helpers/form/field/money.rb +29 -0
  32. data/lib/caisson/helpers/form/field/password.rb +14 -0
  33. data/lib/caisson/helpers/form/field/percent.rb +23 -0
  34. data/lib/caisson/helpers/form/field/select.rb +34 -0
  35. data/lib/caisson/helpers/form/field/text.rb +17 -0
  36. data/lib/caisson/helpers/form/field/textarea.rb +16 -0
  37. data/lib/caisson/helpers/form.rb +30 -0
  38. data/lib/caisson/helpers/grid.rb +32 -0
  39. data/lib/caisson/helpers/orbit_slider.rb +16 -21
  40. data/lib/caisson/helpers.rb +26 -0
  41. data/lib/caisson/implants/mongoid.rb +67 -0
  42. data/lib/caisson/implants/railtie.rb +4 -0
  43. metadata +41 -6
@@ -0,0 +1,195 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form
5
+ class Base
6
+ #*************************************************************************************
7
+ # CONSTRUCTOR
8
+ #*************************************************************************************
9
+ def initialize(core)
10
+ @core = core
11
+ end
12
+
13
+
14
+ #*************************************************************************************
15
+ # PUBLIC INSTANCE METHODS
16
+ #*************************************************************************************
17
+ def button(text, options={})
18
+ Caisson::Helpers::Form::Button.new(@core).build(text, options)
19
+ end
20
+
21
+ def button_to(text, options={}, html_options={})
22
+ Caisson::Helpers::Form::Button.new(@core).build_button_to(text, options, html_options)
23
+ end
24
+
25
+ def buttons(&block)
26
+ content = '<div class="buttons row"><div class="large-12 columns">'
27
+ content << @core.capture(self, &block)
28
+ content << '</div></div>'
29
+
30
+ return content.html_safe
31
+ end
32
+
33
+ def label(text, options={})
34
+ options.reverse_merge!(content: '', placeholder: nil, separator: ' : ')
35
+
36
+ label_for = options[:content].scan(/<[input|textarea|select|span|div].+id="(.+?)"./).flatten.first
37
+
38
+ attributes = {}
39
+ attributes[:for] = label_for if label_for
40
+ attributes[:class] = 'placeholder' if options[:placeholder]
41
+
42
+ text = '&nbsp;'.html_safe if text.empty?
43
+ text += options[:separator].to_s if not options[:placeholder]
44
+
45
+ return content_tag(:label, text, attributes)
46
+ end
47
+
48
+ def line(label_str, content, options={})
49
+ options.reverse_merge!(class: nil, id: nil, label_separator: ' : ', placeholder: false)
50
+
51
+ css_class = ['row', 'form-line', options[:class]].compact.join(' ')
52
+
53
+ line_content = '<div class="' + css_class + '"><div class="large-12 columns field">'
54
+ line_content << label(label_str, content: content, separator: options[:label_separator], placeholder: options[:placeholder]) if not label_str.nil?
55
+ line_content << content
56
+ line_content << '</div></div>'
57
+
58
+ return line_content.html_safe
59
+ end
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+ def checkbox(name, selected=false, options={})
75
+ new_field('checkbox', name, selected, options)
76
+ end
77
+
78
+
79
+
80
+
81
+
82
+ def line_checkbox(label_str, field_name, selected=false, options={})
83
+ options.reverse_merge!(label_separator: nil, wrap_field: false)
84
+
85
+ options[:class] = [options[:class], 'line-checkbox'].compact.join(' ')
86
+
87
+ return line(label_str, checkbox(field_name, selected), options)
88
+ end
89
+
90
+ def line_password(label_str, field_name, value='', options={})
91
+ field_options = get_field_options(label_str, options)
92
+
93
+ line(label_str, password(field_name, value, field_options), options)
94
+ end
95
+
96
+ def line_select(label_str, field_name, choices, selection, options={})
97
+ line(label_str, select(field_name, choices, selection), options)
98
+ end
99
+
100
+ def line_static(label_str, value, options={})
101
+ options.reverse_merge!(wrap_field: false)
102
+
103
+ options[:class] = [options[:class], 'line-static'].compact.join(' ')
104
+
105
+ field_options = {}
106
+ field_options[:date_format] = options.delete(:date_format) if options[:date_format]
107
+
108
+ line(label_str, static(value, field_options), options)
109
+ end
110
+
111
+ def line_switch(label_str, field_name, choices, selection, options={})
112
+ line(label_str, switch(field_name, choices, selection), options)
113
+ end
114
+
115
+ def line_text(label_str, field_name, value='', options={})
116
+ options.reverse_merge!(wrap_field: false)
117
+
118
+ field_options = get_field_options(label_str, options)
119
+
120
+ line(label_str, text(field_name, value, field_options), options)
121
+ end
122
+
123
+ def line_time(label_str, field_name, value='', options={})
124
+ line(label_str, time(field_name, value), options)
125
+ end
126
+
127
+ def password(name, value='', options={})
128
+ new_field('password', name, value, options)
129
+ end
130
+
131
+ def select(name, choices, selection, options={})
132
+ options.reverse_merge!(submit: false, translate: false)
133
+
134
+ new_field('select', name, choices, selection, options)
135
+ end
136
+
137
+ def static(value, options={})
138
+ new_field('static', value, options)
139
+ end
140
+
141
+ def switch(name, choices, selection, options={})
142
+ options.reverse_merge!(submit: false, translate: false)
143
+
144
+ new_field('switch', name, choices, selection, options)
145
+ end
146
+
147
+ def text(name, value='', options={})
148
+ new_field('text', name, value, options)
149
+ end
150
+
151
+ def time(name, value, options={})
152
+ new_field('time_field', name, value, options)
153
+ end
154
+
155
+ private
156
+
157
+ #*************************************************************************************
158
+ # PRIVATE INSTANCE METHODS
159
+ #*************************************************************************************
160
+ def get_field_options(label_str, line_options)
161
+ field_options = {}
162
+
163
+ if line_options[:placeholder]
164
+ field_options[:placeholder] = (line_options[:placeholder] == true) ? label_str : line_options[:placeholder]
165
+ end
166
+
167
+ field_options[:placeholder] = line_options[:placeholder_text] if line_options[:placeholder_text]
168
+ field_options[:validates] = line_options.delete(:validates) if line_options[:validates]
169
+ field_options[:maxlength] = line_options.delete(:maxlength) if line_options[:maxlength]
170
+ field_options[:field_size] = line_options.delete(:field_size) if line_options[:field_size]
171
+
172
+ return field_options
173
+ end
174
+
175
+ def line_options(options)
176
+ options[:class] = ['line', options[:class]].compact.flatten.join(' ')
177
+ options.delete(:label_separator)
178
+ options.delete(:wrap_field)
179
+ options.delete(:placeholder)
180
+ options.delete(:placeholder_text)
181
+
182
+ return options
183
+ end
184
+
185
+ def new_field(nature, *args)
186
+ wrap_field "Caisson::Helpers::Form::Field::#{nature.camelize}".constantize.new(@core).build(*args)
187
+ end
188
+
189
+ def wrap_field(content)
190
+ content_tag(:div, content, class: 'field')
191
+ end
192
+
193
+ def method_missing(*args, &block) return @core.send(*args, &block) end
194
+ end
195
+ end
@@ -0,0 +1,72 @@
1
+ module Caisson::Helpers::Form::Builder
2
+ class Base
3
+ attr_reader :interpreti, :record
4
+
5
+ #*************************************************************************************
6
+ # CONSTRUCTOR
7
+ #*************************************************************************************
8
+ def initialize(core, record)
9
+ @core = core
10
+ @record = record
11
+ @interpreti = Caisson::Helpers::Form::Builder::Interpreti.new(@record)
12
+ end
13
+
14
+
15
+ #*************************************************************************************
16
+ # PUBLIC INSTANCE METHODS
17
+ #*************************************************************************************
18
+ def line(field_name, options={})
19
+ options.reverse_merge!(choices: nil, hint: true, id: 'undefined', label: 'undefined', nature: nil, placeholder: false, value: 'undefined')
20
+
21
+ field = field_builder(field_name, field_options(options))
22
+
23
+ label_str = line_label(field, force: options[:label])
24
+
25
+ return caisson.line(label_str, field.build, line_options(field, options))
26
+ end
27
+
28
+ def line_label(field, options={})
29
+ options.reverse_merge!(force: 'undefined')
30
+
31
+ return case
32
+ when options[:force] != 'undefined' then options[:force]
33
+ when field.checkbox? then nil
34
+ when field.hidden? then nil
35
+ else field.label
36
+ end
37
+ end
38
+
39
+
40
+ private
41
+
42
+ #*************************************************************************************
43
+ # PRIVATE INSTANCE METHODS
44
+ #*************************************************************************************
45
+ def field_builder(name, options={})
46
+ Caisson::Helpers::Form::Builder::FieldBuilder::Base.new(self, name, options)
47
+ end
48
+
49
+ def field_options(full_options)
50
+ options = {}
51
+ options.reverse_merge! full_options
52
+ options.delete :class
53
+
54
+ return options
55
+ end
56
+
57
+ def line_options(field, full_options)
58
+ options = { class: ["line-#{field.nature}", full_options[:class]].join(' ') }
59
+ options[:class] << ' errors' if field.errors?
60
+ options[:id] = 'line-' + full_options[:id] if not [nil, 'undefined'].include?(full_options[:id])
61
+ options[:wrap_field] = false
62
+ options[:placeholder] = full_options[:placeholder]
63
+ options[:hint] = full_options[:hint]
64
+
65
+ options[:label_separator] = '' if field.nature == 'checkbox'
66
+
67
+ return options
68
+ end
69
+
70
+ def method_missing(*args, &block) return @core.send(*args, &block) end
71
+ end
72
+ end
@@ -0,0 +1,168 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Base
6
+ attr_reader :name
7
+
8
+ #*************************************************************************************
9
+ # CONSTRUCTOR
10
+ #*************************************************************************************
11
+ def initialize(core, record, name, options={})
12
+ @core = core
13
+ @record = record
14
+ @name = name
15
+
16
+ @options = OptionParser.new(@record, @name, options).parse
17
+ end
18
+
19
+ #*************************************************************************************
20
+ # PUBLIC INSTANCE METHODS
21
+ #*************************************************************************************
22
+
23
+ private
24
+
25
+ #*************************************************************************************
26
+ # PRIVATE INSTANCE METHODS
27
+ #*************************************************************************************
28
+ def field_id
29
+ "#{model_name}_#{@name}"
30
+ end
31
+
32
+ def field_name
33
+ "#{model_name}[#{@name}]"
34
+ end
35
+
36
+ def label
37
+ interpreti.field_label(@name)
38
+ end
39
+
40
+ def interpreti
41
+ @core.interpreti
42
+ end
43
+
44
+ def model_name
45
+ @record.class.to_s.underscore.downcase
46
+ end
47
+
48
+ def value(readable=false)
49
+ if @name.to_s.include?('[')
50
+ parsed_name = @name.gsub(']', '[').split('[')
51
+
52
+ return @record.read_attribute(parsed_name[0])[parsed_name[1]]
53
+ else
54
+ content = ''
55
+ content = interpreti.field_option(@name) if readable
56
+
57
+ if content.blank?
58
+ content = @record.respond_to?(@name) ? @record.send(@name) : @record.read_attribute(@name)
59
+ end
60
+
61
+ return content
62
+ end
63
+ end
64
+
65
+ def value_readable
66
+ value true
67
+ end
68
+
69
+ def method_missing(*args, &block)
70
+ if [:check_box, :content_tag].include?(args.first)
71
+ return @core.send(*args, &block)
72
+ else
73
+ raise NoMethodError.new("undefined local variable or method '#{args.first}' for #{self.class}")
74
+ end
75
+ end
76
+
77
+ class OptionParser
78
+ def initialize(record, field_name, options)
79
+ @field_name = field_name
80
+ @options = options
81
+ @record = record
82
+ end
83
+
84
+ def parse
85
+ parse_id
86
+ parse_class
87
+ parse_placeholder
88
+ parse_validations
89
+
90
+ delete_junk
91
+
92
+ return @options
93
+ end
94
+
95
+ private
96
+
97
+ def delete_junk
98
+ [:field_size, :nature].each { |n| @options.delete(n) }
99
+
100
+ @options.delete(:label) if @options[:label] == 'undefined'
101
+ @options.delete(:value) if @options[:value] == 'undefined'
102
+ @options.delete(:choices) if not @options[:choices]
103
+ end
104
+
105
+ def parse_class
106
+ @options[:class] = [@options[:class], @options[:field_size]].compact.join(" ") if @options[:field_size]
107
+ end
108
+
109
+ def parse_id
110
+ if @options[:id] == 'undefined'
111
+ model_name = @record.class.to_s.underscore.downcase
112
+
113
+ @options[:id] = "#{model_name}_#{@field_name}"
114
+ end
115
+ end
116
+
117
+ def parse_length_validator(opts)
118
+ case
119
+ when (opts[:minimum] and opts[:maximum]) then "within-#{opts[:minimum]}-#{opts[:maximum]}"
120
+ when opts[:minimum] then "min-#{opts[:minimum]}"
121
+ when opts[:maximum] then "max-#{opts[:maximum]}"
122
+ when opts[:is] then "length-#{opts[:is]}"
123
+ end
124
+ end
125
+
126
+ def parse_placeholder
127
+ if @options[:placeholder] == true
128
+ @options[:placeholder] = interpreti.field_label @field_name
129
+ elsif not @options[:placeholder]
130
+ @options.delete(:placeholder)
131
+ end
132
+ end
133
+
134
+ def parse_validations
135
+ validators = @record.class.validators_on(@field_name).map { |v| parse_validator v }
136
+ validators << 'email' if @field_name.to_s.include? 'email'
137
+ validators << set_other_validations
138
+
139
+ data = [validators, @options.delete(:validates)].flatten.compact
140
+
141
+ @options[:validates] = data.join(" ") if not data.empty?
142
+ end
143
+
144
+ def parse_validator(validator)
145
+ return nil if validator.options[:if] and not @record.send(validator.options[:if])
146
+ return nil if validator.options[:unless] and @record.send(validator.options[:unless])
147
+
148
+ case validator.class.to_s
149
+ when /ConfirmationValidator$/ then nil # TODO: Implement this feature
150
+ when /FormatValidator$/ then nil
151
+ when /LengthValidator$/ then parse_length_validator validator.options
152
+ when /PresenceValidator$/ then 'blank'
153
+ when /UniquenessValidator$/ then nil
154
+ else nil
155
+ end
156
+ end
157
+
158
+ def set_other_validations
159
+ validators = []
160
+
161
+ validators << 'numeric' if @record.fields[@field_name.to_s] and @record.fields[@field_name.to_s].options[:type] == Integer
162
+
163
+ return validators
164
+ end
165
+ end
166
+
167
+ end
168
+ end
@@ -0,0 +1,15 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Checkbox < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ @options[:label] = label
11
+
12
+ Caisson::Helpers::Form::Field::Checkbox.new(@core).build(field_name, value, @options)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Money < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ Caisson::Helpers::Form::Field::Money.new(@core).build(field_name, value, @options)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Password < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ Caisson::Helpers::Form::Field::Password.new(@core).build(field_name, value, @options)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Percent < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ Caisson::Helpers::Form::Field::Percent.new(@core).build(field_name, value, @options)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Select < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ @options.reverse_merge!(choices: nil, include_blank: false)
11
+
12
+ choices = parse_choices @options[:choices]
13
+
14
+ @options.delete(:choices)
15
+ @options.delete(:include_blank)
16
+ @options[:translate] = false
17
+
18
+ Caisson::Helpers::Form::Field::Select.new(@core).build(field_name, choices, value, @options)
19
+ end
20
+
21
+ private
22
+
23
+ #*************************************************************************************
24
+ # PRIVATE INSTANCE METHODS
25
+ #*************************************************************************************
26
+ def parse_choices(choices)
27
+ if choices
28
+ if not choices.is_a? Array or not choices.first.is_a? Array
29
+ # choices are a list of records
30
+ choices = choices.choices_for_select
31
+ choices.insert(0, interpreti.blank_choice(name)) if @options[:include_blank]
32
+ end
33
+ else
34
+ choices = interpreti.field_choices(name, include_blank: @options[:include_blank])
35
+ end
36
+
37
+ return choices
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,13 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Text < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ Caisson::Helpers::Form::Field::Text.new(@core).build(field_name, value, @options)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::Field
5
+ class Textarea < Caisson::Helpers::Form::Builder::Field::Base
6
+ #*************************************************************************************
7
+ # PUBLIC INSTANCE METHODS
8
+ #*************************************************************************************
9
+ def build
10
+ Caisson::Helpers::Form::Field::Textarea.new(@core).build(field_name, value, @options)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,81 @@
1
+ #*************************************************************************************
2
+ # TOCOMMENT
3
+ #*************************************************************************************
4
+ module Caisson::Helpers::Form::Builder::FieldBuilder
5
+ class Base
6
+ attr_reader :nature
7
+ attr_reader :core
8
+
9
+ delegate :content_tag, to: :core
10
+ delegate :interpreti, to: :core
11
+
12
+ #*************************************************************************************
13
+ # CONSTRUCTOR
14
+ #*************************************************************************************
15
+ def initialize(core, name, options={})
16
+ options.reverse_merge!(nature: nil, hint: true)
17
+
18
+ @core = core
19
+ @name = name
20
+ @options = options.dup
21
+ @record = core.record
22
+ @show_hint = options[:hint]
23
+
24
+ @nature = Caisson::Helpers::Form::Builder::FieldBuilder::Nature.new(@record, name).get(force: options[:nature])
25
+ end
26
+
27
+ #*************************************************************************************
28
+ # PUBLIC INSTANCE METHODS
29
+ #*************************************************************************************
30
+ def build
31
+ "Caisson::Helpers::Form::Builder::Field::#{@nature.camelize}".constantize.new(@core, @record, @name, @options).build
32
+ end
33
+
34
+ def checkbox?
35
+ nature == 'checkbox'
36
+ end
37
+
38
+ def errors?
39
+ not errors.empty?
40
+ end
41
+
42
+ def errors
43
+ interpreti.field_errors(@name)
44
+ end
45
+
46
+ def hidden?
47
+ @nature == 'hidden'
48
+ end
49
+
50
+ def hint?
51
+ not interpreti.field_hint(@name).blank? and @show_hint
52
+ end
53
+
54
+ def label
55
+ interpreti.field_label(@name)
56
+ end
57
+
58
+ def wrap_field(field_tags)
59
+ css_class = ['field']
60
+ css_class << 'errors' if errors?
61
+
62
+ content_tag(:div, field_tags + wrapper_hint + wrapper_errors, class: css_class.join(' '))
63
+ end
64
+
65
+ def wrapper_errors
66
+ if errors?
67
+ content_tag(:div, errors.map{|e| content_tag(:span, e)}.join.html_safe, class: 'error-messages')
68
+ else
69
+ ''
70
+ end
71
+ end
72
+
73
+ def wrapper_hint
74
+ if hint?
75
+ content_tag(:div, interpreti.field_hint(@name).html_safe, class: 'hint')
76
+ else
77
+ ''
78
+ end
79
+ end
80
+ end
81
+ end