effective_bootstrap 0.9.36 → 0.9.40
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/app/assets/javascripts/effective_has_many/initialize.js.coffee +20 -1
- data/app/assets/stylesheets/effective_bootstrap/base.scss +1 -1
- data/app/assets/stylesheets/effective_bootstrap/collapse.scss +7 -0
- data/app/assets/stylesheets/effective_has_many/input.scss +4 -0
- data/app/helpers/effective_bootstrap_helper.rb +86 -23
- data/app/models/effective/form_inputs/has_many.rb +71 -7
- data/lib/effective_bootstrap/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ec7aa9c72ddbc58533cf76bf8eb8843f957bc2f79be9604f35a41948bbd03e4
|
4
|
+
data.tar.gz: 064e9a0da7b7d2721953348524dcc38f16cd9fb0bffcaca88fe181aa4d7b9e6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1237917f4abb0ab752d26a6c7af13169ed0a971c048cfeb1b984912dc54bfa58e7f6bdf312a9b54fa1108d8cf725fba038e0a876ee492522a7a53345ce99537b
|
7
|
+
data.tar.gz: 368f386c0683a11fb99060a79a60cd9d6b6870cf9299173b7a1cb7da865ce23c976af625397f6f2fd0c715999d6b266387efb66b8af02ef73792ac6d88696ace
|
@@ -36,8 +36,27 @@ $(document).on 'click', '[data-effective-form-has-many-add]', (event) ->
|
|
36
36
|
template = atob($obj.data('effective-form-has-many-template')).replace(/HASMANYINDEX/g, uid)
|
37
37
|
|
38
38
|
$fields = $(template).hide().fadeIn('fast')
|
39
|
-
EffectiveBootstrap.initialize($fields)
|
40
39
|
$obj.closest('.has-many-links').before($fields)
|
40
|
+
EffectiveBootstrap.initialize($fields)
|
41
|
+
|
42
|
+
assignPositions($hasMany)
|
43
|
+
true
|
44
|
+
|
45
|
+
$(document).on 'click', '[data-effective-form-has-many-insert]', (event) ->
|
46
|
+
event.preventDefault()
|
47
|
+
|
48
|
+
$obj = $(event.currentTarget)
|
49
|
+
$hasMany = $obj.closest('.form-has-many')
|
50
|
+
return unless $hasMany.length > 0
|
51
|
+
|
52
|
+
$add = $hasMany.children('.has-many-links').find('[data-effective-form-has-many-template]')
|
53
|
+
|
54
|
+
uid = (new Date).valueOf()
|
55
|
+
template = atob($add.data('effective-form-has-many-template')).replace(/HASMANYINDEX/g, uid)
|
56
|
+
|
57
|
+
$fields = $(template).hide().fadeIn('fast')
|
58
|
+
$obj.closest('.has-many-fields').before($fields)
|
59
|
+
EffectiveBootstrap.initialize($fields)
|
41
60
|
|
42
61
|
assignPositions($hasMany)
|
43
62
|
true
|
@@ -3,12 +3,16 @@
|
|
3
3
|
.has-many-move { display: none; }
|
4
4
|
.has-many-remove-disabled { opacity: 0; cursor: default !important; }
|
5
5
|
|
6
|
+
.has-many-actions { margin-bottom: 0.75rem; }
|
6
7
|
.has-many-remove { margin-top: 1rem; }
|
7
8
|
.has-many-move { margin-top: 1.5rem; }
|
8
9
|
}
|
9
10
|
|
10
11
|
.form-has-many.reordering {
|
12
|
+
.has-many-actions { display: none; }
|
11
13
|
.has-many-move { display: inline-block; cursor: grab; }
|
14
|
+
|
15
|
+
.form-has-many { display: none; }
|
12
16
|
}
|
13
17
|
|
14
18
|
.form-has-many.tight {
|
@@ -10,7 +10,7 @@ module EffectiveBootstrapHelper
|
|
10
10
|
def accordion(options = nil, &block)
|
11
11
|
(options ||= {})[:class] = "accordion #{options.delete(:class)}".strip
|
12
12
|
|
13
|
-
id = "accordion-#{
|
13
|
+
id = "accordion-#{effective_bootstrap_unique_id}"
|
14
14
|
|
15
15
|
@_accordion_active = id
|
16
16
|
content = content_tag(:div, capture(&block), options.merge(id: id))
|
@@ -18,6 +18,31 @@ module EffectiveBootstrapHelper
|
|
18
18
|
content
|
19
19
|
end
|
20
20
|
|
21
|
+
def accordion_collapse(label, opts = {}, &block)
|
22
|
+
raise 'expected a block' unless block_given?
|
23
|
+
|
24
|
+
id = "collapse-#{effective_bootstrap_unique_id}"
|
25
|
+
show = (opts.delete(:show) == true)
|
26
|
+
|
27
|
+
link_opts = { 'data-toggle': 'collapse', role: 'button', href: "##{id}", 'aria-controls': "##{id}", 'aria-expanded': show }
|
28
|
+
|
29
|
+
link_opts[:class] = opts.delete(:link_class) || 'btn btn-link'
|
30
|
+
div_class = opts.delete(:div_class)
|
31
|
+
card_class = opts.delete(:card_class) || 'card card-body my-2'
|
32
|
+
|
33
|
+
# Accordion collapse
|
34
|
+
content_tag(:div, class: "card mb-0") do
|
35
|
+
content_tag(:div, class: "card-header") do
|
36
|
+
content_tag(:h2, class: "mb-0") do
|
37
|
+
content_tag(:button, label, link_opts.merge(class: "btn btn-link"))
|
38
|
+
end
|
39
|
+
end +
|
40
|
+
content_tag(:div, id: id, class: ['collapse', div_class, ('show' if show)].compact.join(' '), "data-parent": "##{@_accordion_active}") do
|
41
|
+
content_tag(:div, capture(&block), class: "card-body")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
21
46
|
# https://getbootstrap.com/docs/4.0/components/card/
|
22
47
|
# = card('title do')
|
23
48
|
# %p Stuff
|
@@ -56,40 +81,67 @@ module EffectiveBootstrapHelper
|
|
56
81
|
# = collapse('already expanded', show: true) do
|
57
82
|
# %p Something Expanded
|
58
83
|
|
84
|
+
# the word 'show' will automatically be replaced with hide and an icon added
|
85
|
+
# = collapse('show items') do
|
86
|
+
# %p Something Expanded
|
87
|
+
|
88
|
+
# Override the expand and collapse labels directly
|
89
|
+
# = collapse('show items', expand: "Show items" + icon('ok'), collapse: "Hide items" + icon('x')) do
|
90
|
+
# %p Something Expanded
|
91
|
+
|
59
92
|
# collapse(items.length, class: 'btn btn-primary', class: 'mt-2') do
|
60
93
|
# items.map { |item| content_tag(:div, item.to_s) }.join.html_safe
|
61
94
|
# end
|
95
|
+
|
96
|
+
COLLAPSE_SUBSTITUTIONS = {
|
97
|
+
'Show ' => 'Hide ',
|
98
|
+
'show ' => 'hide ',
|
99
|
+
'Expand ' => 'Collapse ',
|
100
|
+
'expand ' => 'collapse ',
|
101
|
+
' More' => ' Less',
|
102
|
+
' more' => ' less'
|
103
|
+
}
|
104
|
+
|
62
105
|
def collapse(label, opts = {}, &block)
|
63
106
|
raise 'expected a block' unless block_given?
|
64
107
|
|
65
|
-
|
108
|
+
return accordian_collapse(label, opts, &block) if @_accordion_active
|
109
|
+
|
110
|
+
id = "collapse-#{effective_bootstrap_unique_id}"
|
66
111
|
show = (opts.delete(:show) == true)
|
67
112
|
|
113
|
+
# Figure out all the button / link options
|
68
114
|
link_opts = { 'data-toggle': 'collapse', role: 'button', href: "##{id}", 'aria-controls': "##{id}", 'aria-expanded': show }
|
69
115
|
|
116
|
+
# Two link labels
|
117
|
+
label_expand = opts.delete(:expand) || label.to_s.tap do |label|
|
118
|
+
COLLAPSE_SUBSTITUTIONS.each { |show, hide| label.sub!(hide, show) }
|
119
|
+
end + icon('chevron-down')
|
120
|
+
|
121
|
+
label_collapse = opts.delete(:collapse) || label.to_s.tap do |label|
|
122
|
+
COLLAPSE_SUBSTITUTIONS.each { |show, hide| label.sub!(show, hide) }
|
123
|
+
end + icon('chevron-up')
|
124
|
+
|
125
|
+
# The link html classes
|
70
126
|
link_opts[:class] = opts.delete(:link_class) || 'btn btn-link'
|
127
|
+
link_opts[:class] += ' effective-collapse-actions hidden-print'
|
128
|
+
link_opts[:class] += ' collapsed' unless show
|
129
|
+
|
130
|
+
# The div and the card now
|
71
131
|
div_class = opts.delete(:div_class)
|
72
132
|
card_class = opts.delete(:card_class) || 'card card-body my-2'
|
73
133
|
|
74
|
-
|
75
|
-
|
76
|
-
content_tag(:div, class:
|
77
|
-
|
78
|
-
content_tag(:h2, class: "mb-0") do
|
79
|
-
content_tag(:button, label, link_opts.merge(class: "btn btn-link"))
|
80
|
-
end
|
81
|
-
end +
|
82
|
-
content_tag(:div, id: id, class: ['collapse', div_class, ('show' if show)].compact.join(' '), "data-parent": "##{@_accordion_active}") do
|
83
|
-
content_tag(:div, capture(&block), class: "card-body")
|
84
|
-
end
|
85
|
-
end
|
86
|
-
else
|
87
|
-
# Normal collapse
|
88
|
-
content_tag(:a, label, link_opts) +
|
89
|
-
content_tag(:div, id: id, class: ['collapse', div_class, ('show' if show)].compact.join(' ')) do
|
90
|
-
content_tag(:div, capture(&block), class: card_class)
|
91
|
-
end
|
134
|
+
# Normal collapse
|
135
|
+
link_tag = content_tag(:a, link_opts) do
|
136
|
+
content_tag(:div, label_expand.html_safe, class: 'collapse-label-expand') +
|
137
|
+
content_tag(:div, label_collapse.html_safe, class: 'collapse-label-collapse')
|
92
138
|
end
|
139
|
+
|
140
|
+
div_tag = content_tag(:div, id: id, class: ['effective-collapse collapse', div_class, ('show' if show)].compact.join(' ')) do
|
141
|
+
content_tag(:div, capture(&block), class: card_class)
|
142
|
+
end
|
143
|
+
|
144
|
+
link_tag + div_tag
|
93
145
|
end
|
94
146
|
|
95
147
|
# Button Dropdowns
|
@@ -259,7 +311,7 @@ module EffectiveBootstrapHelper
|
|
259
311
|
def nav_dropdown(label, right: false, link_class: [], list_class: [], &block)
|
260
312
|
raise 'expected a block' unless block_given?
|
261
313
|
|
262
|
-
id = "dropdown-#{
|
314
|
+
id = "dropdown-#{effective_bootstrap_unique_id}"
|
263
315
|
|
264
316
|
content_tag(:li, class: 'nav-item dropdown') do
|
265
317
|
content_tag(:a, class: 'nav-link dropdown-toggle', href: '#', id: id, role: 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) do
|
@@ -436,7 +488,7 @@ module EffectiveBootstrapHelper
|
|
436
488
|
|
437
489
|
@_tab_mode = :tablist
|
438
490
|
@_tab_active = (active || :first)
|
439
|
-
@_tab_unique =
|
491
|
+
@_tab_unique = effective_bootstrap_unique_id if unique
|
440
492
|
|
441
493
|
content_tag(:ul, {class: 'nav nav-tabs', role: 'tablist'}.merge(list)) do
|
442
494
|
yield # Yield to tab the first time
|
@@ -476,7 +528,7 @@ module EffectiveBootstrapHelper
|
|
476
528
|
|
477
529
|
@_tab_mode = :tablist_vertical
|
478
530
|
@_tab_active = (active || :first)
|
479
|
-
@_tab_unique =
|
531
|
+
@_tab_unique = effective_bootstrap_unique_id if unique
|
480
532
|
|
481
533
|
content_tag(:div, class: 'row border') do
|
482
534
|
content_tag(:div, class: 'col-3 border-right') do
|
@@ -504,4 +556,15 @@ module EffectiveBootstrapHelper
|
|
504
556
|
end
|
505
557
|
end
|
506
558
|
|
559
|
+
def effective_bootstrap_unique_id
|
560
|
+
# Set the first unique value
|
561
|
+
@_effective_bootstrap_unique_id ||= Time.zone.now.to_i
|
562
|
+
|
563
|
+
# Everytime we access this function make a new one
|
564
|
+
@_effective_bootstrap_unique_id = @_effective_bootstrap_unique_id + 1
|
565
|
+
|
566
|
+
# Return the updated value
|
567
|
+
@_effective_bootstrap_unique_id
|
568
|
+
end
|
569
|
+
|
507
570
|
end
|
@@ -51,6 +51,20 @@ module Effective
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# insert: false
|
55
|
+
def insert
|
56
|
+
return @insert unless @insert.nil?
|
57
|
+
|
58
|
+
@insert ||= begin
|
59
|
+
insert = options[:input].delete(:insert)
|
60
|
+
insert.nil? ? false : insert
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def insert?
|
65
|
+
!!insert
|
66
|
+
end
|
67
|
+
|
54
68
|
# errors: true
|
55
69
|
def errors?
|
56
70
|
return @errors unless @errors.nil?
|
@@ -62,7 +76,7 @@ module Effective
|
|
62
76
|
end
|
63
77
|
|
64
78
|
# remove: true
|
65
|
-
def remove
|
79
|
+
def remove
|
66
80
|
return @remove unless @remove.nil?
|
67
81
|
|
68
82
|
@remove ||= begin
|
@@ -77,6 +91,10 @@ module Effective
|
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
94
|
+
def remove?
|
95
|
+
!!remove
|
96
|
+
end
|
97
|
+
|
80
98
|
def can_remove_method
|
81
99
|
return @can_remove_method unless @can_remove_method.nil?
|
82
100
|
@can_remove_method = (options[:input].delete(:can_remove_method) || false)
|
@@ -114,6 +132,7 @@ module Effective
|
|
114
132
|
def render_resource(resource, block)
|
115
133
|
remove = BLANK
|
116
134
|
reorder = BLANK
|
135
|
+
insert = BLANK
|
117
136
|
can_remove = (can_remove_method.blank? || !!resource.send(can_remove_method))
|
118
137
|
|
119
138
|
content = @builder.fields_for(name, resource) do |form|
|
@@ -129,7 +148,11 @@ module Effective
|
|
129
148
|
remove += (can_remove || resource.new_record?) ? link_to_remove(resource) : disabled_link_to_remove(resource)
|
130
149
|
end
|
131
150
|
|
132
|
-
|
151
|
+
if insert?
|
152
|
+
insert = render_insert() if add? && reorder?
|
153
|
+
end
|
154
|
+
|
155
|
+
content_tag(:div, insert + render_fields(content, remove + reorder), class: 'has-many-fields')
|
133
156
|
end
|
134
157
|
|
135
158
|
def render_fields(content, remove)
|
@@ -141,12 +164,25 @@ module Effective
|
|
141
164
|
content_tag(:div, remove, class: 'col-auto')
|
142
165
|
end
|
143
166
|
when :cards
|
144
|
-
|
167
|
+
content_tag(:div, class: 'form-row mb-3') do
|
168
|
+
(reorder? ? content_tag(:div, has_many_move, class: 'col-auto') : BLANK) +
|
169
|
+
content_tag(:div, content, class: 'col mr-auto') do
|
170
|
+
content_tag(:div, class: 'card') do
|
171
|
+
content_tag(:div, class: 'card-body') do
|
172
|
+
content_tag(:div, remove, class: 'float-right') + content
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
145
177
|
else
|
146
178
|
content + remove
|
147
179
|
end
|
148
180
|
end
|
149
181
|
|
182
|
+
def render_insert()
|
183
|
+
content_tag(:div, link_to_insert(), class: 'has-many-actions')
|
184
|
+
end
|
185
|
+
|
150
186
|
def render_template(block)
|
151
187
|
resource = build_resource()
|
152
188
|
index = collection.length
|
@@ -176,6 +212,27 @@ module Effective
|
|
176
212
|
)
|
177
213
|
end
|
178
214
|
|
215
|
+
# f.has_many :things, insert: { label: (icon('plus-circle') + 'Insert Article') }
|
216
|
+
# f.has_many :things, insert: (icon('plus-circle') + 'Insert Article')
|
217
|
+
def link_to_insert
|
218
|
+
tag = (insert[:tag] if insert.kind_of?(Hash))
|
219
|
+
title = (insert[:title] || insert[:label] if insert.kind_of?(Hash))
|
220
|
+
html_class = (insert[:class] if insert.kind_of?(Hash))
|
221
|
+
|
222
|
+
label = (insert[:label] if insert.kind_of?(Hash))
|
223
|
+
label = insert if insert.kind_of?(String)
|
224
|
+
|
225
|
+
content_tag(
|
226
|
+
(tag || :button),
|
227
|
+
(label || (icon('plus-circle') + 'Insert Another')),
|
228
|
+
class: 'has-many-insert ' + (html_class || 'btn btn-secondary'),
|
229
|
+
title: (title || 'Insert Another'),
|
230
|
+
data: {
|
231
|
+
'effective-form-has-many-insert': true,
|
232
|
+
}
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
179
236
|
def link_to_reorder(block)
|
180
237
|
content_tag(
|
181
238
|
:button,
|
@@ -189,11 +246,18 @@ module Effective
|
|
189
246
|
end
|
190
247
|
|
191
248
|
def link_to_remove(resource)
|
249
|
+
tag = (remove[:tag] if remove.kind_of?(Hash))
|
250
|
+
title = (remove[:title] || remove[:label] if remove.kind_of?(Hash))
|
251
|
+
html_class = (remove[:class] if remove.kind_of?(Hash))
|
252
|
+
|
253
|
+
label = (remove[:label] if remove.kind_of?(Hash))
|
254
|
+
label = remove if remove.kind_of?(String)
|
255
|
+
|
192
256
|
content_tag(
|
193
|
-
:button,
|
194
|
-
icon('trash-2'),
|
195
|
-
class: 'has-many-remove btn btn-danger',
|
196
|
-
title: 'Remove',
|
257
|
+
(tag || :button),
|
258
|
+
(label || icon('trash-2')),
|
259
|
+
class: 'has-many-remove ' + (html_class || 'btn btn-danger'),
|
260
|
+
title: (title || 'Remove'),
|
197
261
|
data: {
|
198
262
|
'confirm': "Remove #{resource}?",
|
199
263
|
'effective-form-has-many-remove': true,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_bootstrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.40
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -615,6 +615,7 @@ files:
|
|
615
615
|
- app/assets/stylesheets/effective_article_editor/input.scss
|
616
616
|
- app/assets/stylesheets/effective_bootstrap.scss
|
617
617
|
- app/assets/stylesheets/effective_bootstrap/base.scss
|
618
|
+
- app/assets/stylesheets/effective_bootstrap/collapse.scss
|
618
619
|
- app/assets/stylesheets/effective_bootstrap/forms.scss
|
619
620
|
- app/assets/stylesheets/effective_bootstrap/icons.scss
|
620
621
|
- app/assets/stylesheets/effective_bootstrap/overrides.scss
|