formatic 0.2.5 → 0.2.7
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/CHANGELOG.md +9 -0
- data/app/assets/javascript/declarations/file.d.ts +5 -1
- data/app/assets/javascript/formatic/file.js +56 -13
- data/app/assets/javascript/formatic/file.js.map +1 -1
- data/app/assets/javascript/src/file.ts +67 -13
- data/app/assets/stylesheets/formatic/formatic.css +0 -13
- data/app/assets/stylesheets/formatic/formatic.css.map +1 -0
- data/app/assets/stylesheets/formatic/scopes/form.sass +1 -15
- data/app/components/formatic/file.rb +45 -6
- data/lib/formatic/engine.rb +15 -13
- data/lib/formatic/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: ad4a5b2b68003690147320a60622e0774361260e64ffcbf51b9e59d7197ba1bf
|
|
4
|
+
data.tar.gz: a7047451847ba0057860b377f0bf294c0c97d2eb27df898b822a0da90023d0b2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8725d932a0384fccc8154edde02f53d96db63676fcfd106ac9140a38f3bca78973278532920f494f11c98e7d3cd9313ea30816343bbd155d619f99e238204f11
|
|
7
|
+
data.tar.gz: e4b4c258c6ccbe4bcc9115dcd257bce76a486913559da9d79aecbc58a54dfbabeb814373b8f4f9bb6a58c7b1705a5a9542ef6041449409777b34b31f52c613c6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.7] - 2026-04-29
|
|
4
|
+
|
|
5
|
+
- Fix rails complaining about require'ing action_view too early
|
|
6
|
+
|
|
7
|
+
## [0.2.6] - 2026-03-31
|
|
8
|
+
|
|
9
|
+
- Improvement: Use native dark mode scheme instead of fixed colors
|
|
10
|
+
- Filepond fixes (validations, non-direct upload)
|
|
11
|
+
|
|
3
12
|
## [0.2.5] - 2026-02-04
|
|
4
13
|
|
|
5
14
|
- Add accept mime for files
|
|
@@ -4,13 +4,17 @@ export declare class FormaticFile {
|
|
|
4
4
|
private pond;
|
|
5
5
|
private busyStatuses;
|
|
6
6
|
private inputID;
|
|
7
|
+
private inputName;
|
|
7
8
|
constructor(el: HTMLElement);
|
|
8
|
-
private
|
|
9
|
+
private setupSync;
|
|
10
|
+
private setupAsync;
|
|
9
11
|
private updateLabelId;
|
|
12
|
+
private updatedFiles;
|
|
10
13
|
private updateSubmit;
|
|
11
14
|
private enableSubmit;
|
|
12
15
|
private disableSubmit;
|
|
13
16
|
private get input();
|
|
17
|
+
private get hiddenFieldsContainer();
|
|
14
18
|
private get form();
|
|
15
19
|
private get submitButtons();
|
|
16
20
|
}
|
|
@@ -7,32 +7,49 @@ export class FormaticFile {
|
|
|
7
7
|
FilePond.FileStatus.PROCESSING_QUEUED,
|
|
8
8
|
FilePond.FileStatus.PROCESSING,
|
|
9
9
|
]);
|
|
10
|
-
this.inputID = null;
|
|
11
10
|
this.el = el;
|
|
12
11
|
this.url = this.input.dataset.directUploadUrl;
|
|
13
12
|
this.inputID = this.input.id;
|
|
14
|
-
this.
|
|
13
|
+
this.inputName = this.input.name;
|
|
14
|
+
if (this.url) {
|
|
15
|
+
this.setupAsync();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this.setupSync();
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
|
-
|
|
21
|
+
setupSync() {
|
|
17
22
|
this.pond = FilePond.create(this.input, {
|
|
23
|
+
storeAsFile: true,
|
|
18
24
|
credits: false,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
files: JSON.parse(this.input.dataset.entries || '[]'),
|
|
26
|
+
server: {
|
|
27
|
+
revert: null,
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
setupAsync() {
|
|
32
|
+
this.pond = FilePond.create(this.input, {
|
|
33
|
+
credits: false,
|
|
34
|
+
onactivatefile: () => this.updateSubmit(),
|
|
23
35
|
onaddfile: () => this.updateSubmit(),
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
onaddfileprogress: () => this.updateSubmit(),
|
|
37
|
+
onaddfilestart: () => this.updateSubmit(),
|
|
38
|
+
onerror: () => this.updateSubmit(),
|
|
39
|
+
onpreparefile: () => this.updateSubmit(),
|
|
40
|
+
onprocessfile: () => this.updateSubmit(),
|
|
26
41
|
onprocessfileabort: () => this.updateSubmit(),
|
|
42
|
+
onprocessfileprogress: () => this.updateSubmit(),
|
|
27
43
|
onprocessfilerevert: () => this.updateSubmit(),
|
|
28
|
-
onprocessfile: () => this.updateSubmit(),
|
|
29
44
|
onprocessfiles: () => this.updateSubmit(),
|
|
45
|
+
onprocessfilestart: () => this.updateSubmit(),
|
|
30
46
|
onremovefile: () => this.updateSubmit(),
|
|
31
|
-
onpreparefile: () => this.updateSubmit(),
|
|
32
|
-
onupdatefiles: () => this.updateSubmit(),
|
|
33
|
-
onactivatefile: () => this.updateSubmit(),
|
|
34
47
|
onreorderfiles: () => this.updateSubmit(),
|
|
48
|
+
onwarning: () => this.updateSubmit(),
|
|
49
|
+
onupdatefiles: () => this.updatedFiles(),
|
|
50
|
+
files: JSON.parse(this.input.dataset.entries || '[]'),
|
|
35
51
|
server: {
|
|
52
|
+
revert: null,
|
|
36
53
|
process: (fieldName, file, _metadata, load, error, progress, abort, transfer, options) => {
|
|
37
54
|
const uploader = new DirectUpload(file, this.url, {
|
|
38
55
|
directUploadWillStoreFileWithXHR: (request) => {
|
|
@@ -72,6 +89,29 @@ export class FormaticFile {
|
|
|
72
89
|
return;
|
|
73
90
|
labels.forEach(label => label.setAttribute('for', pondInputId));
|
|
74
91
|
}
|
|
92
|
+
updatedFiles() {
|
|
93
|
+
if (this.pond.allowMultiple)
|
|
94
|
+
return;
|
|
95
|
+
const files = this.pond.getFiles();
|
|
96
|
+
this.hiddenFieldsContainer.innerHTML = '';
|
|
97
|
+
files.forEach(file => {
|
|
98
|
+
if (file.serverId) {
|
|
99
|
+
const h = document.createElement('input');
|
|
100
|
+
h.type = 'hidden';
|
|
101
|
+
h.name = this.inputName;
|
|
102
|
+
h.value = file.serverId;
|
|
103
|
+
this.hiddenFieldsContainer.appendChild(h);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
if (files.length === 0) {
|
|
107
|
+
const h = document.createElement('input');
|
|
108
|
+
h.type = 'hidden';
|
|
109
|
+
h.name = this.inputName;
|
|
110
|
+
h.value = '';
|
|
111
|
+
this.hiddenFieldsContainer.appendChild(h);
|
|
112
|
+
}
|
|
113
|
+
this.updateSubmit();
|
|
114
|
+
}
|
|
75
115
|
updateSubmit() {
|
|
76
116
|
const files = this.pond.getFiles();
|
|
77
117
|
const busyFiles = files.some(f => this.busyStatuses.has(f.status));
|
|
@@ -90,6 +130,9 @@ export class FormaticFile {
|
|
|
90
130
|
get input() {
|
|
91
131
|
return this.el.querySelector('.js-formatic-file__input');
|
|
92
132
|
}
|
|
133
|
+
get hiddenFieldsContainer() {
|
|
134
|
+
return this.el.querySelector('.js-formatic-file__hidden-fields');
|
|
135
|
+
}
|
|
93
136
|
get form() {
|
|
94
137
|
return this.el.closest('form');
|
|
95
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,MAAM,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,35 +10,56 @@ export class FormaticFile {
|
|
|
10
10
|
FilePond.FileStatus.PROCESSING_QUEUED,
|
|
11
11
|
FilePond.FileStatus.PROCESSING,
|
|
12
12
|
]);
|
|
13
|
-
private inputID: string
|
|
13
|
+
private inputID: string
|
|
14
|
+
private inputName: string
|
|
14
15
|
|
|
15
16
|
constructor(el: HTMLElement) {
|
|
16
17
|
this.el = el
|
|
17
18
|
this.url = this.input.dataset.directUploadUrl
|
|
18
19
|
this.inputID = this.input.id
|
|
19
|
-
this.
|
|
20
|
+
this.inputName = this.input.name
|
|
21
|
+
|
|
22
|
+
if (this.url) {
|
|
23
|
+
this.setupAsync()
|
|
24
|
+
} else {
|
|
25
|
+
this.setupSync()
|
|
26
|
+
}
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
private
|
|
29
|
+
private setupSync() {
|
|
23
30
|
this.pond = FilePond.create(this.input, {
|
|
31
|
+
storeAsFile: true,
|
|
24
32
|
credits: false,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
files: JSON.parse(this.input.dataset.entries || '[]') as FilePond.FilePondInitialFile[],
|
|
34
|
+
server: {
|
|
35
|
+
revert: null, // Don't send DELETE request when removing a file on a not-submitted-yet form.
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private setupAsync() {
|
|
41
|
+
this.pond = FilePond.create(this.input, {
|
|
42
|
+
credits: false,
|
|
43
|
+
onactivatefile: () => this.updateSubmit(),
|
|
29
44
|
onaddfile: () => this.updateSubmit(),
|
|
30
|
-
|
|
31
|
-
|
|
45
|
+
onaddfileprogress: () => this.updateSubmit(),
|
|
46
|
+
onaddfilestart: () => this.updateSubmit(),
|
|
47
|
+
onerror: () => this.updateSubmit(),
|
|
48
|
+
onpreparefile: () => this.updateSubmit(),
|
|
49
|
+
onprocessfile: () => this.updateSubmit(),
|
|
32
50
|
onprocessfileabort: () => this.updateSubmit(),
|
|
51
|
+
onprocessfileprogress: () => this.updateSubmit(),
|
|
33
52
|
onprocessfilerevert: () => this.updateSubmit(),
|
|
34
|
-
onprocessfile: () => this.updateSubmit(),
|
|
35
53
|
onprocessfiles: () => this.updateSubmit(),
|
|
54
|
+
onprocessfilestart: () => this.updateSubmit(),
|
|
36
55
|
onremovefile: () => this.updateSubmit(),
|
|
37
|
-
onpreparefile: () => this.updateSubmit(),
|
|
38
|
-
onupdatefiles: () => this.updateSubmit(),
|
|
39
|
-
onactivatefile: () => this.updateSubmit(),
|
|
40
56
|
onreorderfiles: () => this.updateSubmit(),
|
|
57
|
+
onwarning: () => this.updateSubmit(),
|
|
58
|
+
onupdatefiles: () => this.updatedFiles(),
|
|
59
|
+
files: JSON.parse(this.input.dataset.entries || '[]') as FilePond.FilePondInitialFile[],
|
|
41
60
|
server: {
|
|
61
|
+
revert: null,
|
|
62
|
+
|
|
42
63
|
process: (fieldName, file, _metadata, load, error, progress, abort, transfer, options) => {
|
|
43
64
|
|
|
44
65
|
const uploader = new DirectUpload(file as File, this.url, {
|
|
@@ -90,6 +111,35 @@ export class FormaticFile {
|
|
|
90
111
|
labels.forEach(label => label.setAttribute('for', pondInputId))
|
|
91
112
|
}
|
|
92
113
|
|
|
114
|
+
private updatedFiles() {
|
|
115
|
+
// Showing a <form> for an existing record or submitting an invalid form
|
|
116
|
+
// where multiple=true does not play well with filepond at all.
|
|
117
|
+
if (this.pond.allowMultiple) return
|
|
118
|
+
|
|
119
|
+
const files = this.pond.getFiles()
|
|
120
|
+
this.hiddenFieldsContainer.innerHTML = ''
|
|
121
|
+
|
|
122
|
+
files.forEach(file => {
|
|
123
|
+
if (file.serverId) {
|
|
124
|
+
const h = document.createElement('input')
|
|
125
|
+
h.type = 'hidden'
|
|
126
|
+
h.name = this.inputName
|
|
127
|
+
h.value = file.serverId
|
|
128
|
+
this.hiddenFieldsContainer.appendChild(h)
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
if (files.length === 0) {
|
|
133
|
+
const h = document.createElement('input')
|
|
134
|
+
h.type = 'hidden'
|
|
135
|
+
h.name = this.inputName
|
|
136
|
+
h.value = ''
|
|
137
|
+
this.hiddenFieldsContainer.appendChild(h)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this.updateSubmit()
|
|
141
|
+
}
|
|
142
|
+
|
|
93
143
|
private updateSubmit() {
|
|
94
144
|
const files = this.pond.getFiles()
|
|
95
145
|
const busyFiles = files.some(f => this.busyStatuses.has(f.status))
|
|
@@ -112,6 +162,10 @@ export class FormaticFile {
|
|
|
112
162
|
return this.el.querySelector<HTMLInputElement>('.js-formatic-file__input')
|
|
113
163
|
}
|
|
114
164
|
|
|
165
|
+
private get hiddenFieldsContainer() {
|
|
166
|
+
return this.el.querySelector<HTMLElement>('.js-formatic-file__hidden-fields')
|
|
167
|
+
}
|
|
168
|
+
|
|
115
169
|
private get form() {
|
|
116
170
|
return this.el.closest<HTMLFormElement>('form')
|
|
117
171
|
}
|
|
@@ -429,19 +429,6 @@
|
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
@media (prefers-color-scheme: dark) {
|
|
432
|
-
.s-formatic input[type=email],
|
|
433
|
-
.s-formatic input[type=number],
|
|
434
|
-
.s-formatic input[type=password],
|
|
435
|
-
.s-formatic input[type=search],
|
|
436
|
-
.s-formatic input[type=tel],
|
|
437
|
-
.s-formatic input[type=text],
|
|
438
|
-
.s-formatic input[type=url],
|
|
439
|
-
.s-formatic textarea,
|
|
440
|
-
.s-formatic select,
|
|
441
|
-
.s-formatic textarea {
|
|
442
|
-
background-color: #222;
|
|
443
|
-
color: #fff;
|
|
444
|
-
}
|
|
445
432
|
.s-formatic select {
|
|
446
433
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb(255, 255, 255)"></polygon></svg>');
|
|
447
434
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["generics/flip.sass","components/wrapper.sass","../../../../node_modules/iglu/iglu/font-size/tools/_sizing.sass","../../../../node_modules/iglu/iglu/spacing/tools/_margin.sass","settings/_colors.sass","components/checklist.sass","components/date.sass","tools/_mandatory.sass","../../../../node_modules/iglu/iglu/spacing/tools/_padding_immediate.sass","tools/_terminal.sass","tools/_cloud.sass","components/stepper.sass","components/time.sass","components/toggle.sass","utilities/container.sass","scopes/form.sass","tools/_theme.sass"],"names":[],"mappings":"AAAA;EACE;IACE;;;ACGJ;EACE;EACA;EACA;EACA;;ACGD;EACE;;ACiED;EACE;;AFlEF;EACE;;AAGA;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AAEJ;EAEE;;AAEF;EACE,OGpBY;;AHsBZ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEJ;EACE;;AE8BF;EACE;;AD/DH;EACE;;ADmCD;EACE;EACA;EACA;;;AAEJ;EACE;IACE;IACA;IACA;IACA;;;AIlDJ;EACE;EACA;;;ACOA;EACE;EACA;EACA;;AH8DF;EACE;;AIxEF;EACE,mBHCY;EGAZ;;ADcF;EACE;EAEA;EACA;EACA;EACA;;AACA;EACE;;AAEJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OFlCI;;ADsCN;EACE;;AKnCF;EACE;;ANSH;EACE;;AMHD;EACE;;ANHH;EACE;;AOZD;EACE;;AH8CF;EACE;;AJ7CH;EACE;;AI+CD;EACE;;AGpDF;EACE;;APEH;EACE;;AIoDD;EACE;;AAEF;EACE;EACA,OF3DI;;AE6DN;EACE,OF5DY;;AE8Dd;EACE;EACA;;;AClEF;EACE,mBHCY;EGAZ;;AGJF;EAGE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA;;;ACXJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OPlBI;EOmBJ;;ATGH;EACE;;ASDD;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OP7BI;EO8BJ;EACA;EACA;;ATlBH;EACE;;ACyDD;EACE;;AQrCF;EACE,OP7BU;;;AKTZ;EACE;;ACDF;EAGE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA;;AHbF;EACE,mBHCY;EGAZ;;;AGJF;EAGE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA;;AHbF;EACE,mBHCY;EGAZ;;;AKCF;EACE;EACA;EACA;;ATiEF;EACE;;AIxEF;EACE,mBHCY;EGAZ;;;AMFJ;EAGE;EACA;EACA;;AXID;EACE;;AWFD;EACE;EAGA;EACA;;AAEA;EACE;;AXXL;EACE;;AWaD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YTrBU;;ASuBV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,kBTvCE;ESwCF;;AAGJ;EACE;EACA;;AAGA;EACE,kBT7CO;;AS+CP;EACE,kBTlDQ;;ASqDZ;EACE;EACA,kBTzDE;;AS4DJ;EACE;;AACF;EACE;;AAGF;EACE;;AACF;EACE;;AAGJ;EACE;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;EACA,OT7EW;;AFLd;AAAA;EACE;;AWsFD;EACE;EACA;EACA;;;AC9FJ;EACE;;;ACKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASE;EACA;EACA;EACA;EACA;EACA,eXdU;EWeV;EACA,OXpBI;EWqBJ;EACA;EACA;EACA;EACA;EACA;;AbhBH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;;AKVD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE,mBHCY;EGAZ;;AQ6BF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE,OXnCU;;;AYTZ;EDgDE;IACE","file":"formatic.css"}
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
outline-offset: 0
|
|
21
21
|
outline-color: colors.$neon-yellow
|
|
22
22
|
border: 1px solid colors.$silver-gray
|
|
23
|
-
color: colors.$black
|
|
24
23
|
height: 2em
|
|
25
24
|
padding-top: 0.2em
|
|
26
25
|
padding-right: 0.4em
|
|
@@ -43,22 +42,9 @@
|
|
|
43
42
|
box-shadow: none
|
|
44
43
|
|
|
45
44
|
::placeholder
|
|
46
|
-
|
|
45
|
+
opacity: 0.4
|
|
47
46
|
|
|
48
47
|
+theme.dark
|
|
49
48
|
.s-formatic
|
|
50
|
-
input[type="email"],
|
|
51
|
-
input[type="number"],
|
|
52
|
-
input[type="password"],
|
|
53
|
-
input[type="search"],
|
|
54
|
-
input[type="tel"],
|
|
55
|
-
input[type="text"],
|
|
56
|
-
input[type="url"],
|
|
57
|
-
textarea,
|
|
58
|
-
select,
|
|
59
|
-
textarea
|
|
60
|
-
background-color: colors.$black
|
|
61
|
-
color: colors.$white
|
|
62
|
-
|
|
63
49
|
select
|
|
64
50
|
background-image: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"32\" height=\"24\" viewBox=\"0 0 32 24\"><polygon points=\"0,0 32,0 16,24\" style=\"fill: rgb(255, 255, 255)\"></polygon></svg>")
|
|
@@ -7,21 +7,60 @@ module Formatic
|
|
|
7
7
|
option :multiple, default: -> { false }
|
|
8
8
|
option :accept, default: -> {}
|
|
9
9
|
|
|
10
|
-
# TODO: Make the hidden_field (form validations) work with multiple: true
|
|
11
10
|
erb_template <<~ERB
|
|
12
11
|
<%= render wrapper do |wrap| %>
|
|
13
12
|
|
|
14
13
|
<% wrap.with_input do %>
|
|
15
14
|
|
|
16
|
-
<div class="c-formatic-file js-formatic-file">
|
|
17
|
-
<%- if value.present? && value.attached? -%>
|
|
18
|
-
<%= f.hidden_field attribute_name, value: value.signed_id %>
|
|
19
|
-
<%- end -%>
|
|
15
|
+
<div class="c-formatic-file js-formatic-file"'>
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
<%-
|
|
18
|
+
# Make sure we don't loose uploaded files on submit if JS is failing
|
|
19
|
+
# (If JS fails, the empty file <input> would cause AS to purge)
|
|
20
|
+
-%>
|
|
21
|
+
<div class="js-formatic-file__hidden-fields">
|
|
22
|
+
<%- attachments&.each do |attachment| -%>
|
|
23
|
+
<%- if attachment.present? -%>
|
|
24
|
+
<%= hidden_field_tag input_name, attachment.signed_id %>
|
|
25
|
+
<%- end -%>
|
|
26
|
+
<%- end -%>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<%= f.file_field attribute_name, class: "js-formatic-file__input", direct_upload:, multiple:, accept:, data: { entries: entries_json } %>
|
|
22
30
|
</div>
|
|
23
31
|
<% end %>
|
|
24
32
|
<% end %>
|
|
25
33
|
ERB
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def attachments
|
|
38
|
+
return [] if value.blank?
|
|
39
|
+
|
|
40
|
+
# ActiveStorage::Attached::Many
|
|
41
|
+
return value.attachments if value.respond_to?(:attachments)
|
|
42
|
+
|
|
43
|
+
# ActiveStorage::Attached::One
|
|
44
|
+
[value.attachment]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def entries_json
|
|
48
|
+
# Filepond doesn't work well with invalid form submits anyway.
|
|
49
|
+
return if multiple
|
|
50
|
+
|
|
51
|
+
attachments.map do |attachment|
|
|
52
|
+
{
|
|
53
|
+
source: attachment.signed_id,
|
|
54
|
+
options: {
|
|
55
|
+
type: 'local',
|
|
56
|
+
file: {
|
|
57
|
+
name: attachment.filename,
|
|
58
|
+
size: attachment.byte_size,
|
|
59
|
+
type: attachment.content_type
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
end.to_json
|
|
64
|
+
end
|
|
26
65
|
end
|
|
27
66
|
end
|
data/lib/formatic/engine.rb
CHANGED
|
@@ -43,19 +43,21 @@ module Formatic
|
|
|
43
43
|
# AND the view_component gem has been fully initialized (configured).
|
|
44
44
|
#
|
|
45
45
|
# That's right here and now.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
ActiveSupport.on_load(:action_view) do
|
|
47
|
+
require_relative '../../app/components/formatic/application_component'
|
|
48
|
+
require_relative '../../app/components/formatic/wrapper'
|
|
49
|
+
require_relative '../../app/components/formatic/base'
|
|
50
|
+
|
|
51
|
+
# Components
|
|
52
|
+
require_relative '../../app/components/formatic/toggle'
|
|
53
|
+
require_relative '../../app/components/formatic/checklist'
|
|
54
|
+
require_relative '../../app/components/formatic/date'
|
|
55
|
+
require_relative '../../app/components/formatic/select'
|
|
56
|
+
require_relative '../../app/components/formatic/string'
|
|
57
|
+
require_relative '../../app/components/formatic/stepper'
|
|
58
|
+
require_relative '../../app/components/formatic/textarea'
|
|
59
|
+
require_relative '../../app/components/formatic/time'
|
|
60
|
+
end
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
end
|
data/lib/formatic/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: formatic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- halo
|
|
@@ -158,6 +158,7 @@ files:
|
|
|
158
158
|
- app/assets/stylesheets/formatic/components/toggle.sass
|
|
159
159
|
- app/assets/stylesheets/formatic/components/wrapper.sass
|
|
160
160
|
- app/assets/stylesheets/formatic/formatic.css
|
|
161
|
+
- app/assets/stylesheets/formatic/formatic.css.map
|
|
161
162
|
- app/assets/stylesheets/formatic/generics/flip.sass
|
|
162
163
|
- app/assets/stylesheets/formatic/scopes/form.sass
|
|
163
164
|
- app/assets/stylesheets/formatic/settings/_colors.sass
|
|
@@ -225,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
225
226
|
- !ruby/object:Gem::Version
|
|
226
227
|
version: '0'
|
|
227
228
|
requirements: []
|
|
228
|
-
rubygems_version:
|
|
229
|
+
rubygems_version: 3.6.9
|
|
229
230
|
specification_version: 4
|
|
230
231
|
summary: A set of ViewComponents for form elements
|
|
231
232
|
test_files: []
|