dynamic_scaffold 0.3.1 → 0.4.0

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
  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