interview 0.0.8 → 0.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1f72fac32d421925cb9de553456f7d05725c4307
4
- data.tar.gz: f1fdabaee5c509642c1b927fa8ac45d757d71415
3
+ metadata.gz: a79c351a953b407088c70c6686535f16980de03e
4
+ data.tar.gz: 2715694c6c5444764247942612506e19921b4390
5
5
  SHA512:
6
- metadata.gz: a2a38a6cafd9890b5cf2d4b4aae750c6b7c8207d7cbaec77a8bf71d6d7d9986f2a6dd3505bfcb8cf260a2c900970eff8308e71a6fbd435020c9bb36881ea44a3
7
- data.tar.gz: 18de1347ac17165a494057db3c5ac79c03168508ba29fa1f7b69b3d9f89703f8bab73a18d1eec961415771a2a05c18a9b3e04f643b6e74e05d60edf3a26aec78
6
+ metadata.gz: e12ba218332bfac951c2d76f15262cd50b1e1f7f48f4299955441b6aefa3912e49562cfe20997ad688b86d8ed25f24bee13fa0062cc1c4bd131380695e31dd2f
7
+ data.tar.gz: 671e31446ed9a9843030ddb389671ab48aa842e31f2281c02585890a3c01e49576177f432439a57262a1c604d10da1029f9bcbfbd134a9bdf2732e85a40d4e87
@@ -18,7 +18,7 @@
18
18
  //= require jquery.ui.sortable
19
19
  //= require jquery.ui.effect-highlight
20
20
  //= require jquery-fileupload/basic
21
- //= require jquery-fileupload/vendor/tmpl
21
+ //= require jquery-tmpl
22
22
  //= require interview
23
23
  //= require_tree .
24
24
  //= require turbolinks
@@ -123,4 +123,16 @@ $nav-stacked-link-padding-level2: 5px 15px 5px 45px !default;
123
123
  vertical-align: middle;
124
124
  margin-right: 5px;
125
125
  margin-bottom: 5px;
126
+ }
127
+
128
+ .nested_form_container {
129
+ margin: 15px 0px;
130
+ }
131
+
132
+ .nested_form {
133
+ margin-top: 15px;
134
+ }
135
+
136
+ .progress-bar {
137
+ height: 20px;
126
138
  }
@@ -76,46 +76,44 @@ jQuery ->
76
76
  $($(this).data('target')).collapse('toggle')
77
77
 
78
78
  $('.img-link').click (e) ->
79
- links = $('.img-link')
79
+ e.preventDefault()
80
+ links = $(this).closest('.image-gallery').find('.img-link')
80
81
  target = event.target || event.srcElement
81
82
  link = if target.src then target.parentNode else target
82
83
  options = { index: link, event: e }
83
84
  blueimp.Gallery(links, options)
84
85
 
85
- $('.image-upload').fileupload
86
+ $('.upload_image').fileupload
86
87
  add: (e, data) ->
87
88
  types = /(\.|\/)(gif|jpe?g|png|mov|mpeg|mpeg4|avi)$/i
88
89
  file = data.files[0]
89
90
  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')
91
+ $(this).closest('.image_attribute_container').find('.progress').collapse('show')
92
+ $("input[name='_method']").attr('name', '__method')
94
93
  data.submit()
95
- $("input[name='method']").attr('name', '_method')
94
+ $("input[name='__method']").attr('name', '_method')
96
95
  else
97
96
  alert("#{file.name} is not a gif, jpg or png image file")
98
97
  progress: (e, data) ->
99
- if data.context
100
- progress = parseInt(data.loaded / data.total * 100, 10)
101
- data.context.find('.bar').css('width', progress + '%')
98
+ progress = parseInt(data.loaded / data.total * 100, 10)
99
+ $(this).closest('.image_attribute_container').find('.bar').css('width', progress + '%')
102
100
  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
101
+ $(this).closest('.image_attribute_container').find('.upload_buffer_id').attr('value', data.result.id)
102
+ $(this).closest('.image_attribute_container').find('.image').attr('src', data.result.thumb_url)
103
+
104
+ $('.nested_form_add_images').fileupload
109
105
  add: (e, data) ->
110
106
  types = /(\.|\/)(gif|jpe?g|png|mov|mpeg|mpeg4|avi)$/i
111
107
  file = data.files[0]
112
108
  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')
109
+ tmpl_data = { index: new Date().getTime() }
110
+ data.context = $(this).closest('.nested_form_container').find('.nested_form_script').tmpl(tmpl_data)
111
+ $(this).closest('.nested_form_container').append(data.context)
112
+ data.context.find('.progress').collapse('show')
113
+ bind_remove_links()
114
+ $("input[name='_method']").attr('name', 'x_method')
117
115
  data.submit()
118
- $("input[name='method']").attr('name', '_method')
116
+ $("input[name='x_method']").attr('name', '_method')
119
117
  else
120
118
  alert("#{file.name} is not a gif, jpg or png image file")
121
119
  progress: (e, data) ->
@@ -123,8 +121,5 @@ jQuery ->
123
121
  progress = parseInt(data.loaded / data.total * 100, 10)
124
122
  data.context.find('.bar').css('width', progress + '%')
125
123
  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))
124
+ data.context.find('.upload_buffer_id').attr('value', data.result.id)
125
+ data.context.find('.image').attr('src', data.result.thumb_url)
@@ -1,12 +1,13 @@
1
1
  module Interview
2
2
  class Attribute < Control
3
3
 
4
- attr_accessor :method, :caption, :style, :link, :nil_value, :hide_caption, :hide_tooltip,
5
- :only_for, :align, :on_changed, :html_class, :surrounding_tag
4
+ attr_accessor :method, :caption, :style, :link, :nil_value, :hide_caption, :caption_as_placeholder,
5
+ :hide_tooltip, :only_for, :align, :on_changed, :html_class, :surrounding_tag
6
6
 
7
7
  def initialize(params={})
8
- @html_class = []
9
8
  super
9
+ @html_class = []
10
+ @html_class << params[:html_class] if params[:html_class]
10
11
  end
11
12
 
12
13
  def value
@@ -49,7 +50,9 @@ module Interview
49
50
  end
50
51
 
51
52
  def render_write
52
- return form_builder.text_field @method, class: 'form-control'
53
+ opts = {class: 'form-control'}
54
+ opts[:placeholder] = caption if @caption_as_placeholder
55
+ return form_builder.text_field @method, opts
53
56
  end
54
57
 
55
58
  protected
@@ -82,7 +85,7 @@ module Interview
82
85
  html = Builder::XmlMarkup.new(indent: 2)
83
86
  html.div class: 'form-group' do
84
87
 
85
- html.div class: 'col-xs-3' if @hide_caption and align == 'horizontal'
88
+ html.div class: 'col-xs-3' if (@hide_caption or @caption_as_placeholder) and align == 'horizontal'
86
89
  render_form_label(html)
87
90
 
88
91
  if align == 'horizontal'
@@ -101,7 +104,7 @@ module Interview
101
104
 
102
105
  def render_form_label(html)
103
106
  align = @align || find_attribute(:align)
104
- html_opts = if @hide_caption or align == 'inline'
107
+ html_opts = if @hide_caption or @caption_as_placeholder or align == 'inline'
105
108
  { class: 'sr-only' }
106
109
  elsif align == 'horizontal'
107
110
  { class: 'col-xs-3 control-label' }
@@ -0,0 +1,29 @@
1
+ module Interview
2
+ class Button < Control
3
+ include HasControls
4
+
5
+ attr_accessor :caption, :name, :style, :submit
6
+ attr_reader :html_class
7
+
8
+ def initialize(params={})
9
+ @html_class = []
10
+ super
11
+ end
12
+
13
+ def render
14
+ html_class = @html_class
15
+ if @style.to_s == 'primary'
16
+ html_class << 'btn btn-primary'
17
+ else
18
+ html_class << 'btn btn-default'
19
+ end
20
+
21
+ if @submit
22
+ h.submit_tag @caption, name: @name, class: @html_class.join(' ')
23
+ else
24
+ h.button_tag @caption, name: @name, class: @html_class.join(' ')
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -6,10 +6,21 @@ module Interview
6
6
 
7
7
  def render
8
8
  html = Builder::XmlMarkup.new
9
+ if @caption
10
+ link = Interview::Link.new(caption: @caption)
11
+ controls = @controls
12
+ else
13
+ link = @controls.first
14
+ controls = @controls[1..-1]
15
+ end
16
+ link.url = '#'
17
+ link.html_class << 'collapse_link'
18
+ link.html_data[:toggle] = 'collapse'
9
19
  new_id = Time.now.to_f.to_s.delete('.')
10
- html << h.link_to(@caption, '#', class: 'collapse_link', data: { toggle: 'collapse', target: "##{new_id}" })
20
+ link.html_data[:target] = "##{new_id}"
21
+ html << link.render
11
22
  html.div id: new_id, class: 'panel-collapse collapse' do
12
- @controls.each do |control|
23
+ controls.each do |control|
13
24
  html << control.render
14
25
  end
15
26
  end
@@ -2,7 +2,7 @@ module Interview
2
2
  class Dropdown < Control
3
3
  include HasControls
4
4
 
5
- attr_accessor :image, :caption, :style, :html_class
5
+ attr_accessor :image, :caption, :style, :html_class, :container_tag
6
6
 
7
7
  def initialize(params={})
8
8
  @html_class = []
@@ -10,10 +10,11 @@ module Interview
10
10
  end
11
11
 
12
12
  def render
13
+ container_tag = @container_tag || 'div'
13
14
  html = Builder::XmlMarkup.new
14
15
  html_class = @html_class.dup
15
16
  html_class << 'dropdown'
16
- html.div class: html_class.join(' ') do
17
+ html.tag! container_tag, class: html_class.join(' ') do
17
18
  html_class = 'dropdown-toggle'
18
19
  html_class += ' btn btn-default' if @style == 'button'
19
20
  html.a class: html_class, href: '#', :'data-toggle' => 'dropdown' do
@@ -2,7 +2,7 @@ module Interview
2
2
  class Form < Control
3
3
  include HasControls
4
4
 
5
- attr_accessor :skip_submit, :multi_create, :align, :redirect_to
5
+ attr_accessor :skip_submit, :submit_label, :multi_create, :align, :redirect_to
6
6
  attr_reader :form_builder
7
7
 
8
8
  def render
@@ -41,7 +41,7 @@ module Interview
41
41
 
42
42
  def render_submit(html)
43
43
  if not @skip_submit
44
- html << form_builder.submit(class: 'btn btn-primary')
44
+ html << form_builder.submit(@submit_label, class: 'btn btn-primary')
45
45
  if @multi_create || find_attribute(:multi_create)
46
46
  html.text! ' '
47
47
  html << h.check_box_tag('new_record', '1', true)
@@ -9,65 +9,94 @@ module Interview
9
9
  attr_accessor :object, :submethod, :image_style, :hide_if_not_exists
10
10
 
11
11
  def render_read
12
- submethod = @submethod || 'attachment'
13
12
  image_style = @image_style || :thumb
14
- object = @object || find_attribute(:object)
15
- image = value || object.association(@method).build
16
13
 
17
- attachment = image.send(submethod)
18
- return '' if not attachment.exists? and @hide_if_not_exists
14
+ return '' if value.nil? and @hide_if_not_exists
19
15
 
20
16
  html = Builder::XmlMarkup.new
21
17
  opts = {class: "image_#{image_style}"}
22
18
  opts[:class] += ' ' + @html_class.join(' ') unless @html_class.empty? or @surrounding_tag
23
19
  html.div opts do
24
- html << h.image_tag(attachment.url(image_style), class: 'img-responsive')
20
+ if value.nil?
21
+ html << h.image_tag('missing_thumb.png', class: 'image img-responsive')
22
+ else
23
+ html << h.image_tag(value.url(image_style), class: 'image img-responsive')
24
+ end
25
25
  end
26
26
  return html.target!
27
27
  end
28
28
 
29
29
  def render_write
30
- object = @object || find_attribute(:object)
31
- submethod = @submethod || 'attachment'
32
30
  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
36
31
 
37
32
  html = Builder::XmlMarkup.new
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')
43
- end
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'})
33
+ html.div class: 'image_attribute_container' do
34
+ unless value.nil? and @hide_if_not_exists
35
+ html.div class: 'inline-block' do
36
+ html << h.image_tag(value.url(image_style), class: 'image img-responsive')
37
+ end
50
38
  end
51
39
 
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
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%'
40
+ html.div class: 'inline-block' do
41
+ html.div class: "clearfix" do
42
+ html.span class: "btn btn-default fileinput-button" do
43
+ html.span "Bild hochladen" # todo
44
+ html << h.file_field_tag("upload_buffer[attachment]", class: 'upload_image',
45
+ data: {url: "/upload_buffers.json", type: 'POST'})
46
+ end
66
47
  end
48
+ html << Interview::ProgressBar.new(hidden: true).render
49
+ html << form_builder.hidden_field(:upload_buffer_id, class: 'upload_buffer_id')
50
+
51
+ # if attachment.exists?
52
+ # html << form_builder.check_box("destroy_#{@method}")
53
+ # html.text! ' Datei löschen'
54
+ # end
67
55
  end
68
56
  end
69
-
70
57
  return html.target!
58
+
59
+ # object = @object || find_attribute(:object)
60
+ # submethod = @submethod || 'attachment'
61
+ # image_style = @image_style || :thumb
62
+ # image = object.send(@method) || object.association(@method).build
63
+ # attachment = image.send(submethod)
64
+ # model = image.class.model_name.singular
65
+ #
66
+ # html = Builder::XmlMarkup.new
67
+ #
68
+ # html << form_builder.hidden_field("#{@method.singularize}_id", class: 'image-id')
69
+ #
70
+ # html.div class: 'inline-block' do
71
+ # html << h.image_tag(attachment.url(image_style), id: 'image-tag')
72
+ # end
73
+ #
74
+ # html.div class: 'inline-block' do
75
+ # html.span class: "btn btn-default fileinput-button" do
76
+ # html.span "Select file..."
77
+ # html << h.file_field_tag("#{model}[#{submethod}]", class: 'image-upload',
78
+ # data: {url: "/#{model.pluralize}.json", type: 'POST'})
79
+ # end
80
+ #
81
+ # # if attachment.exists?
82
+ # # html << form_builder.check_box("destroy_#{@method}")
83
+ # # html.text! ' Datei löschen'
84
+ # # end
85
+ # end
86
+ #
87
+ # html.div id: 'upload-progress' do
88
+ # end
89
+ #
90
+ # html.script id: 'upload-progress-script', type: 'text/x-tmpl' do
91
+ # html.div class: 'upload' do
92
+ # html.text! "{%=o.name%}"
93
+ # html.div class: 'progress' do
94
+ # html.div '', class: 'progress-bar bar', style: 'width: 0%'
95
+ # end
96
+ # end
97
+ # end
98
+ #
99
+ # return html.target!
71
100
  end
72
101
 
73
102
  end
@@ -25,14 +25,14 @@ module Interview
25
25
 
26
26
  html << form_builder.hidden_field("#{@method.singularize}_ids", class: 'image-ids')
27
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
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
36
 
37
37
  html.div class: "clearfix" do
38
38
  html.span class: "btn btn-default fileinput-button" do
@@ -46,10 +46,15 @@ module Interview
46
46
  end
47
47
 
48
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%'
49
+ html.div do
50
+ html.div class: 'inline-block' do
51
+ html.img class: 'img-thumb', src: '/assets/missing_180x180.png'
52
+ end
53
+ html.div class: 'inline-block' do
54
+ html.text! "{%=o.name%}"
55
+ html.div class: 'progress' do
56
+ html.div '', class: 'progress-bar bar', style: 'width: 0%'
57
+ end
53
58
  end
54
59
  end
55
60
  end
@@ -63,7 +68,7 @@ module Interview
63
68
  def render_gallery(html, images, submethod, image_style, light_box_image_style)
64
69
  html.div class: 'image-gallery' do
65
70
  images.each do |image|
66
- html.a href: image.send(submethod).url(light_box_image_style), class: 'img-link' do
71
+ html.a href: image.send(submethod).url(light_box_image_style), class: 'img-link', title: image.subtitle do
67
72
  html << h.image_tag(image.send(submethod).url(image_style), class: 'img-thumb')
68
73
  end
69
74
  end
@@ -3,11 +3,13 @@ module Interview
3
3
  include HasControls
4
4
 
5
5
  attr_accessor :image, :caption, :hint, :style, :active,
6
- :url, :controller, :object, :action, :http_method, :redirect_to, :nested_resource, :trail
7
- attr_reader :url_params, :html_class
6
+ :url, :controller, :object, :action, :http_method, :redirect_to,
7
+ :nested_resource, :trail
8
+ attr_reader :url_params, :html_class, :html_data
8
9
 
9
10
  def initialize(params={})
10
11
  @html_class = []
12
+ @html_data = {}
11
13
  @url_params = {}
12
14
  super
13
15
  end
@@ -111,6 +113,7 @@ module Interview
111
113
  def render_link(url, html_class=[], html_options={})
112
114
  class_string = html_class.join(' ')
113
115
  html_options[:class] = class_string unless html_class.empty?
116
+ html_options[:data] = @html_data unless @html_data.empty?
114
117
  return h.link_to(url, html_options) do
115
118
  html = Builder::XmlMarkup.new
116
119
  if @controls.empty?
@@ -6,11 +6,11 @@ module Interview
6
6
 
7
7
  def render
8
8
  image_size = @image_size || :thumb
9
- object = find_attribute! :object
9
+ object = find_attribute :object
10
10
  @object = object
11
11
  html = Builder::XmlMarkup.new(indent: 2)
12
12
  html.div class: 'media' do
13
- @controls.first.html_class << 'pull-left'
13
+ @controls[0].html_class << 'pull-left' if @controls[0].respond_to? 'html_class'
14
14
  html << @controls.first.render
15
15
  html.div class: 'media-body' do
16
16
  @controls[1].html_class << 'media-heading' if @controls[1].respond_to? 'html_class'
@@ -2,23 +2,35 @@ module Interview
2
2
  class NestedForm < Control
3
3
  include HasControls
4
4
 
5
- attr_accessor :polymorphic, :align # todo: align einbauen
5
+ attr_accessor :polymorphic, :align, :image_based # todo: align einbauen
6
6
  attr_reader :form_builder, :object
7
7
 
8
8
  def render
9
9
  assoc_form_builder = find_attribute! :form_builder
10
10
  assoc_method = find_attribute! :assoc_method
11
- objects = find_attribute! :objects
12
11
 
13
12
  html = Builder::XmlMarkup.new
14
- html.div class: 'nested_forms' do
15
- html << assoc_form_builder.fields_for(assoc_method.to_sym, objects) do |form_builder|
13
+ html.div class: 'nested_form_container' do
14
+ if @image_based
15
+ html << Interview::NestedFormAddImages.new.render
16
+ end
17
+ html << assoc_form_builder.fields_for(assoc_method.to_sym) do |form_builder|
16
18
  if @polymorphic
17
19
  render_polymorphic_nested_form(form_builder)
18
20
  else
19
21
  render_nested_form(form_builder)
20
22
  end
21
23
  end
24
+ html.script class: 'nested_form_script', type: 'text/x-tmpl' do
25
+ new_object = assoc_form_builder.object.association(assoc_method.to_sym).build # todo: polymorphic add link
26
+ html << assoc_form_builder.fields_for(assoc_method.to_sym, new_object, :child_index => "${index}") do |form_builder|
27
+ if @polymorphic
28
+ render_polymorphic_nested_form(form_builder)
29
+ else
30
+ render_nested_form(form_builder)
31
+ end
32
+ end
33
+ end
22
34
  end
23
35
  return html.target!
24
36
  end
@@ -33,6 +45,9 @@ module Interview
33
45
  end
34
46
  html << form_builder.hidden_field(:id)
35
47
  html << form_builder.hidden_field(:_destroy, class: 'nested_form_destroy')
48
+ if @image_based
49
+ html << form_builder.hidden_field(:upload_buffer_id, class: 'upload_buffer_id')
50
+ end
36
51
  end
37
52
  html.target!.html_safe
38
53
  end
@@ -0,0 +1,33 @@
1
+ module Interview
2
+ class NestedFormAddImages < Control
3
+
4
+ attr_accessor :style
5
+
6
+ def render
7
+ if @style and @style.to_sym == :horizontal_form
8
+ html = Builder::XmlMarkup.new # todo: in eigenes Objekt auslagern?
9
+ html.div class: 'row' do
10
+ html.div class: 'col-xs-9 col-xs-offset-3' do
11
+ html << render_link
12
+ end
13
+ end
14
+ return html.target!
15
+ else
16
+ return render_link
17
+ end
18
+ end
19
+
20
+ def render_link
21
+ html = Builder::XmlMarkup.new
22
+ html.div class: "clearfix" do
23
+ html.span class: "btn btn-default fileinput-button" do
24
+ html.span "Bilder hinzufügen" # todo
25
+ html << h.file_field_tag("upload_buffer[attachment]", class: 'nested_form_add_images',
26
+ multiple: true, data: {url: "/upload_buffers.json", type: 'POST'})
27
+ end
28
+ end
29
+ return html.target!
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ module Interview
2
+ class ProgressBar < Control
3
+
4
+ attr_accessor :hidden, :html_class
5
+
6
+ def initialize(params={})
7
+ super
8
+ @html_class = []
9
+ @html_class << params[:html_class] if params[:html_class]
10
+ end
11
+
12
+ def render
13
+ html_class = @html_class
14
+ html = Builder::XmlMarkup.new
15
+ opts = { class: "progress" }
16
+ opts[:class] += " collapse" if @hidden
17
+ opts[:class] += ' ' + @html_class.join(' ') unless @html_class.empty?
18
+ html.div opts do
19
+ html.div '', class: 'progress-bar bar', style: 'width: 0%'
20
+ end
21
+ return html.target!
22
+ end
23
+
24
+ end
25
+ end
@@ -28,13 +28,13 @@ module Interview
28
28
  def render_text(html)
29
29
  if @bold
30
30
  html.b do
31
- html.text! @text
31
+ html << @text # todo: besser .text! statt << ?
32
32
  @controls.each do |control|
33
33
  html << control.render
34
34
  end
35
35
  end
36
36
  else
37
- html.text! @text if @text
37
+ html << @text if @text # todo: besser .text! statt << ?
38
38
  @controls.each do |control|
39
39
  html << control.render
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module Interview
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
data/lib/interview.rb CHANGED
@@ -52,9 +52,12 @@ require "interview/form"
52
52
  require "interview/nested_form"
53
53
  require "interview/nested_form_remove_link"
54
54
  require "interview/nested_form_add_link"
55
+ require "interview/nested_form_add_images"
55
56
  require "interview/form_errors"
56
57
  require "interview/polymorphic_add_link"
57
58
  require "interview/search_form"
59
+ require "interview/button"
60
+ require "interview/progress_bar"
58
61
 
59
62
  require "interview/association_methods"
60
63
 
@@ -160,60 +163,68 @@ module ActiveRecord
160
163
  return [sql] + values
161
164
  end
162
165
 
163
- def self.string_filter_to_sql(attr, filter, not_filter=false)
166
+ def self.string_filter_to_sql(attr, filter, negation=false)
167
+ negation = negation ? 'NOT ' : ''
164
168
  if filter.respond_to?(:each)
165
- sql = "#{attr} in (?)"
169
+ return self.value_combination_to_sql(attr, filter, :string)
166
170
  else
167
- sql = "#{attr} = ?"
171
+ sql = "#{negation}#{attr} = ?"
168
172
  end
169
173
  return [sql, filter]
170
174
  end
171
175
 
172
- def self.number_filter_to_sql(attr, filter, not_filter=false)
176
+ def self.number_filter_to_sql(attr, filter, negation=false)
177
+ negation = negation ? 'NOT ' : ''
173
178
  if filter.respond_to?(:each)
174
179
  return self.value_combination_to_sql(attr, filter, :number)
175
180
  elsif filter.is_a? String
176
181
  unless result = filter.match(/^([!<>=]*)(\d+\.?\d*)$/)
177
182
  raise "invalid number filter: '#{filter}'"
178
183
  end
179
- operator = result[1] != '' ? result[1] : '='
184
+ connective = result[1].blank? ? '=' : result[1]
180
185
  value = result[2].include?('.') ? result[2].to_f : result[2].to_i
181
- sql = "#{attr} #{operator} ?"
186
+ sql = "#{negation}#{attr} #{connective} ?"
182
187
  values = [value]
183
188
  else
184
- sql = "#{attr} = ?"
189
+ sql = "#{negation}#{attr} = ?"
185
190
  values = [filter]
186
191
  end
187
192
  return [sql] + values
188
193
  end
189
194
 
190
- def self.date_filter_to_sql(attr, filter, not_filter=false)
195
+ def self.date_filter_to_sql(attr, filter, negation=false)
196
+ negation = negation ? 'NOT ' : ''
191
197
  if filter.respond_to?(:each)
192
- if filter.size != 2
198
+ if filter.size != 2 # todo: value_combination einbauen
193
199
  raise "invalid date filter: #{filter.inspect} 2 elements expected, #{filter.size} given"
194
200
  end
195
- sql = "#{attr} BETWEEN ? AND ?"
201
+ sql = "#{negation}#{attr} BETWEEN ? AND ?"
196
202
  values = filter
197
203
  else
198
- sql = "#{attr} = ?"
204
+ sql = "#{negation}#{attr} = ?"
199
205
  values = [filter]
200
206
  end
201
207
  return [sql] + values
202
208
  end
203
209
 
204
- def self.boolean_filter_to_sql(attr, filter, not_filter=false)
205
- return ["#{attr} = ?", filter]
210
+ def self.boolean_filter_to_sql(attr, filter, negation=false)
211
+ if filter.respond_to?(:each)
212
+ return self.value_combination_to_sql(attr, filter, :boolean)
213
+ end
214
+ negation = negation ? 'NOT ' : ''
215
+ return ["#{negation}#{attr} = ?", filter]
206
216
  end
207
217
 
208
- def self.assoc_filter_to_sql(attr, filter, not_filter=false)
218
+ def self.assoc_filter_to_sql(attr, filter, negation=false)
209
219
  if filter.respond_to?(:each)
210
220
  return self.value_combination_to_sql(attr, filter, :assoc)
211
221
  end
222
+ negation = negation ? 'NOT ' : ''
212
223
  assoc = self.reflect_on_association(attr)
213
224
  if assoc.macro == :has_and_belongs_to_many
214
225
  number_filter = self.number_filter_to_sql(assoc.association_foreign_key, filter)
215
226
  values = number_filter[1..-1]
216
- sql = "id #{ not_filter ? 'NOT ' : ''}IN (SELECT #{assoc.foreign_key} FROM #{assoc.join_table} WHERE #{number_filter.first})"
227
+ sql = "id #{negation}IN (SELECT #{assoc.foreign_key} FROM #{assoc.join_table} WHERE #{number_filter.first})"
217
228
  end # todo: erweitern
218
229
  return [sql] + values
219
230
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interview
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jannes Köhler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-20 00:00:00.000000000 Z
11
+ date: 2014-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -126,6 +126,7 @@ files:
126
126
  - lib/interview/attribute.rb
127
127
  - lib/interview/boolean_attribute.rb
128
128
  - lib/interview/breadcrumbs.rb
129
+ - lib/interview/button.rb
129
130
  - lib/interview/collapse_container.rb
130
131
  - lib/interview/condition_container.rb
131
132
  - lib/interview/container_attribute.rb
@@ -153,12 +154,14 @@ files:
153
154
  - lib/interview/navigation_item.rb
154
155
  - lib/interview/navigation_item_old.rb
155
156
  - lib/interview/nested_form.rb
157
+ - lib/interview/nested_form_add_images.rb
156
158
  - lib/interview/nested_form_add_link.rb
157
159
  - lib/interview/nested_form_remove_link.rb
158
160
  - lib/interview/object_context.rb
159
161
  - lib/interview/option_attribute.rb
160
162
  - lib/interview/panel.rb
161
163
  - lib/interview/polymorphic_add_link.rb
164
+ - lib/interview/progress_bar.rb
162
165
  - lib/interview/search_form.rb
163
166
  - lib/interview/space.rb
164
167
  - lib/interview/string_attribute.rb