formstrap 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/app/assets/javascripts/formstrap/controllers/media_controller.js +2 -1
- data/app/assets/javascripts/formstrap/controllers/nested_preview_controller.js +2 -1
- data/app/assets/javascripts/formstrap/controllers/repeater_controller.js +18 -39
- data/app/assets/javascripts/formstrap.js +16 -30
- data/app/views/formstrap/_repeater.html.erb +4 -3
- data/app/views/formstrap/repeater/_row.html.erb +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: 47528e297776dc1c0bfaf1d0d15fcbe65a6872631c1275d4cfcd1af722b92bad
|
4
|
+
data.tar.gz: b8002a2e136bc2b14ae89b41a7641d9562cf23a151d6f37c94bb07d7fdcbcc99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 402ca1e7525e7847453c7026d46828c6c60f73020cd77d927757cdbbecfbb29e3dbfad79cc08b3ffcb1e95be5b66d490fa437f4d52eda80c1180a68f2e7d5b6f
|
7
|
+
data.tar.gz: 764ed214b9c39f07a01a7028b0a2b65ef4c3719717db522efd86936231eba94151f008d81274920af8d697ececef6fc60deca7ab3db0bfaa9c82b9ae4c727301
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* global crypto */
|
1
2
|
import { Controller } from '@hotwired/stimulus'
|
2
3
|
import Sortable from 'sortablejs'
|
3
4
|
|
@@ -193,7 +194,7 @@ export default class extends Controller {
|
|
193
194
|
|
194
195
|
randomizeIds (template) {
|
195
196
|
const regex = new RegExp(template.dataset.templateIdRegex, 'g')
|
196
|
-
const randomNumber =
|
197
|
+
const randomNumber = crypto.randomUUID().substring(0, 8)
|
197
198
|
return template.innerHTML.replace(regex, randomNumber)
|
198
199
|
}
|
199
200
|
|
@@ -126,7 +126,8 @@ export default class extends Controller {
|
|
126
126
|
const formData = new FormData()
|
127
127
|
|
128
128
|
// Replace all occurrences of "page[blocks_attributes][0]" with "block"
|
129
|
-
|
129
|
+
// Replace all occurrences of "form[fields_attributes][random]" with "field"
|
130
|
+
const regex = /\w+\[([^\]]+)s_attributes]\[[^\]]+]/g
|
130
131
|
const formElements = fields.querySelectorAll('input[name]:not([name$="[id]"]), select[name]:not([name$="[id]"]), textarea[name]:not([name$="[id]"]), button[name]:not([name$="[id]"])')
|
131
132
|
formElements.forEach((element) => {
|
132
133
|
const currentName = element.getAttribute('name')
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* global crypto */
|
1
2
|
import { Controller } from '@hotwired/stimulus'
|
2
3
|
import Sortable from 'sortablejs'
|
3
4
|
|
@@ -23,7 +24,6 @@ export default class extends Controller {
|
|
23
24
|
this.resetPositions()
|
24
25
|
}
|
25
26
|
})
|
26
|
-
|
27
27
|
this.toggleEmpty()
|
28
28
|
}
|
29
29
|
|
@@ -38,8 +38,7 @@ export default class extends Controller {
|
|
38
38
|
}
|
39
39
|
|
40
40
|
updatePopupButtonIndices (index) {
|
41
|
-
const
|
42
|
-
const buttons = popup.querySelectorAll('[data-popup-target="button"]')
|
41
|
+
const buttons = document.querySelectorAll(`[data-popup-target="button"][data-popup-id="repeater-buttons-${this.idValue}"]`)
|
43
42
|
buttons.forEach((button) => {
|
44
43
|
button.dataset.rowIndex = index
|
45
44
|
})
|
@@ -53,7 +52,7 @@ export default class extends Controller {
|
|
53
52
|
|
54
53
|
// Prepare html from template
|
55
54
|
let template = this.getTemplate(templateName).content.cloneNode(true)
|
56
|
-
template = this.
|
55
|
+
template = this.randomizeIds(template)
|
57
56
|
|
58
57
|
// Fallback to last row if no index is set
|
59
58
|
if (rowIndex) {
|
@@ -107,44 +106,24 @@ export default class extends Controller {
|
|
107
106
|
})[0]
|
108
107
|
}
|
109
108
|
|
110
|
-
|
111
|
-
const
|
112
|
-
const
|
109
|
+
randomizeIds (template) {
|
110
|
+
const randomNumber = crypto.randomUUID().substring(0, 8)
|
111
|
+
const pattern = `_${this.idValue}_`
|
113
112
|
const regex = new RegExp(pattern, 'g')
|
114
113
|
|
115
|
-
//
|
116
|
-
template.querySelectorAll(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
node.innerHTML = node.innerHTML.replace(regex, replacement)
|
124
|
-
})
|
125
|
-
|
126
|
-
// Replace labels
|
127
|
-
template.querySelectorAll(`label[for*="${pattern}"]`).forEach((node) => {
|
128
|
-
const forValue = node.getAttribute('for')
|
129
|
-
node.setAttribute('for', forValue.replace(pattern, replacement))
|
130
|
-
})
|
131
|
-
|
132
|
-
// Replace names
|
133
|
-
template.querySelectorAll(`input[name*="${pattern}"], select[name*="${pattern}"], textarea[name*="${pattern}"], button[name*="${pattern}"]`).forEach((node) => {
|
134
|
-
const nameValue = node.getAttribute('name')
|
135
|
-
node.setAttribute('name', nameValue.replace(pattern, replacement))
|
136
|
-
})
|
137
|
-
|
138
|
-
// Replace offcanvas targets
|
139
|
-
template.querySelectorAll(`div[data-bs-target="#offcanvas-${pattern}"]`).forEach((node) => {
|
140
|
-
const targetValue = node.getAttribute('data-bs-target')
|
141
|
-
node.setAttribute('data-bs-target', targetValue.replace(pattern, replacement))
|
142
|
-
})
|
114
|
+
// Loop through each node in the template
|
115
|
+
template.querySelectorAll('*').forEach(node => {
|
116
|
+
// Replace attribute values
|
117
|
+
for (const attribute of node.attributes) {
|
118
|
+
if (attribute.value.includes(pattern)) {
|
119
|
+
attribute.value = attribute.value.replace(pattern, randomNumber)
|
120
|
+
}
|
121
|
+
}
|
143
122
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
123
|
+
// Replace template content
|
124
|
+
if (node.nodeName === 'TEMPLATE' && node.innerHTML.includes(pattern)) {
|
125
|
+
node.innerHTML = node.innerHTML.replace(regex, randomNumber)
|
126
|
+
}
|
148
127
|
})
|
149
128
|
|
150
129
|
return template
|
@@ -11213,7 +11213,7 @@ var media_controller_default = class extends Controller {
|
|
11213
11213
|
}
|
11214
11214
|
randomizeIds(template) {
|
11215
11215
|
const regex = new RegExp(template.dataset.templateIdRegex, "g");
|
11216
|
-
const randomNumber =
|
11216
|
+
const randomNumber = crypto.randomUUID().substring(0, 8);
|
11217
11217
|
return template.innerHTML.replace(regex, randomNumber);
|
11218
11218
|
}
|
11219
11219
|
removeAllDeselectedItems(items) {
|
@@ -11498,7 +11498,7 @@ var nested_preview_controller_default = class extends Controller {
|
|
11498
11498
|
buildFormData() {
|
11499
11499
|
const fields = this.fieldsTarget;
|
11500
11500
|
const formData = new FormData();
|
11501
|
-
const regex = /\w+\[([^\]]+)s_attributes]\[
|
11501
|
+
const regex = /\w+\[([^\]]+)s_attributes]\[[^\]]+]/g;
|
11502
11502
|
const formElements = fields.querySelectorAll('input[name]:not([name$="[id]"]), select[name]:not([name$="[id]"]), textarea[name]:not([name$="[id]"]), button[name]:not([name$="[id]"])');
|
11503
11503
|
formElements.forEach((element) => {
|
11504
11504
|
const currentName = element.getAttribute("name");
|
@@ -13276,8 +13276,7 @@ var repeater_controller_default = class extends Controller {
|
|
13276
13276
|
return this.rowTargets.includes(row);
|
13277
13277
|
}
|
13278
13278
|
updatePopupButtonIndices(index2) {
|
13279
|
-
const
|
13280
|
-
const buttons = popup.querySelectorAll('[data-popup-target="button"]');
|
13279
|
+
const buttons = document.querySelectorAll(`[data-popup-target="button"][data-popup-id="repeater-buttons-${this.idValue}"]`);
|
13281
13280
|
buttons.forEach((button) => {
|
13282
13281
|
button.dataset.rowIndex = index2;
|
13283
13282
|
});
|
@@ -13288,7 +13287,7 @@ var repeater_controller_default = class extends Controller {
|
|
13288
13287
|
const templateName = button.dataset.templateName;
|
13289
13288
|
const rowIndex = button.dataset.rowIndex;
|
13290
13289
|
let template = this.getTemplate(templateName).content.cloneNode(true);
|
13291
|
-
template = this.
|
13290
|
+
template = this.randomizeIds(template);
|
13292
13291
|
if (rowIndex) {
|
13293
13292
|
const row = this.rowTargets[rowIndex];
|
13294
13293
|
this.listTarget.insertBefore(template, row.nextSibling);
|
@@ -13324,32 +13323,19 @@ var repeater_controller_default = class extends Controller {
|
|
13324
13323
|
return template.dataset.templateName === name;
|
13325
13324
|
})[0];
|
13326
13325
|
}
|
13327
|
-
|
13328
|
-
const
|
13329
|
-
const
|
13326
|
+
randomizeIds(template) {
|
13327
|
+
const randomNumber = crypto.randomUUID().substring(0, 8);
|
13328
|
+
const pattern = `_${this.idValue}_`;
|
13330
13329
|
const regex = new RegExp(pattern, "g");
|
13331
|
-
template.querySelectorAll(
|
13332
|
-
const
|
13333
|
-
|
13334
|
-
|
13335
|
-
|
13336
|
-
|
13337
|
-
|
13338
|
-
|
13339
|
-
|
13340
|
-
node.setAttribute("for", forValue.replace(pattern, replacement));
|
13341
|
-
});
|
13342
|
-
template.querySelectorAll(`input[name*="${pattern}"], select[name*="${pattern}"], textarea[name*="${pattern}"], button[name*="${pattern}"]`).forEach((node) => {
|
13343
|
-
const nameValue = node.getAttribute("name");
|
13344
|
-
node.setAttribute("name", nameValue.replace(pattern, replacement));
|
13345
|
-
});
|
13346
|
-
template.querySelectorAll(`div[data-bs-target="#offcanvas-${pattern}"]`).forEach((node) => {
|
13347
|
-
const targetValue = node.getAttribute("data-bs-target");
|
13348
|
-
node.setAttribute("data-bs-target", targetValue.replace(pattern, replacement));
|
13349
|
-
});
|
13350
|
-
template.querySelectorAll(`.offcanvas[id="offcanvas-${pattern}"]`).forEach((node) => {
|
13351
|
-
const idValue = node.getAttribute("id");
|
13352
|
-
node.setAttribute("id", idValue.replace(pattern, replacement));
|
13330
|
+
template.querySelectorAll("*").forEach((node) => {
|
13331
|
+
for (const attribute of node.attributes) {
|
13332
|
+
if (attribute.value.includes(pattern)) {
|
13333
|
+
attribute.value = attribute.value.replace(pattern, randomNumber);
|
13334
|
+
}
|
13335
|
+
}
|
13336
|
+
if (node.nodeName === "TEMPLATE" && node.innerHTML.includes(pattern)) {
|
13337
|
+
node.innerHTML = node.innerHTML.replace(regex, randomNumber);
|
13338
|
+
}
|
13353
13339
|
});
|
13354
13340
|
return template;
|
13355
13341
|
}
|
@@ -106,8 +106,9 @@
|
|
106
106
|
class="btn btn-sm btn-outline-secondary"
|
107
107
|
data-repeater-target="addButton"
|
108
108
|
data-popup-target="button"
|
109
|
-
data-popup-id="
|
109
|
+
data-popup-id="repeater-buttons-<%= repeater_id %>"
|
110
110
|
data-popup-pass-thru="<%= pass_thru %>"
|
111
|
+
data-row-index=""
|
111
112
|
data-action="click->repeater#resetButtonIndices click->popup#open"
|
112
113
|
>
|
113
114
|
<%= bootstrap_icon("plus") %>
|
@@ -121,7 +122,7 @@
|
|
121
122
|
<div
|
122
123
|
class="btn btn-sm btn-outline-secondary"
|
123
124
|
data-popup-target="button"
|
124
|
-
data-popup-id="
|
125
|
+
data-popup-id="repeater-buttons-<%= repeater_id %>"
|
125
126
|
data-action="click->repeater#addRow click->popup#close"
|
126
127
|
data-row-index=""
|
127
128
|
data-template-name="<%= name %>"
|
@@ -135,7 +136,7 @@
|
|
135
136
|
<!-- Templates -->
|
136
137
|
<% template_names.each do |template_name| %>
|
137
138
|
<template data-repeater-target="template" data-template-name="<%= template_name %>">
|
138
|
-
<%= form.fields_for attribute, association_object, child_index: "
|
139
|
+
<%= form.fields_for attribute, association_object, child_index: "_#{repeater_id}_" do |ff| %>
|
139
140
|
<%= render "formstrap/repeater/row", row_options.merge(form: ff, pass_thru: pass_thru, repeater_id: repeater_id, index: nil, template_name: template_name) do %>
|
140
141
|
<%= yield(ff, template_name) %>
|
141
142
|
<% end %>
|
@@ -41,7 +41,7 @@
|
|
41
41
|
title="<%= t(".add") %>"
|
42
42
|
data-repeater-target="addButton"
|
43
43
|
data-popup-target="button"
|
44
|
-
data-popup-id="
|
44
|
+
data-popup-id="repeater-buttons-<%= repeater_id %>"
|
45
45
|
data-popup-pass-thru="<%= pass_thru %>"
|
46
46
|
data-action="click->repeater#resetButtonIndices click->popup#open"
|
47
47
|
>
|
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.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: 2024-05-
|
11
|
+
date: 2024-05-16 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:
|