0
# Form Integration
1
2
Automatic integration with Rails forms providing seamless direct file upload functionality through DOM event handling.
3
4
## Capabilities
5
6
### Start Function
7
8
Initializes Active Storage automatic direct upload handling by setting up DOM event listeners for forms containing direct upload file inputs.
9
10
```javascript { .api }
11
/**
12
* Initializes Active Storage automatic direct upload handling
13
* Sets up DOM event listeners for forms with direct upload file inputs
14
* Can be called multiple times safely - will only initialize once
15
*/
16
function start(): void;
17
```
18
19
**Usage Examples:**
20
21
```javascript
22
import { start } from "@rails/activestorage";
23
24
// Initialize after DOM content loaded
25
document.addEventListener("DOMContentLoaded", () => {
26
start();
27
});
28
29
// Or initialize immediately if DOM is already ready
30
start();
31
```
32
33
The `start()` function automatically handles:
34
- Form submission interception for forms with direct upload inputs
35
- Creation and management of upload controllers
36
- Progress tracking and error handling
37
- Hidden form field creation with blob signed IDs
38
39
### Automatic Form Processing
40
41
When `start()` is called, the library automatically:
42
43
1. **Intercepts form submissions** containing file inputs with `data-direct-upload-url` attribute
44
2. **Creates DirectUploadsController** to manage all file uploads in the form
45
3. **Prevents default form submission** until uploads complete
46
4. **Shows processing state** by adding `data-direct-uploads-processing` attribute
47
5. **Submits form** automatically after successful uploads
48
49
**Required HTML Structure:**
50
51
```html
52
<form action="/posts" method="post" enctype="multipart/form-data">
53
<!-- File input must have data-direct-upload-url attribute -->
54
<input type="file"
55
name="post[attachments][]"
56
data-direct-upload-url="/rails/active_storage/direct_uploads"
57
multiple>
58
59
<button type="submit">Create Post</button>
60
</form>
61
```
62
63
### Event Handling
64
65
The automatic integration dispatches custom DOM events throughout the upload process:
66
67
**Form-level events** (dispatched on `<form>` element):
68
- `direct-uploads:start` - When upload process begins
69
- `direct-uploads:end` - When all uploads complete successfully
70
71
**Input-level events** (dispatched on `<input>` element):
72
- `direct-upload:initialize` - For each file when upload is created
73
- `direct-upload:start` - When individual file upload begins
74
- `direct-upload:before-blob-request` - Before blob metadata request
75
- `direct-upload:before-storage-request` - Before file storage upload
76
- `direct-upload:progress` - During file upload progress
77
- `direct-upload:error` - When upload error occurs
78
- `direct-upload:end` - When individual file upload completes
79
80
**Event Listening Examples:**
81
82
```javascript
83
// Listen for upload progress
84
document.addEventListener("direct-upload:progress", (event) => {
85
const { progress, file } = event.detail;
86
console.log(`${file.name}: ${Math.round(progress)}%`);
87
});
88
89
// Handle upload errors
90
document.addEventListener("direct-upload:error", (event) => {
91
const { error, file } = event.detail;
92
console.error(`Upload failed for ${file.name}:`, error);
93
94
// Prevent default alert
95
event.preventDefault();
96
97
// Show custom error message
98
showCustomError(`Failed to upload ${file.name}: ${error}`);
99
});
100
101
// Track form-level completion
102
document.addEventListener("direct-uploads:end", (event) => {
103
console.log("All uploads completed, form will now submit");
104
});
105
```
106
107
### File Input Requirements
108
109
For automatic processing, file inputs must:
110
111
1. **Have `data-direct-upload-url` attribute** pointing to the Rails direct upload endpoint
112
2. **Be enabled** (not have `disabled` attribute)
113
3. **Contain files** (have files selected)
114
4. **Be within a form** that gets submitted
115
116
**Example with Rails helper:**
117
118
```erb
119
<%= form_with model: @post do |form| %>
120
<%= form.file_field :attachments,
121
multiple: true,
122
direct_upload: true %>
123
<%= form.submit %>
124
<% end %>
125
```
126
127
This generates:
128
129
```html
130
<input type="file"
131
name="post[attachments][]"
132
data-direct-upload-url="/rails/active_storage/direct_uploads"
133
multiple>
134
```
135
136
### Processing State Management
137
138
During uploads, the form enters a processing state:
139
140
- **`data-direct-uploads-processing` attribute** is added to the form
141
- **File inputs are disabled** to prevent changes during upload
142
- **Form submission is prevented** until uploads complete
143
- **Submit button state** is preserved and restored
144
145
**CSS Styling:**
146
147
```css
148
/* Style forms during processing */
149
form[data-direct-uploads-processing] {
150
opacity: 0.7;
151
pointer-events: none;
152
}
153
154
/* Show loading indicator */
155
form[data-direct-uploads-processing]::after {
156
content: "Uploading files...";
157
position: absolute;
158
/* Additional styling */
159
}
160
```
161
162
### Error Handling
163
164
The automatic integration provides default error handling:
165
166
- **Displays browser alert** for upload errors (unless prevented)
167
- **Re-enables form inputs** when errors occur
168
- **Removes processing state** to allow retry
169
- **Preserves form data** so users don't lose input
170
171
**Custom Error Handling:**
172
173
```javascript
174
document.addEventListener("direct-upload:error", (event) => {
175
// Prevent default alert
176
event.preventDefault();
177
178
const { error, file } = event.detail;
179
180
// Show custom error UI
181
showToast(`Upload failed: ${file.name}`, "error");
182
183
// Log for debugging
184
console.error("Direct upload error:", error);
185
});
186
```