headmin 0.4.0 → 0.4.1
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/Gemfile.lock +1 -1
- data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +84 -21
- data/app/assets/javascripts/headmin/controllers/popup_controller.js +11 -4
- data/app/assets/javascripts/headmin.js +67 -18
- data/app/assets/stylesheets/headmin/general.scss +9 -0
- data/app/assets/stylesheets/headmin.css +4 -0
- data/app/models/headmin/form/blocks_view.rb +1 -1
- data/app/models/headmin/form/checkbox_view.rb +3 -3
- data/app/models/headmin/form/date_range_view.rb +2 -2
- data/app/models/headmin/form/date_view.rb +5 -5
- data/app/models/headmin/form/email_view.rb +7 -7
- data/app/models/headmin/form/file_view.rb +6 -6
- data/app/models/headmin/form/flatpickr_range_view.rb +7 -7
- data/app/models/headmin/form/flatpickr_view.rb +3 -3
- data/app/models/headmin/form/input_group_view.rb +1 -1
- data/app/models/headmin/form/label_view.rb +1 -1
- data/app/models/headmin/form/number_view.rb +5 -5
- data/app/models/headmin/form/password_view.rb +5 -5
- data/app/models/headmin/form/redactorx_view.rb +2 -2
- data/app/models/headmin/form/search_view.rb +7 -7
- data/app/models/headmin/form/select_view.rb +6 -6
- data/app/models/headmin/form/switch_view.rb +1 -1
- data/app/models/headmin/form/text_view.rb +7 -7
- data/app/models/headmin/form/textarea_view.rb +5 -5
- data/app/models/headmin/form/url_view.rb +7 -7
- data/app/models/headmin/form/wrapper_view.rb +1 -1
- data/app/models/headmin/form/wysiwyg_view.rb +1 -1
- data/app/views/headmin/forms/fields/_group.html.erb +5 -0
- data/config/locales/headmin/forms/en.yml +1 -1
- data/config/locales/headmin/forms/nl.yml +1 -1
- data/lib/headmin/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 503fa2fc7ec041e2a3baca7937f969f7cc8061da02fcb698924f43f3ccc384f9
|
4
|
+
data.tar.gz: 88ad583e50e5d72b8f08c6212bdee24ce1f504d4776bcf0ff6c21faadb37db6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bc9c3497c44c255eca104e024d672fa37041029c0da730ee257078f42a72b2d299b427c636b52ee6d0a370c41576d16af83b2ec55db4ad90418f104dbe406e9
|
7
|
+
data.tar.gz: ccecbb9860f879f0bd398954e67f546671e090a230a5f812bff8c59dd268e62755147ee4d14b3eafd7a59f182c39ee012f70e234ea14b47e58a63ef60dea71c7
|
data/Gemfile.lock
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* global fetch */
|
1
|
+
/* global fetch, Event */
|
2
2
|
import { Controller } from '@hotwired/stimulus'
|
3
3
|
|
4
4
|
export default class extends Controller {
|
@@ -18,11 +18,16 @@ export default class extends Controller {
|
|
18
18
|
this.show()
|
19
19
|
})
|
20
20
|
|
21
|
-
//
|
21
|
+
// Navigation
|
22
22
|
this.inputTarget.addEventListener('keydown', (event) => {
|
23
23
|
this.handleKeydown(event)
|
24
24
|
})
|
25
25
|
|
26
|
+
// Typing
|
27
|
+
this.inputTarget.addEventListener('keyup', (event) => {
|
28
|
+
this.handleKeyup(event)
|
29
|
+
})
|
30
|
+
|
26
31
|
// Clicked outside dropdown
|
27
32
|
document.addEventListener('click', (event) => {
|
28
33
|
this.handleOutsideClick(event)
|
@@ -30,20 +35,33 @@ export default class extends Controller {
|
|
30
35
|
}
|
31
36
|
|
32
37
|
handleKeydown (event) {
|
33
|
-
this.show()
|
34
|
-
|
35
38
|
const keyCode = parseInt(event.keyCode, 10)
|
36
39
|
if (this.isArrowKey(keyCode)) {
|
37
40
|
this.handleArrowKey(keyCode)
|
38
|
-
}
|
39
|
-
|
40
|
-
|
41
|
-
this.
|
41
|
+
}
|
42
|
+
|
43
|
+
if (this.isEnterKey(keyCode)) {
|
44
|
+
this.selectActiveItem(event)
|
42
45
|
}
|
43
46
|
}
|
44
47
|
|
45
|
-
|
46
|
-
|
48
|
+
handleKeyup (event) {
|
49
|
+
// Ignore arrow keys or enters
|
50
|
+
const keyCode = parseInt(event.keyCode, 10)
|
51
|
+
if (this.isArrowKey(keyCode) || this.isEnterKey(keyCode)) {
|
52
|
+
return false
|
53
|
+
}
|
54
|
+
|
55
|
+
this.handleTextKey()
|
56
|
+
}
|
57
|
+
|
58
|
+
selectActiveItem (event) {
|
59
|
+
const activeItem = this.activeItem()
|
60
|
+
if (activeItem) {
|
61
|
+
this.deselectAll()
|
62
|
+
this.setValue(activeItem.getAttribute('value'))
|
63
|
+
event.preventDefault()
|
64
|
+
}
|
47
65
|
}
|
48
66
|
|
49
67
|
isEnterKey (keyCode) {
|
@@ -51,6 +69,7 @@ export default class extends Controller {
|
|
51
69
|
}
|
52
70
|
|
53
71
|
handleArrowKey (keyCode) {
|
72
|
+
this.show()
|
54
73
|
switch (keyCode) {
|
55
74
|
case 38:
|
56
75
|
this.handleArrowUp()
|
@@ -72,8 +91,10 @@ export default class extends Controller {
|
|
72
91
|
|
73
92
|
selectNextItem () {
|
74
93
|
const next = this.nextItem()
|
75
|
-
|
76
|
-
|
94
|
+
if (next) {
|
95
|
+
this.deselectAll()
|
96
|
+
next.classList.add('active')
|
97
|
+
}
|
77
98
|
}
|
78
99
|
|
79
100
|
nextItem () {
|
@@ -94,8 +115,10 @@ export default class extends Controller {
|
|
94
115
|
|
95
116
|
selectPreviousItem () {
|
96
117
|
const previous = this.previousItem()
|
97
|
-
|
98
|
-
|
118
|
+
if (previous) {
|
119
|
+
this.deselectAll()
|
120
|
+
previous.classList.add('active')
|
121
|
+
}
|
99
122
|
}
|
100
123
|
|
101
124
|
previousItem () {
|
@@ -160,13 +183,22 @@ export default class extends Controller {
|
|
160
183
|
// 2. render html
|
161
184
|
this.renderCollection(html)
|
162
185
|
}).then(() => {
|
163
|
-
// 3.
|
164
|
-
// ...
|
165
|
-
// 4. Highlight
|
186
|
+
// 3. Highlight
|
166
187
|
this.highlight()
|
188
|
+
}).then(() => {
|
189
|
+
// 4. Preselect first result
|
190
|
+
this.activateFirstItem()
|
191
|
+
}).then(() => {
|
192
|
+
// 5. Show results
|
193
|
+
this.show()
|
167
194
|
})
|
168
195
|
}
|
169
196
|
|
197
|
+
activateFirstItem () {
|
198
|
+
this.deselectAll()
|
199
|
+
this.firstItem().classList.add('active')
|
200
|
+
}
|
201
|
+
|
170
202
|
show () {
|
171
203
|
if (this.isDropdownEmpty()) {
|
172
204
|
this.dropdownTarget.classList.remove('d-none')
|
@@ -190,7 +222,7 @@ export default class extends Controller {
|
|
190
222
|
|
191
223
|
fetchCollection () {
|
192
224
|
if (this.isRemote()) {
|
193
|
-
return fetch(this.
|
225
|
+
return fetch(this.remoteURL()).then((response) => {
|
194
226
|
return response.text()
|
195
227
|
}).catch((error) => {
|
196
228
|
console.error('The URL you provided for the autocomplete collection didn\'t return a successful result', error)
|
@@ -200,6 +232,29 @@ export default class extends Controller {
|
|
200
232
|
}
|
201
233
|
}
|
202
234
|
|
235
|
+
remoteURL () {
|
236
|
+
// Set dummy base in case a relative path is provided as remote URL
|
237
|
+
const base = 'https://example.com'
|
238
|
+
const url = new URL(this.urlValue, base)
|
239
|
+
|
240
|
+
// Update pagination params
|
241
|
+
const params = new URLSearchParams(url.search)
|
242
|
+
params.set('search', this.value())
|
243
|
+
params.set('page', '1')
|
244
|
+
params.set('per_page', '6')
|
245
|
+
url.search = params.toString()
|
246
|
+
|
247
|
+
// Convert to string
|
248
|
+
let urlString = url.toString()
|
249
|
+
|
250
|
+
// Convert back to relative url if needed
|
251
|
+
if (urlString.includes(base)) {
|
252
|
+
urlString = urlString.replace(base, '')
|
253
|
+
}
|
254
|
+
|
255
|
+
return urlString
|
256
|
+
}
|
257
|
+
|
203
258
|
renderCollection (html) {
|
204
259
|
this.dropdownTarget.innerHTML = html
|
205
260
|
}
|
@@ -217,15 +272,23 @@ export default class extends Controller {
|
|
217
272
|
text = text.replace(/<mark.*?>(.*?)<\/mark>/ig, '$1')
|
218
273
|
|
219
274
|
// Highlight query
|
220
|
-
|
221
|
-
|
275
|
+
if (query && query.length > 0) {
|
276
|
+
// Ignore all strings inside < >
|
277
|
+
const regex2 = new RegExp(`(?<!<[^>]*?)( )?(${query})`, 'gi')
|
278
|
+
text = text.replace(regex2, '<mark>$2</mark>')
|
279
|
+
}
|
222
280
|
|
223
281
|
dropdownItem.innerHTML = text
|
224
282
|
})
|
225
283
|
}
|
226
284
|
|
227
285
|
select (event) {
|
228
|
-
this.
|
286
|
+
this.setValue(event.currentTarget.getAttribute('value'))
|
287
|
+
}
|
288
|
+
|
289
|
+
setValue (value) {
|
290
|
+
this.inputTarget.value = value
|
291
|
+
this.inputTarget.dispatchEvent(new Event('change'))
|
229
292
|
this.hide()
|
230
293
|
}
|
231
294
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* global HTMLInputElement */
|
1
2
|
import { Controller } from '@hotwired/stimulus'
|
2
3
|
import { createPopper } from '@popperjs/core'
|
3
4
|
|
@@ -32,14 +33,20 @@ export default class extends Controller {
|
|
32
33
|
const popup = this.popupById(button.dataset.popupId)
|
33
34
|
const passThru = button.dataset.popupPassThru
|
34
35
|
|
36
|
+
// Open the popup
|
37
|
+
createPopper(button, popup)
|
38
|
+
this.openPopup(popup)
|
39
|
+
|
35
40
|
if (passThru) {
|
36
41
|
// Pass click event to an element inside the popup
|
37
42
|
const passThruElement = popup.querySelector(passThru)
|
38
43
|
passThruElement.click()
|
39
|
-
|
40
|
-
//
|
41
|
-
|
42
|
-
|
44
|
+
|
45
|
+
// Focus and select value if it's an input element
|
46
|
+
if (passThruElement instanceof HTMLInputElement) {
|
47
|
+
passThruElement.focus()
|
48
|
+
passThruElement.select()
|
49
|
+
}
|
43
50
|
}
|
44
51
|
}
|
45
52
|
|
@@ -4979,28 +4979,42 @@ var autocomplete_controller_default = class extends Controller {
|
|
4979
4979
|
this.inputTarget.addEventListener("keydown", (event) => {
|
4980
4980
|
this.handleKeydown(event);
|
4981
4981
|
});
|
4982
|
+
this.inputTarget.addEventListener("keyup", (event) => {
|
4983
|
+
this.handleKeyup(event);
|
4984
|
+
});
|
4982
4985
|
document.addEventListener("click", (event) => {
|
4983
4986
|
this.handleOutsideClick(event);
|
4984
4987
|
});
|
4985
4988
|
}
|
4986
4989
|
handleKeydown(event) {
|
4987
|
-
this.show();
|
4988
4990
|
const keyCode = parseInt(event.keyCode, 10);
|
4989
4991
|
if (this.isArrowKey(keyCode)) {
|
4990
4992
|
this.handleArrowKey(keyCode);
|
4991
|
-
}
|
4992
|
-
|
4993
|
-
|
4994
|
-
this.handleTextKey();
|
4993
|
+
}
|
4994
|
+
if (this.isEnterKey(keyCode)) {
|
4995
|
+
this.selectActiveItem(event);
|
4995
4996
|
}
|
4996
4997
|
}
|
4997
|
-
|
4998
|
-
|
4998
|
+
handleKeyup(event) {
|
4999
|
+
const keyCode = parseInt(event.keyCode, 10);
|
5000
|
+
if (this.isArrowKey(keyCode) || this.isEnterKey(keyCode)) {
|
5001
|
+
return false;
|
5002
|
+
}
|
5003
|
+
this.handleTextKey();
|
5004
|
+
}
|
5005
|
+
selectActiveItem(event) {
|
5006
|
+
const activeItem = this.activeItem();
|
5007
|
+
if (activeItem) {
|
5008
|
+
this.deselectAll();
|
5009
|
+
this.setValue(activeItem.getAttribute("value"));
|
5010
|
+
event.preventDefault();
|
5011
|
+
}
|
4999
5012
|
}
|
5000
5013
|
isEnterKey(keyCode) {
|
5001
5014
|
return keyCode === 13;
|
5002
5015
|
}
|
5003
5016
|
handleArrowKey(keyCode) {
|
5017
|
+
this.show();
|
5004
5018
|
switch (keyCode) {
|
5005
5019
|
case 38:
|
5006
5020
|
this.handleArrowUp();
|
@@ -5019,8 +5033,10 @@ var autocomplete_controller_default = class extends Controller {
|
|
5019
5033
|
}
|
5020
5034
|
selectNextItem() {
|
5021
5035
|
const next = this.nextItem();
|
5022
|
-
|
5023
|
-
|
5036
|
+
if (next) {
|
5037
|
+
this.deselectAll();
|
5038
|
+
next.classList.add("active");
|
5039
|
+
}
|
5024
5040
|
}
|
5025
5041
|
nextItem() {
|
5026
5042
|
const current = this.activeItem();
|
@@ -5036,8 +5052,10 @@ var autocomplete_controller_default = class extends Controller {
|
|
5036
5052
|
}
|
5037
5053
|
selectPreviousItem() {
|
5038
5054
|
const previous = this.previousItem();
|
5039
|
-
|
5040
|
-
|
5055
|
+
if (previous) {
|
5056
|
+
this.deselectAll();
|
5057
|
+
previous.classList.add("active");
|
5058
|
+
}
|
5041
5059
|
}
|
5042
5060
|
previousItem() {
|
5043
5061
|
const current = this.activeItem();
|
@@ -5087,8 +5105,16 @@ var autocomplete_controller_default = class extends Controller {
|
|
5087
5105
|
this.renderCollection(html);
|
5088
5106
|
}).then(() => {
|
5089
5107
|
this.highlight();
|
5108
|
+
}).then(() => {
|
5109
|
+
this.activateFirstItem();
|
5110
|
+
}).then(() => {
|
5111
|
+
this.show();
|
5090
5112
|
});
|
5091
5113
|
}
|
5114
|
+
activateFirstItem() {
|
5115
|
+
this.deselectAll();
|
5116
|
+
this.firstItem().classList.add("active");
|
5117
|
+
}
|
5092
5118
|
show() {
|
5093
5119
|
if (this.isDropdownEmpty()) {
|
5094
5120
|
this.dropdownTarget.classList.remove("d-none");
|
@@ -5108,7 +5134,7 @@ var autocomplete_controller_default = class extends Controller {
|
|
5108
5134
|
}
|
5109
5135
|
fetchCollection() {
|
5110
5136
|
if (this.isRemote()) {
|
5111
|
-
return fetch(this.
|
5137
|
+
return fetch(this.remoteURL()).then((response) => {
|
5112
5138
|
return response.text();
|
5113
5139
|
}).catch((error2) => {
|
5114
5140
|
console.error("The URL you provided for the autocomplete collection didn't return a successful result", error2);
|
@@ -5117,6 +5143,20 @@ var autocomplete_controller_default = class extends Controller {
|
|
5117
5143
|
return Promise.resolve(this.dropdownTarget.innerHTML);
|
5118
5144
|
}
|
5119
5145
|
}
|
5146
|
+
remoteURL() {
|
5147
|
+
const base = "https://example.com";
|
5148
|
+
const url = new URL(this.urlValue, base);
|
5149
|
+
const params = new URLSearchParams(url.search);
|
5150
|
+
params.set("search", this.value());
|
5151
|
+
params.set("page", "1");
|
5152
|
+
params.set("per_page", "6");
|
5153
|
+
url.search = params.toString();
|
5154
|
+
let urlString = url.toString();
|
5155
|
+
if (urlString.includes(base)) {
|
5156
|
+
urlString = urlString.replace(base, "");
|
5157
|
+
}
|
5158
|
+
return urlString;
|
5159
|
+
}
|
5120
5160
|
renderCollection(html) {
|
5121
5161
|
this.dropdownTarget.innerHTML = html;
|
5122
5162
|
}
|
@@ -5128,13 +5168,19 @@ var autocomplete_controller_default = class extends Controller {
|
|
5128
5168
|
this.dropdownItemTargets.forEach((dropdownItem) => {
|
5129
5169
|
let text = dropdownItem.innerHTML;
|
5130
5170
|
text = text.replace(/<mark.*?>(.*?)<\/mark>/ig, "$1");
|
5131
|
-
|
5132
|
-
|
5171
|
+
if (query && query.length > 0) {
|
5172
|
+
const regex2 = new RegExp(`(?<!<[^>]*?)( )?(${query})`, "gi");
|
5173
|
+
text = text.replace(regex2, "<mark>$2</mark>");
|
5174
|
+
}
|
5133
5175
|
dropdownItem.innerHTML = text;
|
5134
5176
|
});
|
5135
5177
|
}
|
5136
5178
|
select(event) {
|
5137
|
-
this.
|
5179
|
+
this.setValue(event.currentTarget.getAttribute("value"));
|
5180
|
+
}
|
5181
|
+
setValue(value) {
|
5182
|
+
this.inputTarget.value = value;
|
5183
|
+
this.inputTarget.dispatchEvent(new Event("change"));
|
5138
5184
|
this.hide();
|
5139
5185
|
}
|
5140
5186
|
value() {
|
@@ -15046,12 +15092,15 @@ var popup_controller_default = class extends Controller {
|
|
15046
15092
|
const button = event.target.closest('[data-popup-target="button"]');
|
15047
15093
|
const popup = this.popupById(button.dataset.popupId);
|
15048
15094
|
const passThru = button.dataset.popupPassThru;
|
15095
|
+
createPopper3(button, popup);
|
15096
|
+
this.openPopup(popup);
|
15049
15097
|
if (passThru) {
|
15050
15098
|
const passThruElement = popup.querySelector(passThru);
|
15051
15099
|
passThruElement.click();
|
15052
|
-
|
15053
|
-
|
15054
|
-
|
15100
|
+
if (passThruElement instanceof HTMLInputElement) {
|
15101
|
+
passThruElement.focus();
|
15102
|
+
passThruElement.select();
|
15103
|
+
}
|
15055
15104
|
}
|
15056
15105
|
}
|
15057
15106
|
close(event) {
|
@@ -13103,6 +13103,10 @@ input[type=search] {
|
|
13103
13103
|
}
|
13104
13104
|
html {
|
13105
13105
|
height: 100%;
|
13106
|
+
background: red;
|
13107
|
+
}
|
13108
|
+
.list-group-item.active .text-muted {
|
13109
|
+
color: #fff !important;
|
13106
13110
|
}
|
13107
13111
|
mark,
|
13108
13112
|
.mark {
|
@@ -17,7 +17,7 @@ module Headmin
|
|
17
17
|
def input_options
|
18
18
|
keys = attributes - %i[attribute form label validate wrapper checked_value unchecked_value]
|
19
19
|
options = to_h.slice(*keys)
|
20
|
-
default_input_options.
|
20
|
+
default_input_options.deep_merge(options)
|
21
21
|
end
|
22
22
|
|
23
23
|
def label_options
|
@@ -31,11 +31,11 @@ module Headmin
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def wrapper_options
|
34
|
-
default_wrapper_options.
|
34
|
+
default_wrapper_options.deep_merge(
|
35
35
|
{
|
36
36
|
class: %w[form-check mb-3]
|
37
37
|
}
|
38
|
-
).
|
38
|
+
).deep_merge(@wrapper || {})
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
@@ -2,11 +2,11 @@ module Headmin
|
|
2
2
|
module Form
|
3
3
|
class DateRangeView < ViewModel
|
4
4
|
def start_options
|
5
|
-
default_start_options.
|
5
|
+
default_start_options.deep_merge(@start || {})
|
6
6
|
end
|
7
7
|
|
8
8
|
def end_options
|
9
|
-
default_end_options.
|
9
|
+
default_end_options.deep_merge(@end || {})
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
@@ -12,19 +12,19 @@ module Headmin
|
|
12
12
|
def input_options
|
13
13
|
keys = attributes - %i[append attribute float form input_group input_group label prepend validate wrapper]
|
14
14
|
options = to_h.slice(*keys)
|
15
|
-
default_input_options.
|
15
|
+
default_input_options.deep_merge(options)
|
16
16
|
end
|
17
17
|
|
18
18
|
def input_group_options
|
19
19
|
default_input_group_options
|
20
|
-
.
|
21
|
-
.
|
20
|
+
.deep_merge(label_input_group_options)
|
21
|
+
.deep_merge(@input_group || {})
|
22
22
|
end
|
23
23
|
|
24
24
|
def wrapper_options
|
25
|
-
default_wrapper_options.
|
25
|
+
default_wrapper_options.deep_merge({
|
26
26
|
class: ["mb-3", ("form-floating" if float)]
|
27
|
-
}).
|
27
|
+
}).deep_merge(@wrapper || {})
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
@@ -13,21 +13,21 @@ module Headmin
|
|
13
13
|
def input_options
|
14
14
|
keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
|
15
15
|
options = to_h.slice(*keys)
|
16
|
-
options = default_input_options.
|
17
|
-
options.
|
16
|
+
options = default_input_options.deep_merge(options)
|
17
|
+
options.deep_merge(autocomplete_input_options)
|
18
18
|
end
|
19
19
|
|
20
20
|
def input_group_options
|
21
21
|
default_input_group_options
|
22
|
-
.
|
23
|
-
.
|
24
|
-
.
|
22
|
+
.deep_merge(autocomplete_input_group_options)
|
23
|
+
.deep_merge(label_input_group_options)
|
24
|
+
.deep_merge(@input_group || {})
|
25
25
|
end
|
26
26
|
|
27
27
|
def wrapper_options
|
28
|
-
default_wrapper_options.
|
28
|
+
default_wrapper_options.deep_merge({
|
29
29
|
class: ["mb-3", ("form-floating" if float)]
|
30
|
-
}).
|
30
|
+
}).deep_merge(@wrapper || {})
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
@@ -11,24 +11,24 @@ module Headmin
|
|
11
11
|
def input_options
|
12
12
|
keys = attributes - %i[append attribute dropzone destroy form input_group label prepend preview validate wrapper]
|
13
13
|
options = to_h.slice(*keys)
|
14
|
-
options = default_input_options.
|
15
|
-
options = options.
|
14
|
+
options = default_input_options.deep_merge(options)
|
15
|
+
options = options.deep_merge(required: false) if attachments.any?
|
16
16
|
options
|
17
17
|
end
|
18
18
|
|
19
19
|
def input_group_options
|
20
20
|
default_input_group_options
|
21
|
-
.
|
22
|
-
.
|
21
|
+
.deep_merge(label_input_group_options)
|
22
|
+
.deep_merge(@input_group || {})
|
23
23
|
end
|
24
24
|
|
25
25
|
def wrapper_options
|
26
|
-
default_wrapper_options.
|
26
|
+
default_wrapper_options.deep_merge({
|
27
27
|
class: ["mb-3 h-form-file", ("form-floating" if float)],
|
28
28
|
data: {
|
29
29
|
controller: ("file-preview" if preview)
|
30
30
|
}
|
31
|
-
}).
|
31
|
+
}).deep_merge(@wrapper || {})
|
32
32
|
end
|
33
33
|
|
34
34
|
def preview
|
@@ -22,32 +22,32 @@ module Headmin
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def start_options
|
25
|
-
default_start_options.
|
25
|
+
default_start_options.deep_merge(@start || {})
|
26
26
|
end
|
27
27
|
|
28
28
|
def end_options
|
29
|
-
default_end_options.
|
29
|
+
default_end_options.deep_merge(@end || {})
|
30
30
|
end
|
31
31
|
|
32
32
|
def input_options
|
33
33
|
keys = attributes - %i[append attribute end float form input_group label prepend start validate wrapper]
|
34
34
|
options = to_h.slice(*keys)
|
35
|
-
default_input_options.
|
35
|
+
default_input_options.deep_merge(options)
|
36
36
|
end
|
37
37
|
|
38
38
|
def input_group_options
|
39
39
|
default_input_group_options
|
40
|
-
.
|
41
|
-
.
|
40
|
+
.deep_merge(label_input_group_options)
|
41
|
+
.deep_merge(@input_group || {})
|
42
42
|
end
|
43
43
|
|
44
44
|
def wrapper_options
|
45
|
-
default_wrapper_options.
|
45
|
+
default_wrapper_options.deep_merge({
|
46
46
|
class: ["mb-3", ("form-floating" if float)],
|
47
47
|
data: {
|
48
48
|
controller: "flatpickr date-range"
|
49
49
|
}
|
50
|
-
}).
|
50
|
+
}).deep_merge(@wrapper || {})
|
51
51
|
end
|
52
52
|
|
53
53
|
private
|
@@ -4,15 +4,15 @@ module Headmin
|
|
4
4
|
def options
|
5
5
|
keys = attributes - %i[data wrapper]
|
6
6
|
options = to_h.slice(*keys)
|
7
|
-
default_options.
|
7
|
+
default_options.deep_merge(options)
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def default_options
|
13
13
|
{
|
14
|
-
data: default_data.
|
15
|
-
wrapper: default_wrapper_options.
|
14
|
+
data: default_data.deep_merge(data || {}),
|
15
|
+
wrapper: default_wrapper_options.deep_merge(wrapper || {})
|
16
16
|
}
|
17
17
|
end
|
18
18
|
|
@@ -12,19 +12,19 @@ module Headmin
|
|
12
12
|
def input_options
|
13
13
|
keys = attributes - %i[append attribute float form input_group label prepend validate wrapper]
|
14
14
|
options = to_h.slice(*keys)
|
15
|
-
default_input_options.
|
15
|
+
default_input_options.deep_merge(options)
|
16
16
|
end
|
17
17
|
|
18
18
|
def input_group_options
|
19
19
|
default_input_group_options
|
20
|
-
.
|
21
|
-
.
|
20
|
+
.deep_merge(label_input_group_options)
|
21
|
+
.deep_merge(@input_group || {})
|
22
22
|
end
|
23
23
|
|
24
24
|
def wrapper_options
|
25
|
-
default_wrapper_options.
|
25
|
+
default_wrapper_options.deep_merge({
|
26
26
|
class: ["mb-3", float_class]
|
27
|
-
}).
|
27
|
+
}).deep_merge(@wrapper || {})
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
@@ -11,19 +11,19 @@ module Headmin
|
|
11
11
|
def input_options
|
12
12
|
keys = attributes - %i[append attribute float form input_group label prepend validate wrapper]
|
13
13
|
options = to_h.slice(*keys)
|
14
|
-
default_input_options.
|
14
|
+
default_input_options.deep_merge(options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def input_group_options
|
18
18
|
default_input_group_options
|
19
|
-
.
|
20
|
-
.
|
19
|
+
.deep_merge(label_input_group_options)
|
20
|
+
.deep_merge(@input_group || {})
|
21
21
|
end
|
22
22
|
|
23
23
|
def wrapper_options
|
24
|
-
default_wrapper_options.
|
24
|
+
default_wrapper_options.deep_merge({
|
25
25
|
class: ["mb-3", ("form-floating" if float)]
|
26
|
-
}).
|
26
|
+
}).deep_merge(@wrapper || {})
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -2,7 +2,7 @@ module Headmin
|
|
2
2
|
module Form
|
3
3
|
class RedactorxView < ViewModel
|
4
4
|
def options
|
5
|
-
default_options.
|
5
|
+
default_options.deep_merge(to_h)
|
6
6
|
end
|
7
7
|
|
8
8
|
private
|
@@ -39,7 +39,7 @@ module Headmin
|
|
39
39
|
attr_reader :topbar
|
40
40
|
|
41
41
|
def redactor_options
|
42
|
-
default_redactor_options.
|
42
|
+
default_redactor_options.deep_merge(redactor || {})
|
43
43
|
end
|
44
44
|
|
45
45
|
def default_redactor_options
|
@@ -13,21 +13,21 @@ module Headmin
|
|
13
13
|
def input_options
|
14
14
|
keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
|
15
15
|
options = to_h.slice(*keys)
|
16
|
-
options = default_input_options.
|
17
|
-
options.
|
16
|
+
options = default_input_options.deep_merge(options)
|
17
|
+
options.deep_merge(autocomplete_input_options)
|
18
18
|
end
|
19
19
|
|
20
20
|
def input_group_options
|
21
21
|
default_input_group_options
|
22
|
-
.
|
23
|
-
.
|
24
|
-
.
|
22
|
+
.deep_merge(autocomplete_input_group_options)
|
23
|
+
.deep_merge(label_input_group_options)
|
24
|
+
.deep_merge(@input_group || {})
|
25
25
|
end
|
26
26
|
|
27
27
|
def wrapper_options
|
28
|
-
default_wrapper_options.
|
28
|
+
default_wrapper_options.deep_merge({
|
29
29
|
class: ["mb-3", ("form-floating" if float)]
|
30
|
-
}).
|
30
|
+
}).deep_merge(@wrapper || {})
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
@@ -12,25 +12,25 @@ module Headmin
|
|
12
12
|
def input_options
|
13
13
|
keys = attributes - %i[append attribute collection float form input_group include_blank label prepend validate selected tags wrapper]
|
14
14
|
options = to_h.slice(*keys)
|
15
|
-
default_input_options.
|
15
|
+
default_input_options.deep_merge(options)
|
16
16
|
end
|
17
17
|
|
18
18
|
def input_group_options
|
19
19
|
default_input_group_options
|
20
|
-
.
|
21
|
-
.
|
20
|
+
.deep_merge(label_input_group_options)
|
21
|
+
.deep_merge(@input_group || {})
|
22
22
|
end
|
23
23
|
|
24
24
|
def wrapper_options
|
25
|
-
default_wrapper_options.
|
25
|
+
default_wrapper_options.deep_merge({
|
26
26
|
class: ["mb-3", ("form-floating" if float)]
|
27
|
-
}).
|
27
|
+
}).deep_merge(@wrapper || {})
|
28
28
|
end
|
29
29
|
|
30
30
|
def select_options
|
31
31
|
keys = %i[include_blank selected]
|
32
32
|
options = to_h.slice(*keys)
|
33
|
-
default_options.
|
33
|
+
default_options.deep_merge(options)
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
@@ -13,21 +13,21 @@ module Headmin
|
|
13
13
|
def input_options
|
14
14
|
keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
|
15
15
|
options = to_h.slice(*keys)
|
16
|
-
options = default_input_options.
|
17
|
-
options.
|
16
|
+
options = default_input_options.deep_merge(options)
|
17
|
+
options.deep_merge(autocomplete_input_options)
|
18
18
|
end
|
19
19
|
|
20
20
|
def input_group_options
|
21
21
|
default_input_group_options
|
22
|
-
.
|
23
|
-
.
|
24
|
-
.
|
22
|
+
.deep_merge(autocomplete_input_group_options)
|
23
|
+
.deep_merge(label_input_group_options)
|
24
|
+
.deep_merge(@input_group || {})
|
25
25
|
end
|
26
26
|
|
27
27
|
def wrapper_options
|
28
|
-
default_wrapper_options.
|
28
|
+
default_wrapper_options.deep_merge({
|
29
29
|
class: ["mb-3", ("form-floating" if float)]
|
30
|
-
}).
|
30
|
+
}).deep_merge(@wrapper || {})
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
@@ -11,19 +11,19 @@ module Headmin
|
|
11
11
|
def input_options
|
12
12
|
keys = attributes - %i[attribute float form input_group label validate wrapper]
|
13
13
|
options = to_h.slice(*keys)
|
14
|
-
default_input_options.
|
14
|
+
default_input_options.deep_merge(options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def input_group_options
|
18
18
|
default_input_group_options
|
19
|
-
.
|
20
|
-
.
|
19
|
+
.deep_merge(label_input_group_options)
|
20
|
+
.deep_merge(@input_group || {})
|
21
21
|
end
|
22
22
|
|
23
23
|
def wrapper_options
|
24
|
-
default_wrapper_options.
|
24
|
+
default_wrapper_options.deep_merge({
|
25
25
|
class: ["mb-3", ("form-floating" if float)]
|
26
|
-
}).
|
26
|
+
}).deep_merge(@wrapper || {})
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -13,21 +13,21 @@ module Headmin
|
|
13
13
|
def input_options
|
14
14
|
keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
|
15
15
|
options = to_h.slice(*keys)
|
16
|
-
options = default_input_options.
|
17
|
-
options.
|
16
|
+
options = default_input_options.deep_merge(options)
|
17
|
+
options.deep_merge(autocomplete_input_options)
|
18
18
|
end
|
19
19
|
|
20
20
|
def input_group_options
|
21
21
|
default_input_group_options
|
22
|
-
.
|
23
|
-
.
|
24
|
-
.
|
22
|
+
.deep_merge(autocomplete_input_group_options)
|
23
|
+
.deep_merge(label_input_group_options)
|
24
|
+
.deep_merge(@input_group || {})
|
25
25
|
end
|
26
26
|
|
27
27
|
def wrapper_options
|
28
|
-
default_wrapper_options.
|
28
|
+
default_wrapper_options.deep_merge({
|
29
29
|
class: ["mb-3", ("form-floating" if float)]
|
30
|
-
}).
|
30
|
+
}).deep_merge(@wrapper || {})
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
@@ -24,6 +24,7 @@
|
|
24
24
|
# <% end %#>
|
25
25
|
|
26
26
|
label = local_assigns.has_key?(:label) ? label : nil
|
27
|
+
wrapper = local_assigns.has_key?(:wrapper) ? local_assigns[:wrapper] : true
|
27
28
|
show_label = label != false
|
28
29
|
%>
|
29
30
|
|
@@ -32,9 +33,13 @@
|
|
32
33
|
<%= render 'headmin/forms/label', form: form, attribute: :value, text: label || field_label %>
|
33
34
|
<% end %>
|
34
35
|
|
36
|
+
<% if wrapper %>
|
35
37
|
<ul class="list-group mb-3">
|
36
38
|
<li class="list-group-item">
|
37
39
|
<%= yield group %>
|
38
40
|
</li>
|
39
41
|
</ul>
|
42
|
+
<% else %>
|
43
|
+
<%= yield group %>
|
44
|
+
<% end %>
|
40
45
|
<% end %>
|
data/lib/headmin/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: headmin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jef Vlamings
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: closure_tree
|