or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ajax-remote.mdcsrf-protection.mddom-utilities.mdelement-state.mdevent-system.mdfeature-handlers.mdform-handling.mdindex.md

form-handling.mddocs/

0

# Form Handling

1

2

Form serialization and element management utilities for handling form submissions, data collection, and form state management in Rails UJS.

3

4

## Capabilities

5

6

### Form Serialization

7

8

Converts form elements and their data into URL-encoded strings suitable for HTTP requests.

9

10

```javascript { .api }

11

/**

12

* Serialize form or element data to URL-encoded string

13

* @param element - Form element or individual input to serialize

14

* @param additionalParam - Optional additional parameter to include

15

* @returns URL-encoded string of form data

16

*/

17

function serializeElement(element: Element, additionalParam?: {name: string, value: string}): string;

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

const form = document.querySelector("form");

24

25

// Serialize entire form

26

const formData = Rails.serializeElement(form);

27

console.log(formData); // "title=Hello&body=World&commit=Create"

28

29

// Serialize with additional parameter

30

const dataWithToken = Rails.serializeElement(form, {

31

name: "authenticity_token",

32

value: "abc123"

33

});

34

35

// Serialize individual input

36

const input = document.querySelector("input[name=title]");

37

const inputData = Rails.serializeElement(input);

38

console.log(inputData); // "title=Hello"

39

40

// Used in AJAX requests

41

Rails.ajax({

42

type: "POST",

43

url: "/posts",

44

data: Rails.serializeElement(form)

45

});

46

```

47

48

### Form Element Selection

49

50

Gets form elements that match a specific selector, handling both forms and individual elements.

51

52

```javascript { .api }

53

/**

54

* Get form elements matching selector

55

* @param form - Form element or container element

56

* @param selector - CSS selector for elements to find

57

* @returns Array of matching elements

58

*/

59

function formElements(form: Element, selector: string): Element[];

60

```

61

62

**Usage Examples:**

63

64

```javascript

65

const form = document.querySelector("form");

66

67

// Get all submit buttons in form

68

const submitButtons = Rails.formElements(form, "input[type=submit], button[type=submit]");

69

70

// Get elements to disable during submission

71

const disableElements = Rails.formElements(form, "[data-disable-with]");

72

disableElements.forEach(el => Rails.disableElement(el));

73

74

// Get file inputs for special handling

75

const fileInputs = Rails.formElements(form, "input[type=file]");

76

77

// Works with non-form containers too

78

const container = document.querySelector(".form-container");

79

const inputs = Rails.formElements(container, "input, select, textarea");

80

```

81

82

### Submit Button Tracking

83

84

Handles submit button clicks to track which button was used for form submission.

85

86

```javascript { .api }

87

/**

88

* Handle form submit button clicks to track submission context

89

* @param event - Click event from submit button

90

*/

91

function formSubmitButtonClick(event: Event): void;

92

```

93

94

**Usage Examples:**

95

96

```javascript

97

// Automatically handled by Rails UJS for these elements:

98

// form input[type=submit]

99

// form input[type=image]

100

// form button[type=submit]

101

// form button:not([type])

102

// input[type=submit][form]

103

// button[type=submit][form]

104

105

// The clicked button info is stored and used in form submission:

106

const form = document.querySelector("form");

107

const submitButton = form.querySelector("button[name=commit]");

108

109

// After button click, Rails UJS stores:

110

// Rails.getData(form, "ujs:submit-button") = { name: "commit", value: "Create" }

111

// Rails.getData(form, "ujs:formnovalidate-button") = button.formNoValidate

112

// Rails.getData(form, "ujs:submit-button-formaction") = button.formAction

113

// Rails.getData(form, "ujs:submit-button-formmethod") = button.formMethod

114

```

115

116

## Form Serialization Details

117

118

### Included Elements

119

120

The serialization process includes:

121

122

- **Text inputs**: `input[type=text]`, `input[type=email]`, etc.

123

- **Textareas**: All `<textarea>` elements

124

- **Select elements**: Single and multiple select dropdowns

125

- **Checkboxes**: Only checked checkboxes

126

- **Radio buttons**: Only selected radio buttons

127

- **Hidden inputs**: `input[type=hidden]`

128

- **Submit buttons**: The clicked submit button (if any)

129

130

### Excluded Elements

131

132

Elements that are NOT serialized:

133

134

- **Disabled elements**: `[disabled]` attribute present

135

- **Elements without names**: Missing `name` attribute

136

- **Fieldset disabled children**: Elements inside `<fieldset disabled>`

137

- **Unchecked checkboxes**: `input[type=checkbox]:not(:checked)`

138

- **Unselected radios**: `input[type=radio]:not(:checked)`

139

- **File inputs**: `input[type=file]` (handled separately as FormData)

140

141

### Special Handling

142

143

```javascript

144

// Select elements - includes all selected options

145

<select name="categories" multiple>

146

<option value="1" selected>Tech</option>

147

<option value="2" selected>News</option>

148

</select>

149

// Serializes as: "categories=1&categories=2"

150

151

// Checkbox groups with same name

152

<input type="checkbox" name="tags[]" value="ruby" checked>

153

<input type="checkbox" name="tags[]" value="rails" checked>

154

// Serializes as: "tags%5B%5D=ruby&tags%5B%5D=rails"

155

156

// Submit button information

157

<button type="submit" name="commit" value="publish">Publish</button>

158

// When clicked, adds: "commit=publish"

159

```

160

161

## Form Processing Integration

162

163

### Remote Form Handling

164

165

Forms with `data-remote="true"` use serialization for AJAX submission:

166

167

```html

168

<form action="/posts" method="post" data-remote="true">

169

<input type="text" name="title" value="Hello">

170

<textarea name="body">World</textarea>

171

<button type="submit" name="commit" value="Create">Create Post</button>

172

</form>

173

```

174

175

```javascript

176

// Rails UJS automatically:

177

// 1. Prevents normal form submission

178

// 2. Serializes form data: "title=Hello&body=World&commit=Create"

179

// 3. Makes AJAX request with serialized data

180

// 4. Handles response appropriately

181

```

182

183

### File Upload Handling

184

185

Forms with file inputs use FormData instead of URL encoding:

186

187

```html

188

<form action="/uploads" method="post" enctype="multipart/form-data" data-remote="true">

189

<input type="file" name="document">

190

<input type="text" name="title">

191

<button type="submit">Upload</button>

192

</form>

193

```

194

195

```javascript

196

// Rails UJS detects multipart forms and:

197

// 1. Creates FormData object instead of URL-encoded string

198

// 2. Appends all form fields to FormData

199

// 3. Includes clicked submit button data

200

// 4. Sends as multipart/form-data

201

```

202

203

### Form Method Override

204

205

Rails method override is handled through hidden fields:

206

207

```html

208

<form action="/posts/1" method="post">

209

<input type="hidden" name="_method" value="patch">

210

<input type="text" name="title">

211

</form>

212

```

213

214

The `_method` field is included in serialization to enable REST methods.

215

216

## Element State During Submission

217

218

Form elements are automatically managed during submission:

219

220

```javascript

221

// Before submission:

222

const disableElements = Rails.formElements(form, "[data-disable-with]:enabled");

223

disableElements.forEach(Rails.disableElement);

224

225

// After completion:

226

const enableElements = Rails.formElements(form, "[data-disable-with]:disabled");

227

enableElements.forEach(Rails.enableElement);

228

```

229

230

## Common Selectors

231

232

Rails UJS uses these selectors for form handling:

233

234

```javascript { .api }

235

// Forms that should be processed by Rails UJS

236

const formSubmitSelector = "form:not([data-turbo=true])";

237

238

// Submit buttons and inputs in forms

239

const formInputClickSelector = "form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])";

240

241

// Elements to disable during form submission

242

const formDisableSelector = "input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled";

243

244

// File inputs that need special handling

245

const fileInputSelector = "input[name][type=file]:not([disabled])";

246

```