or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

direct-upload.mdform-integration.mdindex.mdupload-controllers.mdutilities.md

form-integration.mddocs/

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

```