or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extension-setup.mdform-rendering.mdindex.mdnavigation.mdpagination.mdpython-utilities.mdtable-rendering.mdutilities.md

form-rendering.mddocs/

0

# Form Rendering

1

2

Comprehensive form rendering capabilities with Bootstrap styling, supporting multiple layout types, validation error display, field grouping, and extensive customization options for Flask-WTF/WTForms integration.

3

4

## Capabilities

5

6

### Complete Form Rendering

7

8

Render entire forms with Bootstrap styling and automatic validation error handling.

9

10

```python { .api }

11

def render_form(form, action="", method="post", extra_classes=None, role="form",

12

form_type="basic", horizontal_columns=('lg', 2, 10), enctype=None,

13

button_map={}, button_style="", button_size="", id="",

14

novalidate=False, render_kw={}, form_group_classes="",

15

form_inline_classes=""):

16

"""

17

Render a complete form with Bootstrap styling.

18

19

Args:

20

form: WTForms form object

21

action (str): Form action URL (default: current URL)

22

method (str): HTTP method (default: "post")

23

extra_classes (str): Additional CSS classes for form element

24

role (str): ARIA role attribute (default: "form")

25

form_type (str): Layout type - "basic", "inline", or "horizontal"

26

horizontal_columns (tuple): Column sizing for horizontal layout (breakpoint, label_cols, field_cols)

27

enctype (str): Form encoding type (auto-detected for file uploads)

28

button_map (dict): Custom button styles per field name

29

button_style (str): Default button style for submit buttons

30

button_size (str): Default button size for submit buttons

31

id (str): Form element ID attribute

32

novalidate (bool): Disable HTML5 validation

33

render_kw (dict): Additional attributes for form element

34

form_group_classes (str): Classes for form groups (Bootstrap 5)

35

form_inline_classes (str): Classes for inline forms (Bootstrap 5)

36

37

Returns:

38

Rendered HTML form with Bootstrap styling

39

40

Layout Types:

41

- basic: Standard vertical form layout

42

- inline: Horizontal inline form layout

43

- horizontal: Two-column layout with labels and fields

44

"""

45

```

46

47

### Individual Field Rendering

48

49

Render individual form fields with Bootstrap styling and validation states.

50

51

```python { .api }

52

def render_field(field, form_type="basic", horizontal_columns=('lg', 2, 10),

53

button_map={}, button_style='', button_size='', form_group_classes=''):

54

"""

55

Render an individual form field with Bootstrap styling.

56

57

Args:

58

field: WTForms field object

59

form_type (str): Layout type - "basic", "inline", or "horizontal"

60

horizontal_columns (tuple): Column sizing for horizontal layout

61

button_map (dict): Custom button styles for this field

62

button_style (str): Default button style for submit/button fields

63

button_size (str): Default button size for submit/button fields

64

form_group_classes (str): Additional classes for form group (Bootstrap 5)

65

66

Returns:

67

Rendered HTML field with appropriate Bootstrap classes

68

69

Field Type Support:

70

- Text inputs (StringField, TextAreaField, etc.)

71

- Select fields (SelectField, SelectMultipleField)

72

- Boolean fields (BooleanField, SwitchField)

73

- File uploads (FileField, MultipleFileField)

74

- Hidden fields (HiddenField)

75

- Submit buttons (SubmitField)

76

- Custom field types

77

78

Validation Features:

79

- Automatic validation state classes (is-valid, is-invalid)

80

- Error message display

81

- Required field indicators

82

"""

83

```

84

85

### Multi-Column Form Rows

86

87

Render multiple fields in a single row using Bootstrap grid classes.

88

89

```python { .api }

90

def render_form_row(fields, row_class='row', col_class_default='col',

91

col_map={}, button_map={}, button_style='', button_size='',

92

form_group_classes='', form_type='basic',

93

horizontal_columns=('lg', 2, 10)):

94

"""

95

Render multiple form fields in a single row layout.

96

97

Args:

98

fields (list): List of WTForms field objects

99

row_class (str): CSS class for row container (default: 'row')

100

col_class_default (str): Default column class (default: 'col')

101

col_map (dict): Custom column classes per field name

102

button_map (dict): Custom button styles per field name

103

button_style (str): Default button style

104

button_size (str): Default button size

105

form_group_classes (str): Form group classes (Bootstrap 5)

106

form_type (str): Form layout type

107

horizontal_columns (tuple): Horizontal form column configuration

108

109

Returns:

110

Rendered HTML row with fields in Bootstrap grid layout

111

112

Example col_map:

113

{

114

'first_name': 'col-md-6',

115

'last_name': 'col-md-6',

116

'email': 'col-12'

117

}

118

"""

119

```

120

121

### Hidden Field Error Handling

122

123

Render validation errors for hidden form fields.

124

125

```python { .api }

126

def render_hidden_errors(form):

127

"""

128

Render validation errors for hidden form fields.

129

130

Args:

131

form: WTForms form object

132

133

Returns:

134

Rendered HTML alert with hidden field errors

135

136

Used for displaying validation errors from hidden fields like CSRF tokens

137

that users cannot see but may have validation issues.

138

"""

139

```

140

141

### Switch Field Component

142

143

Custom field type for Bootstrap switch components.

144

145

```python { .api }

146

class SwitchField(BooleanField):

147

"""

148

A wrapper field for BooleanField that renders as a Bootstrap switch.

149

150

Inherits all BooleanField functionality but renders with switch styling

151

instead of standard checkbox appearance.

152

"""

153

154

def __init__(self, label=None, **kwargs):

155

"""

156

Initialize switch field.

157

158

Args:

159

label (str): Field label

160

**kwargs: Additional field arguments passed to BooleanField

161

"""

162

```

163

164

## Form Layout Types

165

166

### Basic Layout

167

168

Standard vertical form layout with fields stacked vertically.

169

170

```html

171

<!-- Template usage -->

172

{% from 'bootstrap5/form.html' import render_form %}

173

{{ render_form(form, form_type="basic") }}

174

175

<!-- Rendered output structure -->

176

<form method="post" role="form">

177

<div class="mb-3">

178

<label class="form-label">Username</label>

179

<input type="text" class="form-control" name="username">

180

</div>

181

<div class="mb-3">

182

<label class="form-label">Password</label>

183

<input type="password" class="form-control" name="password">

184

</div>

185

<button type="submit" class="btn btn-primary">Submit</button>

186

</form>

187

```

188

189

### Inline Layout

190

191

Horizontal inline form layout with fields arranged side-by-side.

192

193

```html

194

<!-- Template usage -->

195

{{ render_form(form, form_type="inline") }}

196

197

<!-- Rendered output structure (Bootstrap 5) -->

198

<form method="post" role="form" class="row row-cols-lg-auto g-3 align-items-center">

199

<div class="col">

200

<label class="visually-hidden">Username</label>

201

<input type="text" class="form-control" name="username" placeholder="Username">

202

</div>

203

<div class="col">

204

<label class="visually-hidden">Password</label>

205

<input type="password" class="form-control" name="password" placeholder="Password">

206

</div>

207

<div class="col">

208

<button type="submit" class="btn btn-primary">Submit</button>

209

</div>

210

</form>

211

```

212

213

### Horizontal Layout

214

215

Two-column layout with labels and fields in separate columns.

216

217

```html

218

<!-- Template usage -->

219

{{ render_form(form, form_type="horizontal", horizontal_columns=('lg', 2, 10)) }}

220

221

<!-- Rendered output structure -->

222

<form method="post" role="form">

223

<div class="row mb-3">

224

<label class="col-lg-2 col-form-label">Username</label>

225

<div class="col-lg-10">

226

<input type="text" class="form-control" name="username">

227

</div>

228

</div>

229

<div class="row mb-3">

230

<label class="col-lg-2 col-form-label">Password</label>

231

<div class="col-lg-10">

232

<input type="password" class="form-control" name="password">

233

</div>

234

</div>

235

<div class="row">

236

<div class="col-lg-10 offset-lg-2">

237

<button type="submit" class="btn btn-primary">Submit</button>

238

</div>

239

</div>

240

</form>

241

```

242

243

## Validation and Error Handling

244

245

### Automatic Validation States

246

247

Bootstrap-Flask automatically applies validation classes based on field errors:

248

249

```html

250

<!-- Field with validation error -->

251

<div class="mb-3">

252

<label class="form-label">Email</label>

253

<input type="email" class="form-control is-invalid" name="email" value="invalid-email">

254

<div class="invalid-feedback">

255

Please enter a valid email address.

256

</div>

257

</div>

258

259

<!-- Field with valid input -->

260

<div class="mb-3">

261

<label class="form-label">Username</label>

262

<input type="text" class="form-control is-valid" name="username" value="john_doe">

263

<div class="valid-feedback">

264

Looks good!

265

</div>

266

</div>

267

```

268

269

### Multiple Error Messages

270

271

When a field has multiple validation errors, all are displayed:

272

273

```html

274

<div class="invalid-feedback">

275

<ul class="mb-0">

276

<li>This field is required.</li>

277

<li>Must be between 8 and 150 characters long.</li>

278

</ul>

279

</div>

280

```

281

282

## Usage Examples

283

284

### Basic Form Example

285

286

```python

287

# forms.py

288

from flask_wtf import FlaskForm

289

from wtforms import StringField, PasswordField, BooleanField, SubmitField

290

from wtforms.validators import DataRequired, Length, Email

291

292

class LoginForm(FlaskForm):

293

username = StringField('Username', validators=[DataRequired(), Length(1, 20)])

294

password = PasswordField('Password', validators=[DataRequired(), Length(8, 150)])

295

remember = BooleanField('Remember me')

296

submit = SubmitField('Sign In')

297

```

298

299

```html

300

<!-- template.html -->

301

{% from 'bootstrap5/form.html' import render_form %}

302

303

<div class="container">

304

<div class="row justify-content-center">

305

<div class="col-md-6">

306

<h2>Login</h2>

307

{{ render_form(form) }}

308

</div>

309

</div>

310

</div>

311

```

312

313

### Customized Form with Styling

314

315

```html

316

{% from 'bootstrap5/form.html' import render_form %}

317

318

{{ render_form(form,

319

form_type="horizontal",

320

horizontal_columns=('md', 3, 9),

321

button_style="success",

322

button_size="lg",

323

extra_classes="border p-4 rounded"

324

) }}

325

```

326

327

### Multi-Column Form Layout

328

329

```html

330

{% from 'bootstrap5/form.html' import render_form_row, render_field %}

331

332

<form method="post">

333

{{ form.hidden_tag() }}

334

335

<!-- Name fields in one row -->

336

{{ render_form_row([form.first_name, form.last_name],

337

col_map={'first_name': 'col-md-6', 'last_name': 'col-md-6'}) }}

338

339

<!-- Full-width email field -->

340

{{ render_field(form.email) }}

341

342

<!-- Address fields in one row -->

343

{{ render_form_row([form.address, form.city, form.zip_code],

344

col_map={'address': 'col-md-6', 'city': 'col-md-4', 'zip_code': 'col-md-2'}) }}

345

346

{{ render_field(form.submit) }}

347

</form>

348

```

349

350

### Switch Field Usage

351

352

```python

353

# forms.py

354

from flask_bootstrap import SwitchField

355

356

class SettingsForm(FlaskForm):

357

notifications = SwitchField('Enable notifications')

358

dark_mode = SwitchField('Dark mode')

359

auto_save = SwitchField('Auto-save documents')

360

```

361

362

```html

363

<!-- Renders as Bootstrap switches -->

364

{% from 'bootstrap5/form.html' import render_field %}

365

366

<div class="form-check form-switch">

367

{{ render_field(form.notifications) }}

368

</div>

369

```

370

371

### File Upload Forms

372

373

```python

374

# forms.py

375

from wtforms import FileField

376

from flask_wtf.file import FileRequired, FileAllowed

377

378

class UploadForm(FlaskForm):

379

file = FileField('Upload File', validators=[

380

FileRequired(),

381

FileAllowed(['jpg', 'png', 'pdf'], 'Images and PDFs only!')

382

])

383

submit = SubmitField('Upload')

384

```

385

386

```html

387

<!-- Automatically sets enctype="multipart/form-data" -->

388

{{ render_form(form) }}

389

```

390

391

### Custom Button Styling

392

393

```html

394

{{ render_form(form,

395

button_map={

396

'submit': 'btn-success btn-lg',

397

'cancel': 'btn-outline-secondary',

398

'delete': 'btn-danger'

399

}

400

) }}

401

```

402

403

### Bootstrap 4 vs Bootstrap 5 Differences

404

405

```html

406

<!-- Bootstrap 4 -->

407

{% from 'bootstrap4/form.html' import render_form %}

408

{{ render_form(form, form_type="inline") }}

409

410

<!-- Bootstrap 5 -->

411

{% from 'bootstrap5/form.html' import render_form %}

412

{{ render_form(form,

413

form_type="inline",

414

form_inline_classes="row row-cols-lg-auto g-3 align-items-center"

415

) }}

416

```

417

418

The main differences include updated CSS classes, form control styling, and enhanced accessibility features in Bootstrap 5.