formstrap 0.3.1 → 0.3.2
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/formstrap/controllers/media_controller.js +5 -11
- data/app/assets/javascripts/formstrap/controllers/nested_preview_controller.js +2 -3
- data/app/assets/javascripts/formstrap/controllers/repeater_controller.js +6 -0
- data/app/assets/javascripts/formstrap.js +10 -12
- data/app/helpers/application_helper.rb +4 -4
- data/app/models/formstrap/media_view.rb +12 -7
- data/app/models/formstrap/thumbnail_view.rb +2 -2
- data/app/views/formstrap/media/_validation.html.erb +2 -0
- data/lib/formstrap/form_builder.rb +1 -1
- data/lib/formstrap/version.rb +1 -1
- data/package.json +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: 98d133e0c15d72418662dbe8a98e296a3c701bc97aa9bec3620fa3f0a346ffec
|
4
|
+
data.tar.gz: f50c6dc41f0809c54e6522e14a718b0a6842a419fc3068928a64e156df771408
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f540f4053664dc2095dd165f5e4d6c2c5a7257a7fe810bed486834b3477d5c0888ca4ee9bfc5f0e9ac8685d86e0f97039e5bde5795013a1e80350246580a35d3
|
7
|
+
data.tar.gz: 7318bdcee8bb2ac4a84a079374fb15b8385e1032186e8ce14cbe00b449b7d33e2f012b887ad5fa35773eebf9ad718a58c5cacb43188300dc59f27486804882b0
|
@@ -114,11 +114,11 @@ export default class extends Controller {
|
|
114
114
|
}
|
115
115
|
|
116
116
|
minActiveItems () {
|
117
|
-
return parseInt(this.
|
117
|
+
return parseInt(this.validationInputTarget.dataset.min, 10) || 0
|
118
118
|
}
|
119
119
|
|
120
120
|
maxActiveItems () {
|
121
|
-
return parseInt(this.
|
121
|
+
return parseInt(this.validationInputTarget.dataset.max, 10) || Infinity
|
122
122
|
}
|
123
123
|
|
124
124
|
resetPositions () {
|
@@ -131,13 +131,7 @@ export default class extends Controller {
|
|
131
131
|
}
|
132
132
|
|
133
133
|
addNewItems (items) {
|
134
|
-
const itemTargetIds = this.itemTargets.map((i) => { return parseInt(i.querySelectorAll('input')[1].value) })
|
135
134
|
items.forEach((item) => {
|
136
|
-
if (itemTargetIds.includes(item.blobId)) {
|
137
|
-
// Do not add this item (as it is already present)
|
138
|
-
return
|
139
|
-
}
|
140
|
-
|
141
135
|
this.addItem(item)
|
142
136
|
})
|
143
137
|
}
|
@@ -211,7 +205,7 @@ export default class extends Controller {
|
|
211
205
|
const returnedBlobIds = elements.map((e) => { return e.blobId })
|
212
206
|
|
213
207
|
items.forEach((item) => {
|
214
|
-
const blobId = parseInt(item.querySelectorAll('input')[1].value)
|
208
|
+
const blobId = parseInt(item.querySelectorAll('input')[1].value, 10)
|
215
209
|
if (returnedBlobIds.includes(blobId)) {
|
216
210
|
// Do not delete this one
|
217
211
|
return
|
@@ -237,7 +231,7 @@ export default class extends Controller {
|
|
237
231
|
|
238
232
|
itemByBlobId (blobId) {
|
239
233
|
return this.itemTargets.find((item) => {
|
240
|
-
return item.querySelector('input[name*=\'blob_id\']').value === blobId
|
234
|
+
return parseInt(item.querySelector('input[name*=\'blob_id\']').value, 10) === blobId
|
241
235
|
})
|
242
236
|
}
|
243
237
|
|
@@ -249,7 +243,7 @@ export default class extends Controller {
|
|
249
243
|
|
250
244
|
activeIds () {
|
251
245
|
return this.activeItems().map((item) => {
|
252
|
-
return item.querySelector('input[name$=\'[blob_id]\']').value
|
246
|
+
return parseInt(item.querySelector('input[name$=\'[blob_id]\']').value, 10)
|
253
247
|
})
|
254
248
|
}
|
255
249
|
}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* global XMLHttpRequest, MutationObserver */
|
1
2
|
import { Controller } from '@hotwired/stimulus'
|
2
3
|
|
3
4
|
export default class extends Controller {
|
@@ -30,7 +31,6 @@ export default class extends Controller {
|
|
30
31
|
}
|
31
32
|
|
32
33
|
autoResizeIframe () {
|
33
|
-
// eslint-disable-next-line no-undef
|
34
34
|
const observer = new MutationObserver((mutations) => {
|
35
35
|
mutations.forEach((mutation) => {
|
36
36
|
this.resizeIframe()
|
@@ -77,7 +77,6 @@ export default class extends Controller {
|
|
77
77
|
|
78
78
|
requestPreview () {
|
79
79
|
// Create an AJAX request
|
80
|
-
// eslint-disable-next-line no-undef
|
81
80
|
const xhr = new XMLHttpRequest()
|
82
81
|
xhr.open('POST', this.urlValue, true)
|
83
82
|
|
@@ -109,7 +108,7 @@ export default class extends Controller {
|
|
109
108
|
validateFields () {
|
110
109
|
let allValid = true
|
111
110
|
const fields = this.fieldsTarget
|
112
|
-
const formElements = fields.querySelectorAll('input[
|
111
|
+
const formElements = fields.querySelectorAll('input:not([type="hidden"]), select[name], textarea[name]')
|
113
112
|
formElements.forEach(function (element) {
|
114
113
|
const isValid = element.reportValidity()
|
115
114
|
if (!isValid) {
|
@@ -110,6 +110,7 @@ export default class extends Controller {
|
|
110
110
|
replaceIdsWithTimestamps (template) {
|
111
111
|
const pattern = 'rrrrrrrrr'
|
112
112
|
const replacement = new Date().getTime().toString()
|
113
|
+
const regex = new RegExp(pattern, 'g')
|
113
114
|
|
114
115
|
// Replace ids
|
115
116
|
template.querySelectorAll(`input[id*="${pattern}"], select[id*="${pattern}"], textarea[id*="${pattern}"], button[id*="${pattern}"]`).forEach((node) => {
|
@@ -117,6 +118,11 @@ export default class extends Controller {
|
|
117
118
|
node.setAttribute('id', idValue.replace(pattern, replacement))
|
118
119
|
})
|
119
120
|
|
121
|
+
// Search and replace pattern in templates
|
122
|
+
template.querySelectorAll('template').forEach((node) => {
|
123
|
+
node.innerHTML = node.innerHTML.replace(regex, replacement)
|
124
|
+
})
|
125
|
+
|
120
126
|
// Replace labels
|
121
127
|
template.querySelectorAll(`label[for*="${pattern}"]`).forEach((node) => {
|
122
128
|
const forValue = node.getAttribute('for')
|
@@ -11035,10 +11035,10 @@ var media_controller_default = class extends Controller {
|
|
11035
11035
|
}
|
11036
11036
|
}
|
11037
11037
|
minActiveItems() {
|
11038
|
-
return parseInt(this.
|
11038
|
+
return parseInt(this.validationInputTarget.dataset.min, 10) || 0;
|
11039
11039
|
}
|
11040
11040
|
maxActiveItems() {
|
11041
|
-
return parseInt(this.
|
11041
|
+
return parseInt(this.validationInputTarget.dataset.max, 10) || Infinity;
|
11042
11042
|
}
|
11043
11043
|
resetPositions() {
|
11044
11044
|
this.activeItems().forEach((item, index2) => {
|
@@ -11049,13 +11049,7 @@ var media_controller_default = class extends Controller {
|
|
11049
11049
|
});
|
11050
11050
|
}
|
11051
11051
|
addNewItems(items) {
|
11052
|
-
const itemTargetIds = this.itemTargets.map((i) => {
|
11053
|
-
return parseInt(i.querySelectorAll("input")[1].value);
|
11054
|
-
});
|
11055
11052
|
items.forEach((item) => {
|
11056
|
-
if (itemTargetIds.includes(item.blobId)) {
|
11057
|
-
return;
|
11058
|
-
}
|
11059
11053
|
this.addItem(item);
|
11060
11054
|
});
|
11061
11055
|
}
|
@@ -11112,7 +11106,7 @@ var media_controller_default = class extends Controller {
|
|
11112
11106
|
return e.blobId;
|
11113
11107
|
});
|
11114
11108
|
items.forEach((item) => {
|
11115
|
-
const blobId = parseInt(item.querySelectorAll("input")[1].value);
|
11109
|
+
const blobId = parseInt(item.querySelectorAll("input")[1].value, 10);
|
11116
11110
|
if (returnedBlobIds.includes(blobId)) {
|
11117
11111
|
return;
|
11118
11112
|
}
|
@@ -11128,7 +11122,7 @@ var media_controller_default = class extends Controller {
|
|
11128
11122
|
}
|
11129
11123
|
itemByBlobId(blobId) {
|
11130
11124
|
return this.itemTargets.find((item) => {
|
11131
|
-
return item.querySelector("input[name*='blob_id']").value === blobId;
|
11125
|
+
return parseInt(item.querySelector("input[name*='blob_id']").value, 10) === blobId;
|
11132
11126
|
});
|
11133
11127
|
}
|
11134
11128
|
activeItems() {
|
@@ -11138,7 +11132,7 @@ var media_controller_default = class extends Controller {
|
|
11138
11132
|
}
|
11139
11133
|
activeIds() {
|
11140
11134
|
return this.activeItems().map((item) => {
|
11141
|
-
return item.querySelector("input[name$='[blob_id]']").value;
|
11135
|
+
return parseInt(item.querySelector("input[name$='[blob_id]']").value, 10);
|
11142
11136
|
});
|
11143
11137
|
}
|
11144
11138
|
};
|
@@ -11374,7 +11368,7 @@ var nested_preview_controller_default = class extends Controller {
|
|
11374
11368
|
validateFields() {
|
11375
11369
|
let allValid = true;
|
11376
11370
|
const fields = this.fieldsTarget;
|
11377
|
-
const formElements = fields.querySelectorAll(
|
11371
|
+
const formElements = fields.querySelectorAll('input:not([type="hidden"]), select[name], textarea[name]');
|
11378
11372
|
formElements.forEach(function(element) {
|
11379
11373
|
const isValid = element.reportValidity();
|
11380
11374
|
if (!isValid) {
|
@@ -13219,10 +13213,14 @@ var repeater_controller_default = class extends Controller {
|
|
13219
13213
|
replaceIdsWithTimestamps(template) {
|
13220
13214
|
const pattern = "rrrrrrrrr";
|
13221
13215
|
const replacement = new Date().getTime().toString();
|
13216
|
+
const regex = new RegExp(pattern, "g");
|
13222
13217
|
template.querySelectorAll(`input[id*="${pattern}"], select[id*="${pattern}"], textarea[id*="${pattern}"], button[id*="${pattern}"]`).forEach((node) => {
|
13223
13218
|
const idValue = node.getAttribute("id");
|
13224
13219
|
node.setAttribute("id", idValue.replace(pattern, replacement));
|
13225
13220
|
});
|
13221
|
+
template.querySelectorAll("template").forEach((node) => {
|
13222
|
+
node.innerHTML = node.innerHTML.replace(regex, replacement);
|
13223
|
+
});
|
13226
13224
|
template.querySelectorAll(`label[for*="${pattern}"]`).forEach((node) => {
|
13227
13225
|
const forValue = node.getAttribute("for");
|
13228
13226
|
node.setAttribute("for", forValue.replace(pattern, replacement));
|
@@ -1,14 +1,14 @@
|
|
1
1
|
class ApplicationHelper
|
2
2
|
def show_svg(attachment, options = {})
|
3
|
-
return if !attachment.content_type.include?(
|
3
|
+
return if !attachment.content_type.include?("svg")
|
4
4
|
|
5
5
|
attachment.open do |file|
|
6
6
|
content = file.read
|
7
7
|
doc = Nokogiri::HTML::DocumentFragment.parse content
|
8
|
-
svg = doc.at_css
|
8
|
+
svg = doc.at_css "svg"
|
9
9
|
|
10
10
|
# for security
|
11
|
-
doc.search(
|
11
|
+
doc.search("script").each do |src|
|
12
12
|
src.remove
|
13
13
|
end
|
14
14
|
|
@@ -17,4 +17,4 @@ class ApplicationHelper
|
|
17
17
|
doc.to_html.html_safe
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
@@ -19,8 +19,6 @@ module Formstrap
|
|
19
19
|
data: {
|
20
20
|
controller: "media",
|
21
21
|
name: name,
|
22
|
-
min: min,
|
23
|
-
max: max,
|
24
22
|
sort: sort,
|
25
23
|
accept: accept,
|
26
24
|
required: required.nil? ? 0 : required
|
@@ -31,7 +29,7 @@ module Formstrap
|
|
31
29
|
def item_options
|
32
30
|
options = {
|
33
31
|
sort: sort,
|
34
|
-
url: modal_url
|
32
|
+
url: modal_url
|
35
33
|
}
|
36
34
|
|
37
35
|
# Don't pass width or height if it was not defined
|
@@ -108,10 +106,10 @@ module Formstrap
|
|
108
106
|
end
|
109
107
|
|
110
108
|
def min
|
111
|
-
if @
|
112
|
-
|
109
|
+
if @min.to_i < 1
|
110
|
+
@required ? 1 : 0
|
113
111
|
else
|
114
|
-
|
112
|
+
@min.to_i
|
115
113
|
end
|
116
114
|
end
|
117
115
|
|
@@ -124,7 +122,14 @@ module Formstrap
|
|
124
122
|
end
|
125
123
|
|
126
124
|
def modal_url
|
127
|
-
formstrap_media_path(
|
125
|
+
formstrap_media_path(
|
126
|
+
name: name,
|
127
|
+
ids: blob_ids,
|
128
|
+
min: min,
|
129
|
+
max: max,
|
130
|
+
mimetype: accept,
|
131
|
+
exclude_models: exclude_models
|
132
|
+
)
|
128
133
|
end
|
129
134
|
|
130
135
|
def edit_modal_url(attachment)
|
@@ -92,10 +92,10 @@ module Formstrap
|
|
92
92
|
blob.open do |file|
|
93
93
|
content = file.read
|
94
94
|
doc = Nokogiri::HTML::DocumentFragment.parse content
|
95
|
-
svg = doc.at_css
|
95
|
+
svg = doc.at_css "svg"
|
96
96
|
|
97
97
|
# for security
|
98
|
-
doc.search(
|
98
|
+
doc.search("script").each do |src|
|
99
99
|
src.remove
|
100
100
|
end
|
101
101
|
|
data/lib/formstrap/version.rb
CHANGED
data/package.json
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formstrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jef Vlamings
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: An extensive Bootstrap form library to power your Ruby On Rails application.
|
14
14
|
email:
|