dynamic_scaffold 0.10.1 → 1.0.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 +4 -4
- data/README.md +35 -7
- data/app/assets/javascripts/dynamic_scaffold.js +1 -1
- data/app/views/dynamic_scaffold/bootstrap/_form.html.erb +1 -83
- data/app/views/dynamic_scaffold/bootstrap/form/_cocoon.html.erb +10 -0
- data/app/views/dynamic_scaffold/bootstrap/form/_row.html.erb +95 -0
- data/lib/dynamic_scaffold/config.rb +8 -238
- data/lib/dynamic_scaffold/form/item/base.rb +38 -20
- data/lib/dynamic_scaffold/form/item/block.rb +1 -1
- data/lib/dynamic_scaffold/form/item/cocoon.rb +34 -0
- data/lib/dynamic_scaffold/form/item/globalize_fields.rb +2 -2
- data/lib/dynamic_scaffold/form_builder.rb +28 -58
- data/lib/dynamic_scaffold/list/item.rb +1 -2
- data/lib/dynamic_scaffold/list/pagination.rb +50 -0
- data/lib/dynamic_scaffold/list_builder.rb +92 -0
- data/lib/dynamic_scaffold/monkeypatch/action_view/helpers/form_builder.rb +65 -0
- data/lib/dynamic_scaffold/title.rb +60 -0
- data/lib/dynamic_scaffold/vars.rb +15 -0
- data/lib/dynamic_scaffold/version.rb +1 -1
- data/lib/dynamic_scaffold.rb +6 -0
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92e34ceaa702cf769f2d04c1f6abcf6424a0fe243aba09c3a47deb7cb0b34744
|
4
|
+
data.tar.gz: 8f14666cf201c3153402d97e12bc12131be4f06cc2afdbed862ccf90d992ff79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9547447542b99e5dc317381dfa2f253c26bd983f08ca0438b9fe7cd08de4643345eca7fa587f9312c0302f8743f47def9bad39e0655b0b12f41fc49e93ab50b
|
7
|
+
data.tar.gz: c2923675d8504bdf3e3c9b392a8a9d032ac0160036759ce21e6c69259b1d725004ee488266b6374cca09aa9e8a4c224cc19596d3221cf69b6656e82f478d4a9a
|
data/README.md
CHANGED
@@ -9,6 +9,7 @@ The Scaffold system which dynamically generates CRUD and sort functions.
|
|
9
9
|
* Support image upload with preview.
|
10
10
|
* Support image crop.
|
11
11
|
* Support [globalize](https://github.com/globalize/globalize) form fields.
|
12
|
+
* Support [cocoon](https://github.com/nathanvda/cocoon).
|
12
13
|
* This has the views with the Twitter Bootstrap. Support bootstrap3/4.
|
13
14
|
* Customizable and flexible.
|
14
15
|
|
@@ -181,11 +182,6 @@ class ShopController < ApplicationController
|
|
181
182
|
rec.fdate name, '%Y-%m-%d %H:%M:%S'
|
182
183
|
end
|
183
184
|
|
184
|
-
# The `label` method also accepts block.
|
185
|
-
config.list.item(:created_at, style: 'width: 180px').label 'Create Date' do |rec, name|
|
186
|
-
rec.fdate name, '%Y-%m-%d %H:%M:%S'
|
187
|
-
end
|
188
|
-
|
189
185
|
# The first argument can also be omitted, to display item that is not model attribute.
|
190
186
|
# The block is executed in the context of view, so you can call the method of view.
|
191
187
|
config.list.item do |rec|
|
@@ -216,8 +212,16 @@ class ShopController < ApplicationController
|
|
216
212
|
|
217
213
|
# Default label is I18n model attribute name.
|
218
214
|
config.form.item :text_field, :name
|
219
|
-
# You can specify `label`.
|
220
|
-
config.form.item(:text_field, :name).label
|
215
|
+
# You can specify `label`. You can specify tag attributes for the second argument.
|
216
|
+
config.form.item(:text_field, :name).label('Shop Name', class: 'h3')
|
217
|
+
# You can pass the block and customize the label tag.
|
218
|
+
config.form.item(:text_field, :name).label do |text, depth, attrs|
|
219
|
+
# This block is called in the scope of view,
|
220
|
+
# So methods and variables that can be used in view are available.
|
221
|
+
tag.div class: 'h3 mb-1' do
|
222
|
+
tag.label text
|
223
|
+
end
|
224
|
+
end
|
221
225
|
|
222
226
|
# You can set default value for new action.
|
223
227
|
config.form.item(:text_field, :name).default('Foo Bar')
|
@@ -334,6 +338,30 @@ class ShopController < ApplicationController
|
|
334
338
|
Setting the model for globalize_fields with validates is [here](https://github.com/gomo/dynamic_scaffold/wiki/Model-setting-for-globalize).
|
335
339
|
|
336
340
|
|
341
|
+
##### cocoon
|
342
|
+
|
343
|
+
We support [cocoon](https://github.com/nathanvda/cocoon).
|
344
|
+
|
345
|
+
```rb
|
346
|
+
# Build the form of related records in the block.
|
347
|
+
c.form.item(:cocoon, :shop_memos, add_text: 'Add Memo') do |form|
|
348
|
+
# This `form` is a form of the child hierarchy generated by `fields_for`.
|
349
|
+
form.item(:hidden_field, :id)
|
350
|
+
form.item(:text_field, :title)
|
351
|
+
form.item(:text_area, :body)
|
352
|
+
end.filter do |records|
|
353
|
+
# If you want to sort the related records, please process in the filter block.
|
354
|
+
|
355
|
+
# The records with empty id are first, then in descending order of id
|
356
|
+
records.partition do |rec|
|
357
|
+
rec.id.nil?
|
358
|
+
end.yield_self do |nils, others|
|
359
|
+
nils + others.sort_by {|rec| -rec.id }
|
360
|
+
end
|
361
|
+
end
|
362
|
+
```
|
363
|
+
|
364
|
+
|
337
365
|
### Sorting
|
338
366
|
|
339
367
|
You can sort records having integer column for order in the list page.
|
@@ -1,88 +1,6 @@
|
|
1
1
|
<%= form_with method: method, model: @record, url: url, local: true do |form| %>
|
2
2
|
<%-dynamic_scaffold.form.items.each do |elem|-%>
|
3
|
-
|
4
|
-
<% if !elem.label? && elem.type?(:hidden_field) %>
|
5
|
-
<%= elem.render(self, form) %>
|
6
|
-
<% else %>
|
7
|
-
<%- errors = elem.errors(@record) -%>
|
8
|
-
<div class="<%= class_names('form-group', 'has-error': errors.present?) %>">
|
9
|
-
<label><%= elem.proxy_field.label %></label>
|
10
|
-
<div class="clearfix">
|
11
|
-
<%- elem.insert(:before).each do |block| -%>
|
12
|
-
<%= self.instance_exec(@record, &block) %>
|
13
|
-
<%-end-%>
|
14
|
-
<% if elem.type? :collection_check_boxes %>
|
15
|
-
<%= elem.render(self, form) do |cb|%>
|
16
|
-
<div class="form-check checkbox">
|
17
|
-
<%= cb.label class: 'form-check-label' do%>
|
18
|
-
<%= cb.check_box class: 'form-check-input' %> <%= cb.text %>
|
19
|
-
<%end%>
|
20
|
-
</div>
|
21
|
-
<%end%>
|
22
|
-
<% elsif elem.type? :collection_radio_buttons %>
|
23
|
-
<%= elem.render(self, form) do |cb|%>
|
24
|
-
<div class="form-check radio">
|
25
|
-
<%= cb.label class: 'form-check-label' do%>
|
26
|
-
<%= cb.radio_button class: 'form-check-input' %> <%= cb.text %>
|
27
|
-
<%end%>
|
28
|
-
</div>
|
29
|
-
<%end%>
|
30
|
-
<% elsif elem.type? :carrierwave_image %>
|
31
|
-
<%- image = form.object.public_send(elem.name) -%>
|
32
|
-
<div class="js-ds-image-wrapper">
|
33
|
-
<div class="js-ds-image-preview panel panel-default card mb-1">
|
34
|
-
<% if elem.options[:removable] %>
|
35
|
-
<div class="text-right panel-heading card-header">
|
36
|
-
<button type="button" class="btn btn-outline-danger btn-danger btn-sm js-ds-image-remove">
|
37
|
-
<%= dynamic_scaffold_icon :times %>
|
38
|
-
</button>
|
39
|
-
</div>
|
40
|
-
<% end %>
|
41
|
-
<div class="panel-body card-body">
|
42
|
-
<%- if elem.cropper.present? -%>
|
43
|
-
<%= form.hidden_field "cropper_#{elem.name}", class: "js-ds-image-cropper", data:{options: elem.cropper.to_json} %>
|
44
|
-
<div class="text-right" style="height: 24px;">
|
45
|
-
<span class="js-ds-image-cropper-display badge badge-primary"></span>
|
46
|
-
</div>
|
47
|
-
<%- end -%>
|
48
|
-
<div style="overflow: hidden;<%= elem.preview_image_style %>">
|
49
|
-
<img src="<%= image.url if image.file.present? %>" alt="" class="img-responsive img-fluid">
|
50
|
-
</div>
|
51
|
-
</div>
|
52
|
-
</div>
|
53
|
-
<%= form.hidden_field "remove_#{elem.name}", value: "1", disabled:"disabled", class: 'js-ds-image-remove-flag' if elem.options[:removable]%>
|
54
|
-
<%= elem.render(self, form, 'form-control-file js-ds-image') do |attr|%>
|
55
|
-
<%= form.file_field(elem.name, attr) %>
|
56
|
-
<%end%>
|
57
|
-
<%= form.hidden_field "#{elem.name}_cache" %>
|
58
|
-
</div>
|
59
|
-
<% elsif elem.type? :globalize_fields %>
|
60
|
-
<% elem.locales.each do |locale, name| %>
|
61
|
-
<%- locale_errors = elem.locale_errors(locale, @record) -%>
|
62
|
-
<%= form.globalize_fields_for(locale) do |gform|%>
|
63
|
-
<div class="<%= class_names('ds-globalize-group', 'has-error': locale_errors.present?) %>">
|
64
|
-
<%= tag.span(elem.lang_attributes('ds-globalize-lang')) do%>
|
65
|
-
<%= name %>
|
66
|
-
<%end%>
|
67
|
-
<%= elem.render(self, gform, class_names('form-control', {'is-invalid': locale_errors.present?})) %>
|
68
|
-
</div>
|
69
|
-
<%= render_form_errors(locale_errors) -%>
|
70
|
-
<%end%>
|
71
|
-
<% end %>
|
72
|
-
<% else %>
|
73
|
-
<%= elem.render(self, form, class_names('form-control', {'is-invalid': errors.present?})) %>
|
74
|
-
<% end %>
|
75
|
-
<%- elem.insert(:after).each do |block| -%>
|
76
|
-
<%= self.instance_exec(@record, &block) %>
|
77
|
-
<%-end-%>
|
78
|
-
</div>
|
79
|
-
<%= render_form_errors(errors) -%>
|
80
|
-
<%if elem.notes?%>
|
81
|
-
<div class="form-text text-muted"><%= elem.render_notes(form.object, self) %></div>
|
82
|
-
<%end%>
|
83
|
-
</div>
|
84
|
-
<% end %>
|
85
|
-
<% end %>
|
3
|
+
<%= render 'dynamic_scaffold/bootstrap/form/row', form: form, elem: elem, depth: 0 %>
|
86
4
|
<% end %>
|
87
5
|
<div>
|
88
6
|
<%= link_to dynamic_scaffold_path(:index, request_queries), class: 'btn btn-outline-secondary btn-default back' do%>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div class="card mb-2 nested-fields">
|
2
|
+
<div class="card-header text-right p-2">
|
3
|
+
<%= link_to_remove_association dynamic_scaffold_icon(:delete), f, class: 'btn btn-danger btn-sm' %>
|
4
|
+
</div>
|
5
|
+
<div class="card-body">
|
6
|
+
<%- items.each do |elem|-%>
|
7
|
+
<%= render 'dynamic_scaffold/bootstrap/form/row', form: f, elem: elem, depth: depth + 1 %>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
</div>
|
@@ -0,0 +1,95 @@
|
|
1
|
+
<% if elem.needs_rendering?(self)%>
|
2
|
+
<% if !elem.label? && elem.type?(:hidden_field) %>
|
3
|
+
<%= elem.render(self, form) %>
|
4
|
+
<% else %>
|
5
|
+
<%- errors = elem.errors(form) -%>
|
6
|
+
<div class="<%= class_names('form-group', 'has-error': errors.present?) %>">
|
7
|
+
<%= elem.render_label(self, depth) %>
|
8
|
+
<div class="clearfix">
|
9
|
+
<%- elem.insert(:before).each do |block| -%>
|
10
|
+
<%= self.instance_exec(@record, &block) %>
|
11
|
+
<%-end-%>
|
12
|
+
<% if elem.type? :collection_check_boxes %>
|
13
|
+
<%= elem.render(self, form) do |cb|%>
|
14
|
+
<div class="form-check checkbox">
|
15
|
+
<%= cb.label class: 'form-check-label' do%>
|
16
|
+
<%= cb.check_box class: 'form-check-input' %> <%= cb.text %>
|
17
|
+
<%end%>
|
18
|
+
</div>
|
19
|
+
<%end%>
|
20
|
+
<% elsif elem.type? :collection_radio_buttons %>
|
21
|
+
<%= elem.render(self, form) do |cb|%>
|
22
|
+
<div class="form-check radio">
|
23
|
+
<%= cb.label class: 'form-check-label' do%>
|
24
|
+
<%= cb.radio_button class: 'form-check-input' %> <%= cb.text %>
|
25
|
+
<%end%>
|
26
|
+
</div>
|
27
|
+
<%end%>
|
28
|
+
<% elsif elem.type? :carrierwave_image %>
|
29
|
+
<%- image = form.object.public_send(elem.name) -%>
|
30
|
+
<div class="js-ds-image-wrapper">
|
31
|
+
<div class="js-ds-image-preview panel panel-default card mb-1">
|
32
|
+
<% if elem.options[:removable] %>
|
33
|
+
<div class="text-right panel-heading card-header">
|
34
|
+
<button type="button" class="btn btn-outline-danger btn-danger btn-sm js-ds-image-remove">
|
35
|
+
<%= dynamic_scaffold_icon :times %>
|
36
|
+
</button>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
<div class="panel-body card-body">
|
40
|
+
<%- if elem.cropper.present? -%>
|
41
|
+
<%= form.hidden_field "cropper_#{elem.name}", class: "js-ds-image-cropper", data:{options: elem.cropper.to_json} %>
|
42
|
+
<div class="text-right" style="height: 24px;">
|
43
|
+
<span class="js-ds-image-cropper-display badge badge-primary"></span>
|
44
|
+
</div>
|
45
|
+
<%- end -%>
|
46
|
+
<div style="overflow: hidden;<%= elem.preview_image_style %>">
|
47
|
+
<img src="<%= image.url if image.file.present? %>" alt="" class="img-responsive img-fluid">
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
<%= form.hidden_field "remove_#{elem.name}", value: "1", disabled:"disabled", class: 'js-ds-image-remove-flag' if elem.options[:removable]%>
|
52
|
+
<%= elem.render(self, form, 'form-control-file js-ds-image') do |attr|%>
|
53
|
+
<%= form.file_field(elem.name, attr) %>
|
54
|
+
<%end%>
|
55
|
+
<%= form.hidden_field "#{elem.name}_cache" %>
|
56
|
+
</div>
|
57
|
+
<% elsif elem.type? :globalize_fields %>
|
58
|
+
<% elem.locales.each do |locale, name| %>
|
59
|
+
<%- locale_errors = elem.locale_errors(locale, form) -%>
|
60
|
+
<%= form.globalize_fields_for(locale) do |gform|%>
|
61
|
+
<div class="<%= class_names('ds-globalize-group', 'has-error': locale_errors.present?) %>">
|
62
|
+
<%= tag.span(elem.lang_attributes('ds-globalize-lang')) do%>
|
63
|
+
<%= name %>
|
64
|
+
<%end%>
|
65
|
+
<%= elem.render(self, gform, class_names('form-control', {'is-invalid': locale_errors.present?})) %>
|
66
|
+
</div>
|
67
|
+
<%= render_form_errors(locale_errors) -%>
|
68
|
+
<%end%>
|
69
|
+
<% end %>
|
70
|
+
<% elsif elem.type? :cocoon %>
|
71
|
+
<%= form.fields_for elem.name, elem.build_children(@record) do |child_form| %>
|
72
|
+
<%= render 'dynamic_scaffold/bootstrap/form/cocoon', f: child_form, items: elem.form.items, depth: depth %>
|
73
|
+
<% end %>
|
74
|
+
<%= link_to_add_association(
|
75
|
+
"#{dynamic_scaffold_icon(:add)} #{elem.add_text}".html_safe,
|
76
|
+
form,
|
77
|
+
elem.name,
|
78
|
+
class: 'btn btn-outline-secondary btn-sm',
|
79
|
+
partial: 'dynamic_scaffold/bootstrap/form/cocoon',
|
80
|
+
render_options: { locals: { items: elem.form.items, depth: depth } }
|
81
|
+
) %>
|
82
|
+
<% else %>
|
83
|
+
<%= elem.render(self, form, class_names('form-control', {'is-invalid': errors.present?})) %>
|
84
|
+
<% end %>
|
85
|
+
<%- elem.insert(:after).each do |block| -%>
|
86
|
+
<%= self.instance_exec(@record, &block) %>
|
87
|
+
<%-end-%>
|
88
|
+
</div>
|
89
|
+
<%= render_form_errors(errors) -%>
|
90
|
+
<%if elem.notes?%>
|
91
|
+
<div class="form-text text-muted"><%= elem.render_notes(form.object, self) %></div>
|
92
|
+
<%end%>
|
93
|
+
</div>
|
94
|
+
<% end %>
|
95
|
+
<% end %>
|
@@ -1,124 +1,4 @@
|
|
1
1
|
module DynamicScaffold
|
2
|
-
class Pagination
|
3
|
-
attr_reader(
|
4
|
-
:kaminari_options,
|
5
|
-
:per_page,
|
6
|
-
:total_count,
|
7
|
-
:end_buttons,
|
8
|
-
:neighbor_buttons,
|
9
|
-
:gap_buttons,
|
10
|
-
:highlight_current,
|
11
|
-
:param_name
|
12
|
-
)
|
13
|
-
def initialize(options)
|
14
|
-
options = {
|
15
|
-
per_page: 25,
|
16
|
-
window: 0, # kaminari options
|
17
|
-
outer_window: 0, # kaminari options
|
18
|
-
left: 0, # kaminari options
|
19
|
-
right: 0, # kaminari options
|
20
|
-
param_name: :page, # kaminari options
|
21
|
-
total_count: true, # Whether to display total count on active page like `2 / 102`
|
22
|
-
end_buttons: true, # Whether to display buttons to the first and last page.
|
23
|
-
neighbor_buttons: true, # Whether to display buttons to the next and prev page.
|
24
|
-
gap_buttons: false, # Whether to display gap buttons.
|
25
|
-
highlight_current: false, # Whether to highlight the current page.
|
26
|
-
}.merge(options)
|
27
|
-
@kaminari_options = options.extract!(:window, :outer_window, :left, :right, :param_name)
|
28
|
-
@param_name = @kaminari_options[:param_name]
|
29
|
-
options.each {|name, value| instance_variable_set("@#{name}", value) }
|
30
|
-
end
|
31
|
-
|
32
|
-
def page_number(page, records)
|
33
|
-
return page unless total_count
|
34
|
-
|
35
|
-
"#{page} / #{records.total_pages}"
|
36
|
-
end
|
37
|
-
|
38
|
-
def page_class(page, _records)
|
39
|
-
if page.inside_window?
|
40
|
-
'inner'
|
41
|
-
elsif page.left_outer?
|
42
|
-
'left-outer'
|
43
|
-
elsif page.right_outer?
|
44
|
-
'right-outer'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class Title
|
50
|
-
attr_writer :name
|
51
|
-
|
52
|
-
def initialize(config)
|
53
|
-
@config = config
|
54
|
-
@titles_cache = {}
|
55
|
-
@name = @config.model.model_name.human
|
56
|
-
end
|
57
|
-
|
58
|
-
def name(&block)
|
59
|
-
if block_given?
|
60
|
-
@block = block
|
61
|
-
elsif !@block.nil?
|
62
|
-
@config.controller.view_context.instance_exec(&@block)
|
63
|
-
else
|
64
|
-
@name
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def current
|
69
|
-
public_send(@config.controller.params[:action])
|
70
|
-
end
|
71
|
-
|
72
|
-
def index
|
73
|
-
titles(:index)
|
74
|
-
end
|
75
|
-
|
76
|
-
def edit
|
77
|
-
titles(:edit)
|
78
|
-
end
|
79
|
-
|
80
|
-
def new
|
81
|
-
titles(:new)
|
82
|
-
end
|
83
|
-
|
84
|
-
def update
|
85
|
-
titles(:edit)
|
86
|
-
end
|
87
|
-
|
88
|
-
def create
|
89
|
-
titles(:new)
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
def titles(action)
|
95
|
-
unless @titles_cache[action]
|
96
|
-
titles = OpenStruct.new
|
97
|
-
titles.name = name
|
98
|
-
titles.full = I18n.t("dynamic_scaffold.title.full.#{action}", name: titles.name)
|
99
|
-
titles.action = I18n.t("dynamic_scaffold.title.action.#{action}")
|
100
|
-
titles.freeze
|
101
|
-
@titles_cache[action] = titles
|
102
|
-
end
|
103
|
-
|
104
|
-
@titles_cache[action]
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
class Vars
|
109
|
-
def initialize(config)
|
110
|
-
@config = config
|
111
|
-
@values = {}
|
112
|
-
end
|
113
|
-
|
114
|
-
def _register(name, block)
|
115
|
-
define_singleton_method(name) do
|
116
|
-
@values[name] ||= @config.controller.instance_exec(&block)
|
117
|
-
@values[name]
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
2
|
class Config
|
123
3
|
attr_reader(
|
124
4
|
:model,
|
@@ -172,128 +52,18 @@ module DynamicScaffold
|
|
172
52
|
end
|
173
53
|
end
|
174
54
|
|
175
|
-
class
|
176
|
-
|
177
|
-
@config = config
|
178
|
-
@items = []
|
179
|
-
@sorter = nil
|
180
|
-
@order = []
|
181
|
-
@title = nil
|
182
|
-
@filter = nil
|
183
|
-
end
|
184
|
-
|
185
|
-
def pagination(options = nil)
|
186
|
-
@pagination = Pagination.new(options) unless options.nil?
|
187
|
-
|
188
|
-
@pagination
|
189
|
-
end
|
190
|
-
|
191
|
-
def page_param_name
|
192
|
-
pagination ? pagination.param_name : nil
|
193
|
-
end
|
194
|
-
|
195
|
-
def sorter(params = nil)
|
196
|
-
@sorter = params if params
|
197
|
-
@sorter
|
198
|
-
end
|
199
|
-
|
200
|
-
def item(*args, &block)
|
201
|
-
item = List::Item.new(@config, *args, block)
|
202
|
-
@items << item
|
203
|
-
item
|
204
|
-
end
|
205
|
-
|
206
|
-
def items
|
207
|
-
if @items.empty?
|
208
|
-
@config.model.column_names.each do |column|
|
209
|
-
@items << List::Item.new(@config, column, nil)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
@items
|
213
|
-
end
|
214
|
-
|
215
|
-
def sorter_attribute
|
216
|
-
@sorter.keys.first
|
217
|
-
end
|
218
|
-
|
219
|
-
def sorter_direction
|
220
|
-
@sorter.values.first
|
221
|
-
end
|
222
|
-
|
223
|
-
def order(*args)
|
224
|
-
@order = args unless args.empty?
|
225
|
-
@order
|
226
|
-
end
|
227
|
-
|
228
|
-
def title(*args, &block)
|
229
|
-
if args[0].is_a?(Symbol) || args[0].is_a?(String) || block_given?
|
230
|
-
@title = {
|
231
|
-
column_name: args[0],
|
232
|
-
block: block
|
233
|
-
}
|
234
|
-
else
|
235
|
-
record = args[0]
|
236
|
-
return @config.controller.view_context.instance_exec(record, &@title[:block]) if @title[:block]
|
237
|
-
|
238
|
-
record.public_send(@title[:column_name])
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def title?
|
243
|
-
@title.present?
|
244
|
-
end
|
245
|
-
|
246
|
-
def build_sql(scope_params)
|
247
|
-
sql = @config.model.all
|
248
|
-
sql = sql.where scope_params
|
249
|
-
ret = @config.controller.instance_exec(sql, &@filter) unless @filter.nil?
|
250
|
-
sql = ret unless ret.nil?
|
251
|
-
unless sql.is_a? ::ActiveRecord::Relation
|
252
|
-
raise(
|
253
|
-
Error::InvalidOperation,
|
254
|
-
'You must return ActiveRecord::Relation from filter block'
|
255
|
-
)
|
256
|
-
end
|
257
|
-
sql
|
258
|
-
end
|
259
|
-
|
260
|
-
def filter(&block)
|
261
|
-
@filter = block if block_given?
|
262
|
-
@filter
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
class FormBuilder
|
267
|
-
def initialize(config)
|
268
|
-
@config = config
|
269
|
-
@items = []
|
270
|
-
@permit_params = []
|
271
|
-
end
|
55
|
+
class GlobalConfig
|
56
|
+
attr_accessor :form
|
272
57
|
|
273
|
-
|
274
|
-
|
275
|
-
@
|
276
|
-
|
277
|
-
type = :hidden_field if @config.scope && @config.scope.include?(column.to_sym)
|
278
|
-
@items << Form::Item::SingleOption.new(@config, type, column)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
@items
|
282
|
-
end
|
283
|
-
|
284
|
-
def permit_params(*params)
|
285
|
-
if !params.empty?
|
286
|
-
@permit_params.concat(params)
|
287
|
-
self
|
288
|
-
else
|
289
|
-
@permit_params
|
58
|
+
class Form
|
59
|
+
def label(&block)
|
60
|
+
@label = block if block_given?
|
61
|
+
@label
|
290
62
|
end
|
291
63
|
end
|
292
64
|
|
293
|
-
def
|
294
|
-
|
295
|
-
@items << item
|
296
|
-
item
|
65
|
+
def initialize
|
66
|
+
@form = Form.new
|
297
67
|
end
|
298
68
|
end
|
299
69
|
end
|
@@ -27,7 +27,9 @@ module DynamicScaffold
|
|
27
27
|
|
28
28
|
carrierwave_image: Form::Item::CarrierWaveImage,
|
29
29
|
|
30
|
-
globalize_fields: Form::Item::GlobalizeFields
|
30
|
+
globalize_fields: Form::Item::GlobalizeFields,
|
31
|
+
|
32
|
+
cocoon: Form::Item::Cocoon
|
31
33
|
}.freeze
|
32
34
|
|
33
35
|
class << self
|
@@ -39,11 +41,7 @@ module DynamicScaffold
|
|
39
41
|
)
|
40
42
|
end
|
41
43
|
|
42
|
-
|
43
|
-
ITEM_TYPES[type].new(config, type, *args, block)
|
44
|
-
else
|
45
|
-
ITEM_TYPES[type].new(config, type, *args)
|
46
|
-
end
|
44
|
+
ITEM_TYPES[type].new(config, type, *args, &block)
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -59,6 +57,8 @@ module DynamicScaffold
|
|
59
57
|
@notes = []
|
60
58
|
@multiple = type == :collection_check_boxes || html_attributes[:multiple]
|
61
59
|
@inserts = { before: [], after: [] }
|
60
|
+
@label_attributes = {}
|
61
|
+
@label_block = nil
|
62
62
|
end
|
63
63
|
|
64
64
|
def notes?
|
@@ -85,20 +85,38 @@ module DynamicScaffold
|
|
85
85
|
!@label.nil?
|
86
86
|
end
|
87
87
|
|
88
|
-
def label(
|
89
|
-
if
|
90
|
-
raise Error::InvalidParameter, 'Only the block type accepts block.' unless type? :block
|
88
|
+
def label(*args, &block)
|
89
|
+
return @label || @config.model.human_attribute_name(@name) if args.empty? && block.nil?
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
if
|
95
|
-
@label = label
|
96
|
-
self
|
97
|
-
else
|
98
|
-
return @label if @label
|
91
|
+
@label_attributes = args.extract_options!
|
92
|
+
@label = args.first unless args.empty?
|
93
|
+
@label_block = block if block_given?
|
99
94
|
|
100
|
-
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
def render_label(view, depth)
|
99
|
+
if @label_block.present?
|
100
|
+
label = view.instance_exec(
|
101
|
+
proxy_field.label,
|
102
|
+
depth,
|
103
|
+
@label_attributes,
|
104
|
+
&@label_block
|
105
|
+
)
|
106
|
+
return label unless label.nil?
|
101
107
|
end
|
108
|
+
|
109
|
+
# if DynamicScaffold.config.form.label.present?
|
110
|
+
# label = view.instance_exec(
|
111
|
+
# proxy_field.label,
|
112
|
+
# depth,
|
113
|
+
# @label_attributes,
|
114
|
+
# &DynamicScaffold.config.form.label
|
115
|
+
# )
|
116
|
+
# return label unless label.nil?
|
117
|
+
# end
|
118
|
+
|
119
|
+
view.tag.label(proxy_field.label, @label_attributes)
|
102
120
|
end
|
103
121
|
|
104
122
|
def extract_parameters(permitting)
|
@@ -162,10 +180,10 @@ module DynamicScaffold
|
|
162
180
|
end
|
163
181
|
end
|
164
182
|
|
165
|
-
def errors(
|
166
|
-
msg =
|
183
|
+
def errors(form)
|
184
|
+
msg = form.object.errors.full_messages_for(proxy_field.name)
|
167
185
|
rel = @config.model.reflect_on_all_associations.find {|r| r.foreign_key.to_s == name.to_s }
|
168
|
-
msg.concat(
|
186
|
+
msg.concat(form.object.errors.full_messages_for(rel.name)) if rel.present?
|
169
187
|
msg
|
170
188
|
end
|
171
189
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Form
|
3
|
+
module Item
|
4
|
+
class Cocoon < Base
|
5
|
+
attr_reader :form
|
6
|
+
def initialize(config, type, name, options = {})
|
7
|
+
super
|
8
|
+
@options = options
|
9
|
+
@form = FormBuilder.new(config)
|
10
|
+
yield(@form)
|
11
|
+
end
|
12
|
+
|
13
|
+
def extract_parameters(permitting)
|
14
|
+
permitting << { "#{@name}_attributes": [*@form.items.map(&:name).push(:_destroy)] }
|
15
|
+
end
|
16
|
+
|
17
|
+
def filter(&block)
|
18
|
+
@filter = block
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_text
|
23
|
+
@options[:add_text] || "Add #{proxy_field.label}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_children(record)
|
27
|
+
children = record.public_send(name).to_a
|
28
|
+
children = @filter.call(children) if @filter.present?
|
29
|
+
children
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -31,8 +31,8 @@ module DynamicScaffold
|
|
31
31
|
build_html_attributes(classnames)
|
32
32
|
end
|
33
33
|
|
34
|
-
def locale_errors(locale,
|
35
|
-
|
34
|
+
def locale_errors(locale, form)
|
35
|
+
form.object.errors.full_messages_for("#{@item.proxy_field.name}_#{locale}")
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -1,65 +1,35 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# in the same request.
|
9
|
-
#
|
10
|
-
# Use it like this:
|
11
|
-
#
|
12
|
-
# <h1>Editing post</h1>
|
13
|
-
#
|
14
|
-
# <% form_for(@post) do |f| %>
|
15
|
-
# <%= f.error_messages %>
|
16
|
-
#
|
17
|
-
# <h2>English (default locale)</h2>
|
18
|
-
# <p><%= f.text_field :title %></p>
|
19
|
-
# <p><%= f.text_field :teaser %></p>
|
20
|
-
# <p><%= f.text_field :body %></p>
|
21
|
-
#
|
22
|
-
# <hr/>
|
23
|
-
#
|
24
|
-
# <h2>Spanish translation</h2>
|
25
|
-
# <% f.globalize_fields_for :es do |g| %>
|
26
|
-
# <p><%= g.text_field :title %></p>
|
27
|
-
# <p><%= g.text_field :teaser %></p>
|
28
|
-
# <p><%= g.text_field :body %></p>
|
29
|
-
# <% end %>
|
30
|
-
#
|
31
|
-
# <hr/>
|
32
|
-
#
|
33
|
-
# <h2>French translation</h2>
|
34
|
-
# <% f.globalize_fields_for :fr do |g| %>
|
35
|
-
# <p><%= g.text_field :title %></p>
|
36
|
-
# <p><%= g.text_field :teaser %></p>
|
37
|
-
# <p><%= g.text_field :body %></p>
|
38
|
-
# <% end %>
|
39
|
-
#
|
40
|
-
# <% end %>
|
41
|
-
#
|
42
|
-
def globalize_fields_for(locale, *args, &proc)
|
43
|
-
raise ArgumentError, 'Missing block' unless block_given?
|
44
|
-
|
45
|
-
@locales ||= []
|
46
|
-
|
47
|
-
first = false
|
48
|
-
unless @locales.include?(locale)
|
49
|
-
@locales << locale
|
50
|
-
first = true
|
51
|
-
end
|
52
|
-
object_name = "#{@object_name}[translations_attributes][#{@locales.index(locale) + 1}]"
|
53
|
-
object = @object.translations.to_a.find {|t| t.locale.to_s == locale.to_s }
|
1
|
+
module DynamicScaffold
|
2
|
+
class FormBuilder
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@items = []
|
6
|
+
@permit_params = []
|
7
|
+
end
|
54
8
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
9
|
+
def items
|
10
|
+
if @items.empty?
|
11
|
+
@config.model.column_names.each do |column|
|
12
|
+
type = :text_field
|
13
|
+
type = :hidden_field if @config.scope && @config.scope.include?(column.to_sym)
|
14
|
+
@items << Form::Item::SingleOption.new(@config, type, column)
|
59
15
|
end
|
16
|
+
end
|
17
|
+
@items
|
18
|
+
end
|
60
19
|
|
61
|
-
|
20
|
+
def permit_params(*params)
|
21
|
+
if !params.empty?
|
22
|
+
@permit_params.concat(params)
|
23
|
+
self
|
24
|
+
else
|
25
|
+
@permit_params
|
62
26
|
end
|
63
27
|
end
|
28
|
+
|
29
|
+
def item(type, *args, &block)
|
30
|
+
item = Form::Item::Base.create(@config, type, *args, &block)
|
31
|
+
@items << item
|
32
|
+
item
|
33
|
+
end
|
64
34
|
end
|
65
35
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module List
|
3
|
+
class Pagination
|
4
|
+
attr_reader(
|
5
|
+
:kaminari_options,
|
6
|
+
:per_page,
|
7
|
+
:total_count,
|
8
|
+
:end_buttons,
|
9
|
+
:neighbor_buttons,
|
10
|
+
:gap_buttons,
|
11
|
+
:highlight_current,
|
12
|
+
:param_name
|
13
|
+
)
|
14
|
+
def initialize(options)
|
15
|
+
options = {
|
16
|
+
per_page: 25,
|
17
|
+
window: 0, # kaminari options
|
18
|
+
outer_window: 0, # kaminari options
|
19
|
+
left: 0, # kaminari options
|
20
|
+
right: 0, # kaminari options
|
21
|
+
param_name: :page, # kaminari options
|
22
|
+
total_count: true, # Whether to display total count on active page like `2 / 102`
|
23
|
+
end_buttons: true, # Whether to display buttons to the first and last page.
|
24
|
+
neighbor_buttons: true, # Whether to display buttons to the next and prev page.
|
25
|
+
gap_buttons: false, # Whether to display gap buttons.
|
26
|
+
highlight_current: false, # Whether to highlight the current page.
|
27
|
+
}.merge(options)
|
28
|
+
@kaminari_options = options.extract!(:window, :outer_window, :left, :right, :param_name)
|
29
|
+
@param_name = @kaminari_options[:param_name]
|
30
|
+
options.each {|name, value| instance_variable_set("@#{name}", value) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def page_number(page, records)
|
34
|
+
return page unless total_count
|
35
|
+
|
36
|
+
"#{page} / #{records.total_pages}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def page_class(page, _records)
|
40
|
+
if page.inside_window?
|
41
|
+
'inner'
|
42
|
+
elsif page.left_outer?
|
43
|
+
'left-outer'
|
44
|
+
elsif page.right_outer?
|
45
|
+
'right-outer'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
class ListBuilder
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@items = []
|
6
|
+
@sorter = nil
|
7
|
+
@order = []
|
8
|
+
@title = nil
|
9
|
+
@filter = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def pagination(options = nil)
|
13
|
+
@pagination = List::Pagination.new(options) unless options.nil?
|
14
|
+
|
15
|
+
@pagination
|
16
|
+
end
|
17
|
+
|
18
|
+
def page_param_name
|
19
|
+
pagination ? pagination.param_name : nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def sorter(params = nil)
|
23
|
+
@sorter = params if params
|
24
|
+
@sorter
|
25
|
+
end
|
26
|
+
|
27
|
+
def item(*args, &block)
|
28
|
+
item = List::Item.new(@config, *args, block)
|
29
|
+
@items << item
|
30
|
+
item
|
31
|
+
end
|
32
|
+
|
33
|
+
def items
|
34
|
+
if @items.empty?
|
35
|
+
@config.model.column_names.each do |column|
|
36
|
+
@items << List::Item.new(@config, column, nil)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@items
|
40
|
+
end
|
41
|
+
|
42
|
+
def sorter_attribute
|
43
|
+
@sorter.keys.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def sorter_direction
|
47
|
+
@sorter.values.first
|
48
|
+
end
|
49
|
+
|
50
|
+
def order(*args)
|
51
|
+
@order = args unless args.empty?
|
52
|
+
@order
|
53
|
+
end
|
54
|
+
|
55
|
+
def title(*args, &block)
|
56
|
+
if args[0].is_a?(Symbol) || args[0].is_a?(String) || block_given?
|
57
|
+
@title = {
|
58
|
+
column_name: args[0],
|
59
|
+
block: block
|
60
|
+
}
|
61
|
+
else
|
62
|
+
record = args[0]
|
63
|
+
return @config.controller.view_context.instance_exec(record, &@title[:block]) if @title[:block]
|
64
|
+
|
65
|
+
record.public_send(@title[:column_name])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def title?
|
70
|
+
@title.present?
|
71
|
+
end
|
72
|
+
|
73
|
+
def build_sql(scope_params)
|
74
|
+
sql = @config.model.all
|
75
|
+
sql = sql.where scope_params
|
76
|
+
ret = @config.controller.instance_exec(sql, &@filter) unless @filter.nil?
|
77
|
+
sql = ret unless ret.nil?
|
78
|
+
unless sql.is_a? ::ActiveRecord::Relation
|
79
|
+
raise(
|
80
|
+
Error::InvalidOperation,
|
81
|
+
'You must return ActiveRecord::Relation from filter block'
|
82
|
+
)
|
83
|
+
end
|
84
|
+
sql
|
85
|
+
end
|
86
|
+
|
87
|
+
def filter(&block)
|
88
|
+
@filter = block if block_given?
|
89
|
+
@filter
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ActionView
|
2
|
+
module Helpers
|
3
|
+
class FormBuilder
|
4
|
+
#
|
5
|
+
# Helper that renders translations fields
|
6
|
+
# on a per-locale basis, so you can use them separately
|
7
|
+
# in the same form and still saving them all at once
|
8
|
+
# in the same request.
|
9
|
+
#
|
10
|
+
# Use it like this:
|
11
|
+
#
|
12
|
+
# <h1>Editing post</h1>
|
13
|
+
#
|
14
|
+
# <% form_for(@post) do |f| %>
|
15
|
+
# <%= f.error_messages %>
|
16
|
+
#
|
17
|
+
# <h2>English (default locale)</h2>
|
18
|
+
# <p><%= f.text_field :title %></p>
|
19
|
+
# <p><%= f.text_field :teaser %></p>
|
20
|
+
# <p><%= f.text_field :body %></p>
|
21
|
+
#
|
22
|
+
# <hr/>
|
23
|
+
#
|
24
|
+
# <h2>Spanish translation</h2>
|
25
|
+
# <% f.globalize_fields_for :es do |g| %>
|
26
|
+
# <p><%= g.text_field :title %></p>
|
27
|
+
# <p><%= g.text_field :teaser %></p>
|
28
|
+
# <p><%= g.text_field :body %></p>
|
29
|
+
# <% end %>
|
30
|
+
#
|
31
|
+
# <hr/>
|
32
|
+
#
|
33
|
+
# <h2>French translation</h2>
|
34
|
+
# <% f.globalize_fields_for :fr do |g| %>
|
35
|
+
# <p><%= g.text_field :title %></p>
|
36
|
+
# <p><%= g.text_field :teaser %></p>
|
37
|
+
# <p><%= g.text_field :body %></p>
|
38
|
+
# <% end %>
|
39
|
+
#
|
40
|
+
# <% end %>
|
41
|
+
#
|
42
|
+
def globalize_fields_for(locale, *args, &proc)
|
43
|
+
raise ArgumentError, 'Missing block' unless block_given?
|
44
|
+
|
45
|
+
@locales ||= []
|
46
|
+
|
47
|
+
first = false
|
48
|
+
unless @locales.include?(locale)
|
49
|
+
@locales << locale
|
50
|
+
first = true
|
51
|
+
end
|
52
|
+
object_name = "#{@object_name}[translations_attributes][#{@locales.index(locale) + 1}]"
|
53
|
+
object = @object.translations.to_a.find {|t| t.locale.to_s == locale.to_s }
|
54
|
+
|
55
|
+
# The following tags are added only once for the first time.
|
56
|
+
if first
|
57
|
+
@template.concat @template.hidden_field_tag("#{object_name}[id]", object ? object.id : '')
|
58
|
+
@template.concat @template.hidden_field_tag("#{object_name}[locale]", locale)
|
59
|
+
end
|
60
|
+
|
61
|
+
@template.fields_for(object_name, object, *args, &proc)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
class Title
|
3
|
+
attr_writer :name
|
4
|
+
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
@titles_cache = {}
|
8
|
+
@name = @config.model.model_name.human
|
9
|
+
end
|
10
|
+
|
11
|
+
def name(&block)
|
12
|
+
if block_given?
|
13
|
+
@block = block
|
14
|
+
elsif !@block.nil?
|
15
|
+
@config.controller.view_context.instance_exec(&@block)
|
16
|
+
else
|
17
|
+
@name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def current
|
22
|
+
public_send(@config.controller.params[:action])
|
23
|
+
end
|
24
|
+
|
25
|
+
def index
|
26
|
+
titles(:index)
|
27
|
+
end
|
28
|
+
|
29
|
+
def edit
|
30
|
+
titles(:edit)
|
31
|
+
end
|
32
|
+
|
33
|
+
def new
|
34
|
+
titles(:new)
|
35
|
+
end
|
36
|
+
|
37
|
+
def update
|
38
|
+
titles(:edit)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create
|
42
|
+
titles(:new)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def titles(action)
|
48
|
+
unless @titles_cache[action]
|
49
|
+
titles = OpenStruct.new
|
50
|
+
titles.name = name
|
51
|
+
titles.full = I18n.t("dynamic_scaffold.title.full.#{action}", name: titles.name)
|
52
|
+
titles.action = I18n.t("dynamic_scaffold.title.action.#{action}")
|
53
|
+
titles.freeze
|
54
|
+
@titles_cache[action] = titles
|
55
|
+
end
|
56
|
+
|
57
|
+
@titles_cache[action]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
class Vars
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@values = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def _register(name, block)
|
9
|
+
define_singleton_method(name) do
|
10
|
+
@values[name] ||= @config.controller.instance_exec(&block)
|
11
|
+
@values[name]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/dynamic_scaffold.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require 'dynamic_scaffold/version'
|
2
2
|
require 'dynamic_scaffold/engine'
|
3
|
+
require 'dynamic_scaffold/monkeypatch/action_view/helpers/form_builder'
|
3
4
|
require 'dynamic_scaffold/routes'
|
4
5
|
require 'dynamic_scaffold/controller_utilities'
|
5
6
|
require 'dynamic_scaffold/controller'
|
6
7
|
require 'dynamic_scaffold/config'
|
8
|
+
require 'dynamic_scaffold/list_builder'
|
7
9
|
require 'dynamic_scaffold/form_builder'
|
10
|
+
require 'dynamic_scaffold/title'
|
11
|
+
require 'dynamic_scaffold/vars'
|
8
12
|
|
9
13
|
module DynamicScaffold
|
10
14
|
module Error
|
@@ -16,6 +20,7 @@ module DynamicScaffold
|
|
16
20
|
|
17
21
|
module List
|
18
22
|
autoload :Item, 'dynamic_scaffold/list/item'
|
23
|
+
autoload :Pagination, 'dynamic_scaffold/list/pagination'
|
19
24
|
end
|
20
25
|
|
21
26
|
module Form
|
@@ -27,6 +32,7 @@ module DynamicScaffold
|
|
27
32
|
autoload :TwoOptionsWithBlock, 'dynamic_scaffold/form/item/two_options_with_block'
|
28
33
|
autoload :TwoOptions, 'dynamic_scaffold/form/item/two_options'
|
29
34
|
autoload :GlobalizeFields, 'dynamic_scaffold/form/item/globalize_fields'
|
35
|
+
autoload :Cocoon, 'dynamic_scaffold/form/item/cocoon'
|
30
36
|
end
|
31
37
|
end
|
32
38
|
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.
|
4
|
+
version: 1.0.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: 2019-
|
11
|
+
date: 2019-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: classnames-rails-view
|
@@ -240,6 +240,8 @@ files:
|
|
240
240
|
- app/views/dynamic_scaffold/bootstrap/_new.html.erb
|
241
241
|
- app/views/dynamic_scaffold/bootstrap/_pagination.html.erb
|
242
242
|
- app/views/dynamic_scaffold/bootstrap/_save_order.html.erb
|
243
|
+
- app/views/dynamic_scaffold/bootstrap/form/_cocoon.html.erb
|
244
|
+
- app/views/dynamic_scaffold/bootstrap/form/_row.html.erb
|
243
245
|
- app/views/dynamic_scaffold/bootstrap/kaminari/_first_page.html.erb
|
244
246
|
- app/views/dynamic_scaffold/bootstrap/kaminari/_gap.html.erb
|
245
247
|
- app/views/dynamic_scaffold/bootstrap/kaminari/_last_page.html.erb
|
@@ -263,6 +265,7 @@ files:
|
|
263
265
|
- lib/dynamic_scaffold/form/item/base.rb
|
264
266
|
- lib/dynamic_scaffold/form/item/block.rb
|
265
267
|
- lib/dynamic_scaffold/form/item/carrier_wave_image.rb
|
268
|
+
- lib/dynamic_scaffold/form/item/cocoon.rb
|
266
269
|
- lib/dynamic_scaffold/form/item/globalize_fields.rb
|
267
270
|
- lib/dynamic_scaffold/form/item/single_option.rb
|
268
271
|
- lib/dynamic_scaffold/form/item/two_options.rb
|
@@ -270,7 +273,12 @@ files:
|
|
270
273
|
- lib/dynamic_scaffold/form_builder.rb
|
271
274
|
- lib/dynamic_scaffold/icons/fontawesome.rb
|
272
275
|
- lib/dynamic_scaffold/list/item.rb
|
276
|
+
- lib/dynamic_scaffold/list/pagination.rb
|
277
|
+
- lib/dynamic_scaffold/list_builder.rb
|
278
|
+
- lib/dynamic_scaffold/monkeypatch/action_view/helpers/form_builder.rb
|
273
279
|
- lib/dynamic_scaffold/routes.rb
|
280
|
+
- lib/dynamic_scaffold/title.rb
|
281
|
+
- lib/dynamic_scaffold/vars.rb
|
274
282
|
- lib/dynamic_scaffold/version.rb
|
275
283
|
- lib/generators/dynamic_scaffold/USAGE
|
276
284
|
- lib/generators/dynamic_scaffold/dynamic_scaffold_generator.rb
|
@@ -299,7 +307,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
299
307
|
version: '0'
|
300
308
|
requirements: []
|
301
309
|
rubyforge_project:
|
302
|
-
rubygems_version: 2.7.
|
310
|
+
rubygems_version: 2.7.6
|
303
311
|
signing_key:
|
304
312
|
specification_version: 4
|
305
313
|
summary: The Scaffold system which dynamically generates CRUD and sort functions.
|