interview 0.0.1 → 0.0.6
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.
- checksums.yaml +4 -4
- data/interview.gemspec +4 -0
- data/lib/generators/interview/install/install_generator.rb +47 -0
- data/lib/generators/interview/install/templates/32px.png +0 -0
- data/lib/generators/interview/install/templates/40px.png +0 -0
- data/lib/generators/interview/install/templates/application.js +22 -0
- data/lib/generators/interview/install/templates/bootstrap_interview.css.scss +98 -0
- data/lib/generators/interview/install/templates/ckeditor_config.js +19 -0
- data/lib/generators/interview/install/templates/colors.css.scss +2 -0
- data/lib/generators/interview/install/templates/defaults_de.yml +204 -0
- data/lib/generators/interview/install/templates/interview.js.coffee +72 -0
- data/lib/generators/interview/install/templates/interview.rb +4 -0
- data/lib/generators/interview/install/templates/jstree.css +916 -0
- data/lib/generators/interview/install/templates/jstree.js +5892 -0
- data/lib/generators/interview/install/templates/missing_large.png +0 -0
- data/lib/generators/interview/install/templates/missing_medium.png +0 -0
- data/lib/generators/interview/install/templates/missing_thumb.png +0 -0
- data/lib/generators/interview/install/templates/throbber.gif +0 -0
- data/lib/generators/interview/install/templates/views_defaults_de.yml +8 -0
- data/lib/generators/interview/view_control/templates/card.rb +6 -0
- data/lib/generators/interview/view_control/templates/form.rb +6 -0
- data/lib/generators/interview/view_control/templates/list.rb +6 -0
- data/lib/generators/interview/view_control/view_control_generator.rb +34 -0
- data/lib/interview/actionbar.rb +38 -0
- data/lib/interview/association_attribute.rb +33 -0
- data/lib/interview/association_list_attribute.rb +36 -0
- data/lib/interview/association_methods.rb +23 -0
- data/lib/interview/attribute.rb +141 -0
- data/lib/interview/boolean_attribute.rb +59 -0
- data/lib/interview/breadcrumbs.rb +21 -0
- data/lib/interview/container_attribute.rb +30 -0
- data/lib/interview/control.rb +73 -0
- data/lib/interview/control_def.rb +36 -0
- data/lib/interview/date_attribute.rb +20 -0
- data/lib/interview/datetime_attribute.rb +20 -0
- data/lib/interview/decimal_attribute.rb +10 -0
- data/lib/interview/dropdown.rb +26 -0
- data/lib/interview/form.rb +69 -0
- data/lib/interview/form_errors.rb +22 -0
- data/lib/interview/grid.rb +53 -0
- data/lib/interview/has_controls.rb +43 -0
- data/lib/interview/hidden_attribute.rb +15 -0
- data/lib/interview/html_control.rb +15 -0
- data/lib/interview/html_text_attribute.rb +19 -0
- data/lib/interview/image_attribute.rb +34 -0
- data/lib/interview/integer_attribute.rb +5 -0
- data/lib/interview/link.rb +129 -0
- data/lib/interview/list.rb +21 -0
- data/lib/interview/navigation.rb +55 -0
- data/lib/interview/navigation_item.rb +26 -0
- data/lib/interview/nested_form.rb +51 -0
- data/lib/interview/nested_form_add_link.rb +80 -0
- data/lib/interview/nested_form_remove_link.rb +28 -0
- data/lib/interview/object_context.rb +17 -0
- data/lib/interview/option_attribute.rb +74 -0
- data/lib/interview/polymorphic_add_link.rb +28 -0
- data/lib/interview/space.rb +18 -0
- data/lib/interview/string_attribute.rb +5 -0
- data/lib/interview/tab.rb +21 -0
- data/lib/interview/tab_box.rb +29 -0
- data/lib/interview/text.rb +15 -0
- data/lib/interview/text_attribute.rb +21 -0
- data/lib/interview/tooltip.rb +38 -0
- data/lib/interview/tree.rb +33 -0
- data/lib/interview/version.rb +1 -1
- data/lib/interview/view.rb +87 -0
- data/lib/interview.rb +196 -0
- metadata +107 -2
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Interview
|
4
|
+
module Generators
|
5
|
+
class ViewControlGenerator < ::Rails::Generators::NamedBase
|
6
|
+
include Rails::Generators::ResourceHelpers
|
7
|
+
|
8
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
9
|
+
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
desc "This generator adds View Controls for a model."
|
12
|
+
|
13
|
+
def add_erb_templates
|
14
|
+
template "list.rb", "app/view_controls/#{file_name}_list.rb"
|
15
|
+
template "card.rb", "app/view_controls/#{file_name}_card.rb"
|
16
|
+
template "form.rb", "app/view_controls/#{file_name}_form.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def attribute_class_name(attribute)
|
22
|
+
return case attribute.type
|
23
|
+
when :string then 'StringAttribute'
|
24
|
+
when :text then 'TextAttribute'
|
25
|
+
when :boolean then 'BooleanAttribute'
|
26
|
+
when :date then 'DateAttribute'
|
27
|
+
when :option then 'OptionAttribute'
|
28
|
+
else 'Attribute'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Interview
|
2
|
+
class Actionbar < Control
|
3
|
+
include HasControls
|
4
|
+
|
5
|
+
attr_accessor :title, :icon
|
6
|
+
|
7
|
+
def render
|
8
|
+
title = @title || find_attribute(:title)
|
9
|
+
icon = @icon
|
10
|
+
if icon == :polymorphic
|
11
|
+
object = find_attribute! :object
|
12
|
+
icon = object.icon
|
13
|
+
end
|
14
|
+
|
15
|
+
html = Builder::XmlMarkup.new
|
16
|
+
html.div class: 'clearfix' do
|
17
|
+
unless @controls.empty?
|
18
|
+
html.ul class: 'list-inline pull-right' do
|
19
|
+
@controls.each do |control|
|
20
|
+
html.li do
|
21
|
+
html << control.render
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
if title
|
27
|
+
html.p class: 'h3' do
|
28
|
+
html.span '', class: icon if icon
|
29
|
+
html.text! ' ' if icon
|
30
|
+
html.text! title
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return html.target!
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Interview
|
2
|
+
class AssociationAttribute < Attribute
|
3
|
+
|
4
|
+
attr_accessor :association_class
|
5
|
+
|
6
|
+
def render_read
|
7
|
+
return '' if value.nil?
|
8
|
+
assoc_object = value
|
9
|
+
if h.respond_to? "#{@method}_path"
|
10
|
+
return Link.new(parent: self,
|
11
|
+
caption: "#{assoc_object.human_id}",
|
12
|
+
object: assoc_object).render
|
13
|
+
else
|
14
|
+
return assoc_object.human_id
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_write
|
19
|
+
object = find_attribute!(:object)
|
20
|
+
if object.respond_to? "#{method}_pool"
|
21
|
+
pool = object.send "#{method}_pool"
|
22
|
+
elsif @association_class
|
23
|
+
assoc_class = Object.const_get(@association_class.to_s.camelcase)
|
24
|
+
pool = assoc_class.all
|
25
|
+
else
|
26
|
+
assoc_class = object.class.new.send("build_#{@method}").class
|
27
|
+
pool = assoc_class.all
|
28
|
+
end
|
29
|
+
form_builder.collection_select "#{@method}_id", pool, :id, :human_id, {prompt: true}, {class: 'form-control'}
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Interview
|
2
|
+
class AssociationListAttribute < Attribute
|
3
|
+
|
4
|
+
attr_accessor :use
|
5
|
+
|
6
|
+
def render_read
|
7
|
+
return '' if value.nil?
|
8
|
+
assoc_objects = value
|
9
|
+
assoc_count = assoc_objects.count
|
10
|
+
if @use == 'link'
|
11
|
+
return Link.new(caption: "#{@method.humanize} (#{assoc_count})",
|
12
|
+
object: "#{assoc_objects.klass}",
|
13
|
+
filter: assoc_objects.where_values_hash).render # todo: Überarbeiten
|
14
|
+
else
|
15
|
+
return assoc_objects.human_ids.join(', ')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def render_write
|
20
|
+
if @use == 'multi_select'
|
21
|
+
object = find_attribute!(:object)
|
22
|
+
if object.respond_to? "#{method.singularize}_pool"
|
23
|
+
pool = object.send "#{method.singularize}_pool"
|
24
|
+
else
|
25
|
+
assoc_class = object.class.new.send(@method).build.class
|
26
|
+
pool = assoc_class.all
|
27
|
+
end
|
28
|
+
form_builder.collection_select "#{@method.singularize}_ids", pool, :id, :human_id, {prompt: true}, {class: 'form-control', multiple: true}
|
29
|
+
# form_builder.collection_select "#{@method.singularize}_ids", Category.all.collect {|x| [x.name, x.id]}, {}, :multiple => true
|
30
|
+
else
|
31
|
+
return form_builder.text_field "#{@method}_human_ids_string", class: 'form-control'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AssociationMethods
|
2
|
+
|
3
|
+
def define_readers
|
4
|
+
super
|
5
|
+
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
6
|
+
def #{name}_human_ids_string
|
7
|
+
return self.#{name}.human_ids.join(', ')
|
8
|
+
end
|
9
|
+
CODE
|
10
|
+
end
|
11
|
+
|
12
|
+
def define_writers
|
13
|
+
super
|
14
|
+
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
15
|
+
def #{name}_human_ids_string=(string)
|
16
|
+
human_ids = string.split /, */
|
17
|
+
#{name} = human_ids.map { |human_id| self.#{name}.klass.find_by_human_id(human_id) }
|
18
|
+
self.#{name} = #{name}
|
19
|
+
end
|
20
|
+
CODE
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Interview
|
2
|
+
class Attribute < Control
|
3
|
+
|
4
|
+
attr_accessor :method, :caption, :style, :link, :nil_value, :hide_caption, :hide_tooltip,
|
5
|
+
:only_for, :align, :on_changed
|
6
|
+
|
7
|
+
def value
|
8
|
+
object = find_attribute! :object
|
9
|
+
if object.respond_to? @method
|
10
|
+
val = object.send @method
|
11
|
+
end
|
12
|
+
val = @nil_value if val.nil?
|
13
|
+
return val
|
14
|
+
end
|
15
|
+
|
16
|
+
def caption
|
17
|
+
if @caption
|
18
|
+
return @caption
|
19
|
+
else
|
20
|
+
object = find_attribute! :object
|
21
|
+
puts "#{object.class.name} #{@method}"
|
22
|
+
return object.class.human_attribute_name(@method)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def tooltip
|
27
|
+
object = find_attribute! :object
|
28
|
+
return h.t("activerecord.tooltips.#{object.class.name.underscore}.attributes.#{@method}", default: '')
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def render
|
33
|
+
return '' if hide?
|
34
|
+
|
35
|
+
if @style and respond_to?("render_#{@style}_style", true)
|
36
|
+
return send("render_#{@style}_style")
|
37
|
+
else
|
38
|
+
return render_default_style
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_read
|
43
|
+
return value.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def render_write
|
47
|
+
return form_builder.text_field @method, class: 'form-control'
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def render_default_style
|
53
|
+
return add_link(render_read)
|
54
|
+
end
|
55
|
+
|
56
|
+
def render_card_style
|
57
|
+
html = Builder::XmlMarkup.new
|
58
|
+
html.div class: 'row' do
|
59
|
+
html.p class: 'col-xs-3' do
|
60
|
+
html.b caption unless @hide_caption
|
61
|
+
if not @hide_tooltip and tooltip != ''
|
62
|
+
html << Tooltip.new(tooltip: tooltip, style: :popover).render
|
63
|
+
end
|
64
|
+
end
|
65
|
+
html.p class: 'col-xs-9' do
|
66
|
+
html << add_link(render_read)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return html.target!
|
70
|
+
end
|
71
|
+
|
72
|
+
def render_form_style
|
73
|
+
form_builder = find_attribute! :form_builder
|
74
|
+
object = find_attribute! :object
|
75
|
+
align = @align || find_attribute(:align)
|
76
|
+
|
77
|
+
html = Builder::XmlMarkup.new
|
78
|
+
html.div class: "form-group" do # todo: old class: "form-group attribute_#{@method.to_s} collapse in"
|
79
|
+
opts = {}
|
80
|
+
opts[:class] = 'col-xs-3 control-label' if align == 'horizontal'
|
81
|
+
opts[:class] = 'sr-only' if align == 'inline'
|
82
|
+
if @hide_caption
|
83
|
+
html.div opts
|
84
|
+
else
|
85
|
+
html << form_builder.label(@method, opts) do
|
86
|
+
form_html = Builder::XmlMarkup.new
|
87
|
+
form_html.text! caption
|
88
|
+
# if not @hide_tooltip and tooltip != ''
|
89
|
+
# form_html.text! ' '
|
90
|
+
# form_html << Tooltip.new(tooltip: tooltip, style: :popover).render
|
91
|
+
# end
|
92
|
+
form_html.target!.html_safe
|
93
|
+
end
|
94
|
+
end
|
95
|
+
if align == 'horizontal'
|
96
|
+
html.div class: 'col-xs-9' do
|
97
|
+
html << render_write
|
98
|
+
if not @hide_tooltip and tooltip != ''
|
99
|
+
html.p tooltip, class: 'help-block'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
else
|
103
|
+
html << render_write
|
104
|
+
if not @hide_tooltip and tooltip != ''
|
105
|
+
html.p tooltip, class: 'help-block'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
return html.target!
|
110
|
+
end
|
111
|
+
|
112
|
+
def form_builder
|
113
|
+
return find_attribute! :form_builder
|
114
|
+
end
|
115
|
+
|
116
|
+
def add_link(value)
|
117
|
+
if @link
|
118
|
+
return Link.new(parent: @parent, caption: value.to_s).render
|
119
|
+
else
|
120
|
+
return value
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def hide?
|
125
|
+
if @only_for
|
126
|
+
object = find_attribute! :object
|
127
|
+
if @only_for.is_a? Array
|
128
|
+
unless @only_for.any? { |class_name| object.is_a? class_name.camelcase.constantize }
|
129
|
+
return true
|
130
|
+
end
|
131
|
+
else
|
132
|
+
unless object.is_a? @only_for.camelcase.constantize
|
133
|
+
return true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
return false
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Interview
|
2
|
+
class BooleanAttribute < Attribute
|
3
|
+
|
4
|
+
def render_read
|
5
|
+
return '' if value.nil?
|
6
|
+
html = Builder::XmlMarkup.new
|
7
|
+
if value
|
8
|
+
html.span '', class: 'glyphicon glyphicon-ok'
|
9
|
+
else
|
10
|
+
html.text! ''
|
11
|
+
end
|
12
|
+
return html.target!
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_write
|
16
|
+
form_builder.check_box @method
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def render_form_style
|
22
|
+
form_builder = find_attribute! :form_builder
|
23
|
+
object = find_attribute! :object
|
24
|
+
align = @align || find_attribute(:align)
|
25
|
+
|
26
|
+
html = Builder::XmlMarkup.new
|
27
|
+
html.div class: "form-group attribute_#{@method.to_s} collapse in" do
|
28
|
+
if align == 'horizontal'
|
29
|
+
html.div class: 'col-xs-9 col-xs-offset-3' do
|
30
|
+
html << render_checkbox
|
31
|
+
end
|
32
|
+
else
|
33
|
+
html << render_checkbox
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return html.target!
|
37
|
+
end
|
38
|
+
|
39
|
+
def render_checkbox
|
40
|
+
html = Builder::XmlMarkup.new
|
41
|
+
html << render_write
|
42
|
+
html.text! ' '
|
43
|
+
html << form_builder.label(@method) do
|
44
|
+
form_html = Builder::XmlMarkup.new
|
45
|
+
form_html.text! caption
|
46
|
+
# if not @hide_tooltip and tooltip != ''
|
47
|
+
# form_html.text! ' '
|
48
|
+
# form_html << Tooltip.new(tooltip: tooltip, style: :popover).render
|
49
|
+
# end
|
50
|
+
form_html.target!.html_safe
|
51
|
+
end
|
52
|
+
if not @hide_tooltip and tooltip != ''
|
53
|
+
html.p tooltip, class: 'help-block'
|
54
|
+
end
|
55
|
+
return html.target!
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Interview
|
2
|
+
class Breadcrumbs < Control
|
3
|
+
|
4
|
+
include HasControls
|
5
|
+
|
6
|
+
def render
|
7
|
+
if Object.const_defined?('Gretel')
|
8
|
+
return h.breadcrumbs
|
9
|
+
else
|
10
|
+
html = Builder::XmlMarkup.new
|
11
|
+
html.ol class: 'breadcrumb' do
|
12
|
+
@controls.each do |control|
|
13
|
+
html << control.render
|
14
|
+
end
|
15
|
+
end
|
16
|
+
return html.target!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Interview
|
2
|
+
class ContainerAttribute < Attribute
|
3
|
+
include HasControls
|
4
|
+
|
5
|
+
def value
|
6
|
+
return nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def caption
|
10
|
+
return @caption.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def tooltip
|
14
|
+
return ''
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_read
|
18
|
+
html = Builder::XmlMarkup.new
|
19
|
+
@controls.each do |control|
|
20
|
+
html << control.render
|
21
|
+
end
|
22
|
+
return html.target!
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_write
|
26
|
+
render_read
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Interview
|
2
|
+
class Control
|
3
|
+
include Draper::ViewHelpers
|
4
|
+
|
5
|
+
attr_accessor :parent
|
6
|
+
|
7
|
+
def initialize(params={})
|
8
|
+
set_attributes(params)
|
9
|
+
set_defaults
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_attributes(params={})
|
13
|
+
params.each do |key, value|
|
14
|
+
key = "#{key}=".to_sym
|
15
|
+
if respond_to?(key) # and not value.nil?
|
16
|
+
send(key, value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_defaults
|
22
|
+
if self.class.const_defined? 'DEFAULTS'
|
23
|
+
self.class::DEFAULTS.each do |key, value|
|
24
|
+
self.send("#{key}=".to_sym, value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def ancestors
|
30
|
+
if @parent.nil?
|
31
|
+
return []
|
32
|
+
else
|
33
|
+
return [@parent] + @parent.ancestors
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_attribute(attribute)
|
38
|
+
return nil if @parent.nil?
|
39
|
+
if @parent.respond_to? attribute
|
40
|
+
return @parent.send attribute
|
41
|
+
else
|
42
|
+
return @parent.find_attribute attribute
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_attribute!(attr_name)
|
47
|
+
attribute = find_attribute(attr_name)
|
48
|
+
throw "Attribute #{attr_name} was not found." if attribute.nil?
|
49
|
+
return attribute
|
50
|
+
end
|
51
|
+
|
52
|
+
def render
|
53
|
+
return ''
|
54
|
+
end
|
55
|
+
|
56
|
+
@definition = ControlDef.new :control
|
57
|
+
|
58
|
+
def self.definition
|
59
|
+
return @definition
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.build(opts={})
|
63
|
+
return @definition.build(opts)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.inherited(subclass)
|
67
|
+
new_def = @definition.deep_dup
|
68
|
+
new_def.klass = subclass.name.underscore.to_sym
|
69
|
+
subclass.instance_variable_set :@definition, new_def
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ControlDef
|
2
|
+
|
3
|
+
attr_accessor :klass
|
4
|
+
attr_reader :params, :controls
|
5
|
+
|
6
|
+
def initialize(klass, params={})
|
7
|
+
@klass = klass.to_sym
|
8
|
+
@params = params
|
9
|
+
@controls = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def control(klass, params={}, &block)
|
13
|
+
control = ControlDef.new(klass, params)
|
14
|
+
@controls << control
|
15
|
+
yield(control) if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def build(params={})
|
19
|
+
control = Object::const_get("#{@klass.to_s.camelcase}").new(@params.merge(params))
|
20
|
+
if control.respond_to? :add_controls
|
21
|
+
control.add_controls build_controls_for(control)
|
22
|
+
end
|
23
|
+
return control
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_controls_for(parent_control)
|
27
|
+
return @controls.map { |c| c.build(parent: parent_control) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def deep_dup
|
31
|
+
new_definition = self.class.new(@klass, @params.deep_dup)
|
32
|
+
new_definition.instance_variable_set :@controls, @controls.deep_dup
|
33
|
+
return new_definition
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Interview
|
2
|
+
class DateAttribute < Attribute
|
3
|
+
|
4
|
+
attr_accessor :format
|
5
|
+
|
6
|
+
def render_read
|
7
|
+
return '' if value.nil?
|
8
|
+
if @format
|
9
|
+
return value.strftime(@format)
|
10
|
+
else
|
11
|
+
return h.l value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_write
|
16
|
+
form_builder.date_select @method #, {}, {class: 'form-control'}
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Interview
|
2
|
+
class DatetimeAttribute < Attribute
|
3
|
+
|
4
|
+
attr_accessor :format
|
5
|
+
|
6
|
+
def render_read
|
7
|
+
return '' if value.nil?
|
8
|
+
if @format
|
9
|
+
return value.strftime(@format)
|
10
|
+
else
|
11
|
+
return h.l value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_write
|
16
|
+
form_builder.date_select @method #, {}, {class: 'form-control'}
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Interview
|
2
|
+
class Dropdown < Control
|
3
|
+
include HasControls
|
4
|
+
|
5
|
+
attr_accessor :caption, :align
|
6
|
+
|
7
|
+
def render
|
8
|
+
html = Builder::XmlMarkup.new
|
9
|
+
html.div class: 'dropdown' do
|
10
|
+
html.a class: 'dropdown-toggle btn btn-default', href: '#', :'data-toggle' => 'dropdown' do
|
11
|
+
html.text! @caption + ' '
|
12
|
+
html.span '', class: 'caret'
|
13
|
+
end
|
14
|
+
html.ul class: 'dropdown-menu' do
|
15
|
+
@controls.each do |control|
|
16
|
+
html.li do
|
17
|
+
html << control.render
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
return html.target!
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|