dynamic_scaffold 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27b88a53221d6cd3762a14df6a327717d1633c7ad6fd15571149d3503b08c2f9
4
- data.tar.gz: 2df989a2e51776a426ab9d464d13b879c728e097fdb978cbc3296c16c56e10ef
3
+ metadata.gz: c40fe45194a04923ed48fbb0d6efb18167fba2cd0af2220d23981ec0128fca8b
4
+ data.tar.gz: 3ecda8f9b0391686716eb10c151bdfa688b7b84e2b2ca48e8cbc02d99478205c
5
5
  SHA512:
6
- metadata.gz: 01e25f9bc9f91d0b14079503acb5b1c15efe1a6ef48a1067548ac19a109a717c0c0c24f843110f481b7baba0a8a140b1a57783e483a2a710328227dcece20d40
7
- data.tar.gz: 9ead2dc6192bd2847c4b0c96ca6e4f45fa7aec13fed3b8fdcb0a371b3da4c716c16b611d7bb7bfee7f05c3683089afa7229ae3f38ace3dd917c0ade22458d418
6
+ metadata.gz: a4851bb43b47f7d4d181d4f49e21ebfc2268df8cd29b5d1477007f992be0c0d5d0b1394621fc8c71f8b7e58530b5b64f639dd3b3ccd21fd6606ef6015c8800db
7
+ data.tar.gz: ff879c9a5f4fae140aeec1c2a2212ad705adb8bf7f176375406c5dfc8f9c137195847329acc48ca36dc43bff4a3f0f8348e5cc13b47d54597273e7862a3d490d
data/README.md CHANGED
@@ -227,6 +227,14 @@ class ShopController < ApplicationController
227
227
  config.form.item(:collection_check_boxes, :state_ids, State.all, :id, :name)
228
228
  config.form.item(:collection_radio_buttons, :status, Shop.statuses.map{|k, _v| [k, k.titleize]}, :first, :last)
229
229
 
230
+ # You can add an image uploader with preview to the form. The save and remove part to the model corresponds to [carrierwave](https://github.com/carrierwaveuploader/carrierwave).
231
+ # In the example below, you need to mount the carrierwave uploader on the thumb column of the model.
232
+ #
233
+ # class Shop < ApplicationRecord
234
+ # mount_uploader :thumb, ShopThumbUploader
235
+ #
236
+ config.form.item(:carrierwave_image, :thumb, preview_max_size: {width: '300px', height: '300px'})
237
+
230
238
  # If you want to display more free form field, use block.
231
239
  # The block is executed in the context of view, so you can call the method of view.
232
240
  config.form.item :block, :free do |form, field|
@@ -506,5 +514,9 @@ end
506
514
  * We use rspec for test.
507
515
  * Check code with [rubocop](https://github.com/bbatsov/rubocop).
508
516
 
517
+ ### Development hints.
518
+
519
+ Please support both Bootstrap 3/4. You can change CSS to Bootstrap3 by registering `bootstrap=3` in cookie in the sample page.
520
+
509
521
  ## License
510
522
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,4 +1,5 @@
1
1
  //= require dynamic_scaffold/common
2
2
  //= require dynamic_scaffold/delete
3
3
  //= require dynamic_scaffold/pagination
4
- //= require dynamic_scaffold/sorter
4
+ //= require dynamic_scaffold/sorter
5
+ //= require dynamic_scaffold/image
@@ -0,0 +1,37 @@
1
+ document.addEventListener('dynamic_scaffold:load', function (){
2
+ const inputs = document.querySelectorAll('.dynamicScaffoldJs-image')
3
+ Array.prototype.forEach.call(inputs, function(input){
4
+ // initialize
5
+ const wrapper = input.closest('.dynamicScaffoldJs-image-wrapper')
6
+ const preview = wrapper.querySelector('.dynamicScaffoldJs-image-preview')
7
+ const img = preview.querySelector('img')
8
+
9
+ // hide on non image
10
+ if(!img.getAttribute('src')){
11
+ preview.style.display = 'none'
12
+ }
13
+
14
+ // delete event
15
+ const button = preview.querySelector('.dynamicScaffoldJs-image-remove')
16
+ const flag = wrapper.querySelector('.dynamicScaffoldJs-image-remove-flag')
17
+ button.addEventListener('click', function(e){
18
+ preview.style.display = 'none'
19
+ flag.disabled = false
20
+ input.value = ''
21
+ })
22
+
23
+ // change event
24
+ input.addEventListener('change', function(e){
25
+ const reader = new FileReader();
26
+ reader.onload = function (e) {
27
+ img.src = e.target.result
28
+ preview.style.display = 'block'
29
+ flag.disabled = true
30
+ }
31
+
32
+ if(input.files.length){
33
+ reader.readAsDataURL(input.files[0])
34
+ }
35
+ })
36
+ })
37
+ })
@@ -8,14 +8,20 @@ document.addEventListener('dynamic_scaffold:load', function(){
8
8
  sourceRect = source.getBoundingClientRect()
9
9
  targetRect = target.getBoundingClientRect()
10
10
 
11
- //Calculate the duration according to the moving distance.
12
- const distance = targetRect.top - sourceRect.top
11
+
12
+ // Find the distance between two points and calculate the animation duration.
13
13
  const durationBase = 200
14
+ const distance = Math.sqrt(
15
+ Math.pow(targetRect.left - sourceRect.left, 2 ) + Math.pow( targetRect.top - sourceRect.top, 2 )
16
+ )
14
17
  const durationFactor = Math.abs(distance) * 0.03
15
18
  const duration = Math.min(durationBase + durationFactor, 600)
16
-
17
19
  source.style.transition = 'all ' + duration + 'ms cubic-bezier(1.0, 0, 0.25, 1.0)'
18
- source.style.transform = 'translateY(' + distance + 'px)'
20
+
21
+ //Calculate the duration according to the moving distance.
22
+ const y = targetRect.top - sourceRect.top
23
+ const x = targetRect.left - sourceRect.left
24
+ source.style.transform = 'translate(' + x + 'px, ' + y + 'px)'
19
25
  }))
20
26
  }
21
27
 
@@ -4,6 +4,7 @@
4
4
  $dynamic_scaffold_primary: #007bff !default;
5
5
  $dynamic_scaffold_secondary: #868e96 !default;
6
6
  $dynamic_scaffold_warning: #ffc107 !default;
7
+ $dynamic_scaffold_danger: #dc3545 !default;
7
8
 
8
9
  .btn-outline-primary, .btn-outline-secondary, .btn-outline-warning{
9
10
  background-color: #fff;
@@ -29,7 +30,11 @@ $dynamic_scaffold_warning: #ffc107 !default;
29
30
  fill: $dynamic_scaffold_warning;
30
31
  }
31
32
 
32
- .btn-outline-warning:hover{
33
+ .btn-outline-danger path{
34
+ fill: $dynamic_scaffold_danger;
35
+ }
36
+
37
+ .btn-outline-warning:hover, .btn-outline-danger:hover{
33
38
  path{
34
39
  fill: #fff;
35
40
  }
@@ -49,10 +49,12 @@
49
49
  clear: both;
50
50
  }
51
51
 
52
- ul.resplist {
52
+ .resplist {
53
53
  list-style: none;
54
54
  padding: 0;
55
55
  border-collapse: separate;
56
+ display: flex;
57
+ flex-wrap: wrap;
56
58
  }
57
59
 
58
60
  .resplist-striped .resplist-row:nth-child(odd) {
@@ -114,6 +116,7 @@ ul.resplist {
114
116
  background-color: #fff;
115
117
  border-top: 1px solid #dddddd;
116
118
  padding: 0;
119
+ width: 100%;
117
120
  }
118
121
 
119
122
  .resplist-item-xs {
@@ -26,6 +26,22 @@
26
26
  <%end%>
27
27
  </div>
28
28
  <%end%>
29
+ <% elsif elem.type? :carrierwave_image %>
30
+ <%- image = form.object.public_send(elem.name) -%>
31
+ <div class="dynamicScaffoldJs-image-wrapper">
32
+ <div class="dynamicScaffoldJs-image-preview panel panel-default card mb-1" style="<%= elem.preview_image_style %>">
33
+ <div class="text-right panel-heading card-header">
34
+ <button type="button" class="btn btn-outline-danger btn-danger btn-sm dynamicScaffoldJs-image-remove">
35
+ <%= dynamic_scaffold_icon :times %>
36
+ </button>
37
+ </div>
38
+ <img src="<%= image.url if image.file.present? %>" alt="" class="img-responsive img-fluid">
39
+ </div>
40
+ <%= form.hidden_field "remove_#{elem.name}", value: "1", disabled:"disabled", class: 'dynamicScaffoldJs-image-remove-flag'%>
41
+ <%= elem.render(self, form, 'form-control-file dynamicScaffoldJs-image') do |attr|%>
42
+ <%= form.file_field(elem.name, attr) %>
43
+ <%end%>
44
+ </div>
29
45
  <% else %>
30
46
  <%= elem.render(self, form, class_names('form-control', {'is-invalid': @record.errors[elem.proxy_field.name].any?})) %>
31
47
  <% end %>
@@ -263,6 +263,9 @@ module DynamicScaffold
263
263
  when
264
264
  :block then
265
265
  item = Form::Item::Block.new(@config, type, *args, block)
266
+ when
267
+ :carrierwave_image then
268
+ item = Form::Item::CarrierWaveImage.new(@config, type, *args)
266
269
  else
267
270
  raise DynamicScaffold::Error::Config, "Unknown form item type #{type}"
268
271
  end
@@ -30,7 +30,10 @@ module DynamicScaffold
30
30
 
31
31
  # Get paramters for update record.
32
32
  def update_values
33
- permitting = dynamic_scaffold.form.items.map(&:strong_parameter).concat(dynamic_scaffold.form.permit_params)
33
+ permitting = dynamic_scaffold.form.items
34
+ .map(&:strong_parameter)
35
+ .concat(dynamic_scaffold.form.permit_params)
36
+ .flatten
34
37
  values = params
35
38
  .require(dynamic_scaffold.model.name.underscore)
36
39
  .permit(*permitting)
@@ -0,0 +1,31 @@
1
+ module DynamicScaffold
2
+ module Form
3
+ module Item
4
+ class CarrierWaveImage < Base
5
+ def initialize(config, type, name, options = {})
6
+ super(config, type, name, {})
7
+ @options = options
8
+ end
9
+
10
+ def preview_image_style
11
+ max_size = @options[:preview_max_size]
12
+ return '' unless max_size
13
+
14
+ ''.tap do |s|
15
+ s << "max-width: #{max_size[:width]};" if max_size[:width]
16
+ s << "max-height: #{max_size[:height]};" if max_size[:height]
17
+ end
18
+ end
19
+
20
+ def render(_view, _form, classnames = nil)
21
+ html_attributes = build_html_attributes(classnames)
22
+ yield(html_attributes)
23
+ end
24
+
25
+ def strong_parameter
26
+ [@name, "remove_#{@name}"]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -41,6 +41,8 @@ Rails.application.config.dynamic_scaffold.icons = proc do |name|
41
41
  DynamicScaffold::Fontawesome.inline_svg('angle-double-up.svg')
42
42
  when :bottom then
43
43
  DynamicScaffold::Fontawesome.inline_svg('angle-double-down.svg')
44
+ when :times then
45
+ DynamicScaffold::Fontawesome.inline_svg('times.svg')
44
46
  else
45
47
  raise DynamicScaffold::Error::InvalidIcon, "Unknown icon type #{name} specified."
46
48
  end
@@ -1,3 +1,3 @@
1
1
  module DynamicScaffold
2
- VERSION = '0.3.1'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masamoto Miyata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-22 00:00:00.000000000 Z
11
+ date: 2018-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: classnames-rails-view
@@ -226,6 +226,7 @@ files:
226
226
  - app/assets/javascripts/dynamic_scaffold.js
227
227
  - app/assets/javascripts/dynamic_scaffold/common.js
228
228
  - app/assets/javascripts/dynamic_scaffold/delete.js
229
+ - app/assets/javascripts/dynamic_scaffold/image.js
229
230
  - app/assets/javascripts/dynamic_scaffold/pagination.js
230
231
  - app/assets/javascripts/dynamic_scaffold/sorter.js
231
232
  - app/assets/stylesheets/dynamic_scaffold/bootstrap3.scss
@@ -259,6 +260,7 @@ files:
259
260
  - lib/dynamic_scaffold/error/invalid_icon.rb
260
261
  - lib/dynamic_scaffold/form/item/base.rb
261
262
  - lib/dynamic_scaffold/form/item/block.rb
263
+ - lib/dynamic_scaffold/form/item/carrier_wave_image.rb
262
264
  - lib/dynamic_scaffold/form/item/single_option.rb
263
265
  - lib/dynamic_scaffold/form/item/two_options.rb
264
266
  - lib/dynamic_scaffold/form/item/two_options_with_block.rb