interview 0.0.6 → 0.0.7
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/lib/generators/interview/install/install_generator.rb +3 -0
- data/lib/generators/interview/install/templates/application.css +14 -0
- data/lib/generators/interview/install/templates/application.js +2 -0
- data/lib/generators/interview/install/templates/blueimp-gallery.css +226 -0
- data/lib/generators/interview/install/templates/blueimp-gallery.js +1341 -0
- data/lib/generators/interview/install/templates/bootstrap_interview.css.scss +28 -0
- data/lib/generators/interview/install/templates/interview.js.coffee +60 -2
- data/lib/generators/interview/install/templates/missing_thumb.png +0 -0
- data/lib/interview/association_attribute.rb +6 -8
- data/lib/interview/association_list_attribute.rb +3 -2
- data/lib/interview/attribute.rb +52 -30
- data/lib/interview/collapse_container.rb +20 -0
- data/lib/interview/condition_container.rb +19 -0
- data/lib/interview/dropdown.rb +16 -4
- data/lib/interview/form.rb +42 -47
- data/lib/interview/form_errors.rb +2 -2
- data/lib/interview/grid.rb +1 -1
- data/lib/interview/image_attribute.rb +55 -15
- data/lib/interview/image_gallery_attribute.rb +74 -0
- data/lib/interview/image_light_box.rb +19 -0
- data/lib/interview/link.rb +2 -1
- data/lib/interview/list.rb +8 -2
- data/lib/interview/media_object.rb +45 -0
- data/lib/interview/navigation_item.rb +19 -4
- data/lib/interview/navigation_item_old.rb +26 -0
- data/lib/interview/nested_form_add_link.rb +1 -1
- data/lib/interview/panel.rb +18 -0
- data/lib/interview/polymorphic_add_link.rb +33 -4
- data/lib/interview/search_form.rb +21 -0
- data/lib/interview/text.rb +33 -3
- data/lib/interview/version.rb +1 -1
- data/lib/interview/view.rb +28 -6
- data/lib/interview.rb +12 -0
- metadata +13 -2
@@ -4,6 +4,11 @@
|
|
4
4
|
|
5
5
|
$navbar-default-brand-color: $brand-primary;
|
6
6
|
$navbar-default-bg: $brand-primary-lighten;
|
7
|
+
$navbar-inverse-brand-color: $brand-primary-lighten;
|
8
|
+
$navbar-inverse-bg: $brand-primary;
|
9
|
+
$navbar-inverse-color: #ffffff;
|
10
|
+
$navbar-inverse-link-color: $brand-primary-lighten;
|
11
|
+
$navbar-inverse-link-hover-color: #ffffff;
|
7
12
|
|
8
13
|
@import 'bootstrap';
|
9
14
|
|
@@ -95,4 +100,27 @@ $nav-stacked-link-padding-level2: 5px 15px 5px 45px !default;
|
|
95
100
|
input {
|
96
101
|
width: auto;
|
97
102
|
}
|
103
|
+
}
|
104
|
+
|
105
|
+
.inline-block {
|
106
|
+
display: inline-block;
|
107
|
+
/* IE 7 hack */
|
108
|
+
*zoom:1;
|
109
|
+
*display: inline;
|
110
|
+
vertical-align: middle;
|
111
|
+
margin-right: 10px;
|
112
|
+
}
|
113
|
+
|
114
|
+
.list-item {
|
115
|
+
margin-top: 15px;
|
116
|
+
}
|
117
|
+
|
118
|
+
.img-thumb {
|
119
|
+
display: inline-block;
|
120
|
+
/* IE 7 hack */
|
121
|
+
*zoom:1;
|
122
|
+
*display: inline;
|
123
|
+
vertical-align: middle;
|
124
|
+
margin-right: 5px;
|
125
|
+
margin-bottom: 5px;
|
98
126
|
}
|
@@ -42,7 +42,7 @@ jQuery ->
|
|
42
42
|
e.preventDefault()
|
43
43
|
object_class = $('#add_link_class').children('option:selected').val()
|
44
44
|
if object_class != ''
|
45
|
-
location.href = "#{$(this).attr('href')}?
|
45
|
+
location.href = "#{$(this).attr('href')}?filter%5Btype%5D=#{object_class}"
|
46
46
|
|
47
47
|
$('.jstree').each ->
|
48
48
|
params =
|
@@ -69,4 +69,62 @@ jQuery ->
|
|
69
69
|
"position": data.position
|
70
70
|
error: (data) ->
|
71
71
|
tree.jstree('refresh')
|
72
|
-
$(tree).before("<div class=\"alert alert-danger\">#{data.responseText}</div>")
|
72
|
+
$(tree).before("<div class=\"alert alert-danger\">#{data.responseText}</div>")
|
73
|
+
|
74
|
+
$('.collapse_link').click (e) ->
|
75
|
+
e.preventDefault()
|
76
|
+
$($(this).data('target')).collapse('toggle')
|
77
|
+
|
78
|
+
$('.img-link').click (e) ->
|
79
|
+
links = $('.img-link')
|
80
|
+
target = event.target || event.srcElement
|
81
|
+
link = if target.src then target.parentNode else target
|
82
|
+
options = { index: link, event: e }
|
83
|
+
blueimp.Gallery(links, options)
|
84
|
+
|
85
|
+
$('.image-upload').fileupload
|
86
|
+
add: (e, data) ->
|
87
|
+
types = /(\.|\/)(gif|jpe?g|png|mov|mpeg|mpeg4|avi)$/i
|
88
|
+
file = data.files[0]
|
89
|
+
if types.test(file.type) || types.test(file.name)
|
90
|
+
data.context = $(tmpl("upload-progress-script", file))
|
91
|
+
$('#upload-progress').append($(data.context))
|
92
|
+
|
93
|
+
$("input[name='_method']").attr('name', 'method')
|
94
|
+
data.submit()
|
95
|
+
$("input[name='method']").attr('name', '_method')
|
96
|
+
else
|
97
|
+
alert("#{file.name} is not a gif, jpg or png image file")
|
98
|
+
progress: (e, data) ->
|
99
|
+
if data.context
|
100
|
+
progress = parseInt(data.loaded / data.total * 100, 10)
|
101
|
+
data.context.find('.bar').css('width', progress + '%')
|
102
|
+
done: (e, data) ->
|
103
|
+
$('#image-tag').attr('src', data.result.thumb_url)
|
104
|
+
# context = $(tmpl("image-thumb-script", data.result))
|
105
|
+
# $('#image-gallery').append($(context))
|
106
|
+
$('.image-id').attr('value', data.result.id)
|
107
|
+
|
108
|
+
$('.multiple-image-upload').fileupload
|
109
|
+
add: (e, data) ->
|
110
|
+
types = /(\.|\/)(gif|jpe?g|png|mov|mpeg|mpeg4|avi)$/i
|
111
|
+
file = data.files[0]
|
112
|
+
if types.test(file.type) || types.test(file.name)
|
113
|
+
data.context = $(tmpl("upload-progress-script", file))
|
114
|
+
$('#upload-progress').append($(data.context))
|
115
|
+
|
116
|
+
$("input[name='_method']").attr('name', 'method')
|
117
|
+
data.submit()
|
118
|
+
$("input[name='method']").attr('name', '_method')
|
119
|
+
else
|
120
|
+
alert("#{file.name} is not a gif, jpg or png image file")
|
121
|
+
progress: (e, data) ->
|
122
|
+
if data.context
|
123
|
+
progress = parseInt(data.loaded / data.total * 100, 10)
|
124
|
+
data.context.find('.bar').css('width', progress + '%')
|
125
|
+
done: (e, data) ->
|
126
|
+
context = $(tmpl("image-thumb-script", data.result))
|
127
|
+
$('#image-gallery').append($(context))
|
128
|
+
ids = JSON.parse($('.image-ids').attr('value'))
|
129
|
+
ids.push data.result.id
|
130
|
+
$('.image-ids').attr('value', JSON.stringify(ids))
|
Binary file
|
@@ -6,13 +6,10 @@ module Interview
|
|
6
6
|
def render_read
|
7
7
|
return '' if value.nil?
|
8
8
|
assoc_object = value
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
return assoc_object.human_id
|
15
|
-
end
|
9
|
+
# todo: Link nicht anzeigen, wenn Route für Objekt nicht existiert
|
10
|
+
return Link.new(parent: self,
|
11
|
+
caption: "#{assoc_object.human_id}",
|
12
|
+
object: assoc_object).render
|
16
13
|
end
|
17
14
|
|
18
15
|
def render_write
|
@@ -26,7 +23,8 @@ module Interview
|
|
26
23
|
assoc_class = object.class.new.send("build_#{@method}").class
|
27
24
|
pool = assoc_class.all
|
28
25
|
end
|
29
|
-
form_builder.collection_select "#{@method}_id", pool, :id, :human_id, {
|
26
|
+
form_builder.collection_select "#{@method}_id", pool, :id, :human_id, {include_blank: true}, {class: 'form-control'}
|
27
|
+
# todo: prompt einbauen
|
30
28
|
end
|
31
29
|
|
32
30
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Interview
|
2
2
|
class AssociationListAttribute < Attribute
|
3
3
|
|
4
|
-
attr_accessor :use
|
4
|
+
attr_accessor :use, :size
|
5
5
|
|
6
6
|
def render_read
|
7
7
|
return '' if value.nil?
|
@@ -17,6 +17,7 @@ module Interview
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def render_write
|
20
|
+
size = @size || 8
|
20
21
|
if @use == 'multi_select'
|
21
22
|
object = find_attribute!(:object)
|
22
23
|
if object.respond_to? "#{method.singularize}_pool"
|
@@ -25,7 +26,7 @@ module Interview
|
|
25
26
|
assoc_class = object.class.new.send(@method).build.class
|
26
27
|
pool = assoc_class.all
|
27
28
|
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", pool, :id, :human_id, {prompt: true}, {class: 'form-control', multiple: true, size: size}
|
29
30
|
# form_builder.collection_select "#{@method.singularize}_ids", Category.all.collect {|x| [x.name, x.id]}, {}, :multiple => true
|
30
31
|
else
|
31
32
|
return form_builder.text_field "#{@method}_human_ids_string", class: 'form-control'
|
data/lib/interview/attribute.rb
CHANGED
@@ -2,10 +2,15 @@ module Interview
|
|
2
2
|
class Attribute < Control
|
3
3
|
|
4
4
|
attr_accessor :method, :caption, :style, :link, :nil_value, :hide_caption, :hide_tooltip,
|
5
|
-
:only_for, :align, :on_changed
|
5
|
+
:only_for, :align, :on_changed, :html_class, :surrounding_tag
|
6
|
+
|
7
|
+
def initialize(params={})
|
8
|
+
@html_class = []
|
9
|
+
super
|
10
|
+
end
|
6
11
|
|
7
12
|
def value
|
8
|
-
object = find_attribute!
|
13
|
+
object = @object || find_attribute!(:object)
|
9
14
|
if object.respond_to? @method
|
10
15
|
val = object.send @method
|
11
16
|
end
|
@@ -18,14 +23,13 @@ module Interview
|
|
18
23
|
return @caption
|
19
24
|
else
|
20
25
|
object = find_attribute! :object
|
21
|
-
puts "#{object.class.name} #{@method}"
|
22
26
|
return object.class.human_attribute_name(@method)
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def tooltip
|
27
31
|
object = find_attribute! :object
|
28
|
-
return h.t("activerecord.
|
32
|
+
return h.t("activerecord.attribute_tooltips.#{object.class.model_name.i18n_key}.#{@method}", default: '')
|
29
33
|
end
|
30
34
|
|
31
35
|
|
@@ -33,10 +37,11 @@ module Interview
|
|
33
37
|
return '' if hide?
|
34
38
|
|
35
39
|
if @style and respond_to?("render_#{@style}_style", true)
|
36
|
-
|
40
|
+
html = send("render_#{@style}_style")
|
37
41
|
else
|
38
|
-
|
42
|
+
html = render_default_style
|
39
43
|
end
|
44
|
+
return add_surrounding_tag(html)
|
40
45
|
end
|
41
46
|
|
42
47
|
def render_read
|
@@ -74,45 +79,62 @@ module Interview
|
|
74
79
|
object = find_attribute! :object
|
75
80
|
align = @align || find_attribute(:align)
|
76
81
|
|
77
|
-
html = Builder::XmlMarkup.new
|
78
|
-
html.div class:
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
82
|
+
html = Builder::XmlMarkup.new(indent: 2)
|
83
|
+
html.div class: 'form-group' do
|
84
|
+
|
85
|
+
html.div class: 'col-xs-3' if @hide_caption and align == 'horizontal'
|
86
|
+
render_form_label(html)
|
87
|
+
|
95
88
|
if align == 'horizontal'
|
96
89
|
html.div class: 'col-xs-9' do
|
97
90
|
html << render_write
|
98
|
-
|
99
|
-
html.p tooltip, class: 'help-block'
|
100
|
-
end
|
91
|
+
render_form_tooltip(html)
|
101
92
|
end
|
102
93
|
else
|
103
94
|
html << render_write
|
104
|
-
|
105
|
-
html.p tooltip, class: 'help-block'
|
106
|
-
end
|
95
|
+
render_form_tooltip(html)
|
107
96
|
end
|
97
|
+
|
108
98
|
end
|
109
99
|
return html.target!
|
110
100
|
end
|
111
101
|
|
102
|
+
def render_form_label(html)
|
103
|
+
align = @align || find_attribute(:align)
|
104
|
+
html_opts = if @hide_caption or align == 'inline'
|
105
|
+
{ class: 'sr-only' }
|
106
|
+
elsif align == 'horizontal'
|
107
|
+
{ class: 'col-xs-3 control-label' }
|
108
|
+
else
|
109
|
+
{}
|
110
|
+
end
|
111
|
+
html << form_builder.label(@method, html_opts) do
|
112
|
+
form_html = Builder::XmlMarkup.new
|
113
|
+
form_html.text! caption
|
114
|
+
form_html.target!.html_safe
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def render_form_tooltip(html)
|
119
|
+
if not @hide_tooltip and tooltip != ''
|
120
|
+
html.p tooltip, class: 'help-block'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
112
124
|
def form_builder
|
113
125
|
return find_attribute! :form_builder
|
114
126
|
end
|
115
127
|
|
128
|
+
def add_surrounding_tag(html)
|
129
|
+
if @surrounding_tag
|
130
|
+
opts = {}
|
131
|
+
opts[:class] = @html_class.join(' ') unless @html_class.empty?
|
132
|
+
return h.content_tag @surrounding_tag.to_sym, html, opts
|
133
|
+
else
|
134
|
+
return html
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
116
138
|
def add_link(value)
|
117
139
|
if @link
|
118
140
|
return Link.new(parent: @parent, caption: value.to_s).render
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Interview
|
2
|
+
class CollapseContainer < Control
|
3
|
+
include HasControls
|
4
|
+
|
5
|
+
attr_accessor :caption
|
6
|
+
|
7
|
+
def render
|
8
|
+
html = Builder::XmlMarkup.new
|
9
|
+
new_id = Time.now.to_f.to_s.delete('.')
|
10
|
+
html << h.link_to(@caption, '#', class: 'collapse_link', data: { toggle: 'collapse', target: "##{new_id}" })
|
11
|
+
html.div id: new_id, class: 'panel-collapse collapse' do
|
12
|
+
@controls.each do |control|
|
13
|
+
html << control.render
|
14
|
+
end
|
15
|
+
end
|
16
|
+
return html.target!
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Interview
|
2
|
+
class ConditionContainer < Control
|
3
|
+
include HasControls
|
4
|
+
|
5
|
+
attr_accessor :condition
|
6
|
+
|
7
|
+
def render
|
8
|
+
object = find_attribute :object
|
9
|
+
if @condition.call(object)
|
10
|
+
return @controls.map do |control|
|
11
|
+
control.render
|
12
|
+
end.join
|
13
|
+
else
|
14
|
+
return ''
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/interview/dropdown.rb
CHANGED
@@ -2,13 +2,25 @@ module Interview
|
|
2
2
|
class Dropdown < Control
|
3
3
|
include HasControls
|
4
4
|
|
5
|
-
attr_accessor :caption, :
|
5
|
+
attr_accessor :image, :caption, :style, :html_class
|
6
|
+
|
7
|
+
def initialize(params={})
|
8
|
+
@html_class = []
|
9
|
+
super
|
10
|
+
end
|
6
11
|
|
7
12
|
def render
|
8
13
|
html = Builder::XmlMarkup.new
|
9
|
-
|
10
|
-
|
11
|
-
|
14
|
+
html_class = @html_class.dup
|
15
|
+
html_class << 'dropdown'
|
16
|
+
html.div class: html_class.join(' ') do
|
17
|
+
html_class = 'dropdown-toggle'
|
18
|
+
html_class += ' btn btn-default' if @style == 'button'
|
19
|
+
html.a class: html_class, href: '#', :'data-toggle' => 'dropdown' do
|
20
|
+
html.span '', class: "glyphicon glyphicon-#{@image}" if @image
|
21
|
+
html.text! ' ' if @image and @caption
|
22
|
+
html.text! @caption if @caption
|
23
|
+
html.text! ' ' if @caption
|
12
24
|
html.span '', class: 'caret'
|
13
25
|
end
|
14
26
|
html.ul class: 'dropdown-menu' do
|
data/lib/interview/form.rb
CHANGED
@@ -5,64 +5,59 @@ module Interview
|
|
5
5
|
attr_accessor :skip_submit, :multi_create, :align, :redirect_to
|
6
6
|
attr_reader :form_builder
|
7
7
|
|
8
|
-
def
|
9
|
-
return :write
|
10
|
-
end
|
11
|
-
|
12
|
-
def render # todo: Aufräumen
|
8
|
+
def render
|
13
9
|
object = find_attribute!(:object)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# model = object.class.superclass.name.underscore
|
19
|
-
# end
|
20
|
-
if object.id
|
21
|
-
url = h.send("#{model}_path", object)
|
22
|
-
else
|
23
|
-
url = h.send("#{model.pluralize}_path")
|
10
|
+
html_options = case @align
|
11
|
+
when 'horizontal' then { class: 'form-horizontal' }
|
12
|
+
when 'inline' then { class: 'form-inline' }
|
13
|
+
else {}
|
24
14
|
end
|
25
|
-
|
26
|
-
opts[:html][:class] = 'form-horizontal' if @align == 'horizontal'
|
27
|
-
opts[:html][:class] = 'form-inline' if @align == 'inline'
|
28
|
-
html = Builder::XmlMarkup.new
|
29
|
-
html << h.form_for(object, opts) do |form_builder|
|
15
|
+
return h.form_for(object, role: 'form', html: html_options) do |form_builder|
|
30
16
|
@form_builder = form_builder
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
form_html << h.hidden_field_tag('redirect_to', h.parent_breadcrumb.url)
|
35
|
-
end
|
17
|
+
html = Builder::XmlMarkup.new(indent: 2)
|
18
|
+
|
19
|
+
render_default_controls(html)
|
36
20
|
|
37
21
|
@controls.each do |control|
|
38
|
-
|
39
|
-
|
22
|
+
html << control.render
|
23
|
+
html.text! ' ' if @align == 'inline'
|
40
24
|
end
|
41
25
|
|
42
|
-
if
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
form_html << form_builder.submit(class: 'btn btn-primary')
|
47
|
-
if @multi_create || find_attribute(:multi_create)
|
48
|
-
form_html.text! ' '
|
49
|
-
form_html << h.check_box_tag('new_record', '1', true)
|
50
|
-
form_html.text! ' und weiteren Datesatz'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
else
|
55
|
-
form_html << form_builder.submit(class: 'btn btn-primary')
|
56
|
-
if @multi_create || find_attribute(:multi_create)
|
57
|
-
form_html.text! ' '
|
58
|
-
form_html << h.check_box_tag('new_record', '1', true)
|
59
|
-
form_html.text! ' und weiteren Datesatz'
|
26
|
+
if @align == 'horizontal'
|
27
|
+
html.div class: 'form-group' do
|
28
|
+
html.div class: 'col-sm-offset-3 col-sm-9' do
|
29
|
+
render_submit(html)
|
60
30
|
end
|
61
31
|
end
|
32
|
+
else
|
33
|
+
render_submit(html)
|
34
|
+
end
|
35
|
+
|
36
|
+
html.target!.html_safe
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def render_submit(html)
|
43
|
+
if not @skip_submit
|
44
|
+
html << form_builder.submit(class: 'btn btn-primary')
|
45
|
+
if @multi_create || find_attribute(:multi_create)
|
46
|
+
html.text! ' '
|
47
|
+
html << h.check_box_tag('new_record', '1', true)
|
48
|
+
html.text! ' und weiteren Datesatz' # todo
|
62
49
|
end
|
63
|
-
form_html.target!.html_safe
|
64
50
|
end
|
65
|
-
|
51
|
+
end
|
52
|
+
|
53
|
+
def render_default_controls(html)
|
54
|
+
html << FormErrors.new(parent: self).render
|
55
|
+
|
56
|
+
if @redirect_to == :parent and Object.const_defined? 'Gretel'
|
57
|
+
html << h.hidden_field_tag('redirect_to', h.parent_breadcrumb.url)
|
58
|
+
elsif @redirect_to == :current
|
59
|
+
html << h.hidden_field_tag('redirect_to', h.request.original_url)
|
60
|
+
end
|
66
61
|
end
|
67
62
|
|
68
63
|
end
|
@@ -6,8 +6,8 @@ module Interview
|
|
6
6
|
|
7
7
|
html = Builder::XmlMarkup.new
|
8
8
|
if object.errors.any?
|
9
|
-
html.div class: '
|
10
|
-
html.
|
9
|
+
html.div class: 'alert alert-danger' do
|
10
|
+
html.h4 h.translate("errors.template.header", count: object.errors.count, model: object.class.model_name.human)
|
11
11
|
html.ul do
|
12
12
|
object.errors.full_messages.each do |msg|
|
13
13
|
html.li msg
|
data/lib/interview/grid.rb
CHANGED
@@ -44,7 +44,7 @@ module Interview
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
if objects.empty?
|
47
|
-
html.p "Keine #{@object.class.
|
47
|
+
html.p "Keine #{@object.class.human_name(count: 2)} vorhanden.", class: 'text-center text-muted'
|
48
48
|
end
|
49
49
|
return html.target!
|
50
50
|
end
|
@@ -1,32 +1,72 @@
|
|
1
1
|
module Interview
|
2
2
|
class ImageAttribute < Attribute
|
3
3
|
|
4
|
-
|
4
|
+
# - Bild muss in eingener Klasse ausgelagert werden
|
5
|
+
# - object muss die Methode method_id= implementieren
|
6
|
+
# - method_id muss als parameter erlaubt werden
|
7
|
+
# - json ansicht auf bild muss vorhanden sein
|
8
|
+
|
9
|
+
attr_accessor :object, :submethod, :image_style, :hide_if_not_exists
|
5
10
|
|
6
11
|
def render_read
|
7
|
-
|
12
|
+
submethod = @submethod || 'attachment'
|
8
13
|
image_style = @image_style || :thumb
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
object = @object || find_attribute(:object)
|
15
|
+
image = value || object.association(@method).build
|
16
|
+
|
17
|
+
attachment = image.send(submethod)
|
18
|
+
return '' if not attachment.exists? and @hide_if_not_exists
|
19
|
+
|
20
|
+
html = Builder::XmlMarkup.new
|
21
|
+
opts = {class: "image_#{image_style}"}
|
22
|
+
opts[:class] += ' ' + @html_class.join(' ') unless @html_class.empty? or @surrounding_tag
|
23
|
+
html.div opts do
|
24
|
+
html << h.image_tag(attachment.url(image_style), class: 'img-responsive')
|
13
25
|
end
|
26
|
+
return html.target!
|
14
27
|
end
|
15
28
|
|
16
29
|
def render_write
|
17
|
-
object = find_attribute(:object)
|
18
|
-
|
30
|
+
object = @object || find_attribute(:object)
|
31
|
+
submethod = @submethod || 'attachment'
|
32
|
+
image_style = @image_style || :thumb
|
33
|
+
image = object.send(@method) || object.association(@method).build
|
34
|
+
attachment = image.send(submethod)
|
35
|
+
model = image.class.model_name.singular
|
19
36
|
|
20
37
|
html = Builder::XmlMarkup.new
|
21
|
-
|
22
|
-
|
23
|
-
|
38
|
+
|
39
|
+
html << form_builder.hidden_field("#{@method.singularize}_id", class: 'image-id')
|
40
|
+
|
41
|
+
html.div class: 'inline-block' do
|
42
|
+
html << h.image_tag(attachment.url(image_style), id: 'image-tag')
|
24
43
|
end
|
25
|
-
|
26
|
-
|
27
|
-
html
|
28
|
-
|
44
|
+
|
45
|
+
html.div class: 'inline-block' do
|
46
|
+
html.span class: "btn btn-default fileinput-button" do
|
47
|
+
html.span "Select file..."
|
48
|
+
html << h.file_field_tag("#{model}[#{submethod}]", class: 'image-upload',
|
49
|
+
data: {url: "/#{model.pluralize}.json", type: 'POST'})
|
50
|
+
end
|
51
|
+
|
52
|
+
# if attachment.exists?
|
53
|
+
# html << form_builder.check_box("destroy_#{@method}")
|
54
|
+
# html.text! ' Datei löschen'
|
55
|
+
# end
|
56
|
+
end
|
57
|
+
|
58
|
+
html.div id: 'upload-progress' do
|
29
59
|
end
|
60
|
+
|
61
|
+
html.script id: 'upload-progress-script', type: 'text/x-tmpl' do
|
62
|
+
html.div class: 'upload' do
|
63
|
+
html.text! "{%=o.name%}"
|
64
|
+
html.div class: 'progress' do
|
65
|
+
html.div '', class: 'progress-bar bar', style: 'width: 0%'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
30
70
|
return html.target!
|
31
71
|
end
|
32
72
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Interview
|
2
|
+
class ImageGalleryAttribute < Attribute
|
3
|
+
|
4
|
+
attr_accessor :object, :submethod, :image_style, :light_box_image_style
|
5
|
+
|
6
|
+
def render_read
|
7
|
+
submethod = @submethod || 'attachment'
|
8
|
+
image_style = @image_style || :thumb
|
9
|
+
images = value
|
10
|
+
|
11
|
+
html = Builder::XmlMarkup.new
|
12
|
+
render_gallery(html, images, submethod, image_style, @light_box_image_style)
|
13
|
+
return html.target!
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_write
|
17
|
+
object = @object || find_attribute(:object)
|
18
|
+
submethod = @submethod || 'attachment'
|
19
|
+
image_style = @image_style || :thumb
|
20
|
+
images = object.send @method
|
21
|
+
model = images.klass.model_name.singular
|
22
|
+
|
23
|
+
html = Builder::XmlMarkup.new
|
24
|
+
html.div class: 'image-upload-group' do
|
25
|
+
|
26
|
+
html << form_builder.hidden_field("#{@method.singularize}_ids", class: 'image-ids')
|
27
|
+
|
28
|
+
render_gallery(html, images, submethod, image_style, @light_box_image_style)
|
29
|
+
|
30
|
+
light_box_image_url = @light_box_image_style ? "#{@light_box_image_style}_url" : 'url'
|
31
|
+
html.script id: 'image-thumb-script', type: 'text/x-tmpl' do
|
32
|
+
html.a href: "{%=o.#{light_box_image_url}%}", class: 'img-link' do
|
33
|
+
html.img class: 'img-thumb', src: "{%=o.thumb_url%}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
html.div class: "clearfix" do
|
38
|
+
html.span class: "btn btn-default fileinput-button" do
|
39
|
+
html.span "Bilder hinzufügen" # todo
|
40
|
+
html << h.file_field_tag("#{model}[#{submethod}]", class: 'multiple-image-upload', multiple: true,
|
41
|
+
data: {url: "/#{model.pluralize}.json", type: 'POST'})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
html.div class: 'upload-progress' do
|
46
|
+
end
|
47
|
+
|
48
|
+
html.script id: 'upload-progress-script', type: 'text/x-tmpl' do
|
49
|
+
html.div class: 'upload' do
|
50
|
+
html.text! "{%=o.name%}"
|
51
|
+
html.div class: 'progress' do
|
52
|
+
html.div '', class: 'progress-bar bar', style: 'width: 0%'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
return html.target!
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def render_gallery(html, images, submethod, image_style, light_box_image_style)
|
64
|
+
html.div class: 'image-gallery' do
|
65
|
+
images.each do |image|
|
66
|
+
html.a href: image.send(submethod).url(light_box_image_style), class: 'img-link' do
|
67
|
+
html << h.image_tag(image.send(submethod).url(image_style), class: 'img-thumb')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|