CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-bootstrap-flask

Bootstrap 4 & 5 helper for Flask projects providing Jinja macros for forms, tables, navigation, and utilities.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

form-rendering.mddocs/

Form Rendering

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.

Capabilities

Complete Form Rendering

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

def render_form(form, action="", method="post", extra_classes=None, role="form",
               form_type="basic", horizontal_columns=('lg', 2, 10), enctype=None,
               button_map={}, button_style="", button_size="", id="",
               novalidate=False, render_kw={}, form_group_classes="",
               form_inline_classes=""):
    """
    Render a complete form with Bootstrap styling.
    
    Args:
        form: WTForms form object
        action (str): Form action URL (default: current URL)
        method (str): HTTP method (default: "post")
        extra_classes (str): Additional CSS classes for form element
        role (str): ARIA role attribute (default: "form")
        form_type (str): Layout type - "basic", "inline", or "horizontal"
        horizontal_columns (tuple): Column sizing for horizontal layout (breakpoint, label_cols, field_cols)
        enctype (str): Form encoding type (auto-detected for file uploads)
        button_map (dict): Custom button styles per field name
        button_style (str): Default button style for submit buttons
        button_size (str): Default button size for submit buttons
        id (str): Form element ID attribute
        novalidate (bool): Disable HTML5 validation
        render_kw (dict): Additional attributes for form element
        form_group_classes (str): Classes for form groups (Bootstrap 5)
        form_inline_classes (str): Classes for inline forms (Bootstrap 5)
        
    Returns:
        Rendered HTML form with Bootstrap styling
        
    Layout Types:
        - basic: Standard vertical form layout
        - inline: Horizontal inline form layout  
        - horizontal: Two-column layout with labels and fields
    """

Individual Field Rendering

Render individual form fields with Bootstrap styling and validation states.

def render_field(field, form_type="basic", horizontal_columns=('lg', 2, 10),
                button_map={}, button_style='', button_size='', form_group_classes=''):
    """
    Render an individual form field with Bootstrap styling.
    
    Args:
        field: WTForms field object
        form_type (str): Layout type - "basic", "inline", or "horizontal"
        horizontal_columns (tuple): Column sizing for horizontal layout
        button_map (dict): Custom button styles for this field
        button_style (str): Default button style for submit/button fields
        button_size (str): Default button size for submit/button fields  
        form_group_classes (str): Additional classes for form group (Bootstrap 5)
        
    Returns:
        Rendered HTML field with appropriate Bootstrap classes
        
    Field Type Support:
        - Text inputs (StringField, TextAreaField, etc.)
        - Select fields (SelectField, SelectMultipleField)
        - Boolean fields (BooleanField, SwitchField)
        - File uploads (FileField, MultipleFileField)
        - Hidden fields (HiddenField)
        - Submit buttons (SubmitField)
        - Custom field types
        
    Validation Features:
        - Automatic validation state classes (is-valid, is-invalid)
        - Error message display
        - Required field indicators
    """

Multi-Column Form Rows

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

def render_form_row(fields, row_class='row', col_class_default='col',
                   col_map={}, button_map={}, button_style='', button_size='',
                   form_group_classes='', form_type='basic',
                   horizontal_columns=('lg', 2, 10)):
    """
    Render multiple form fields in a single row layout.
    
    Args:
        fields (list): List of WTForms field objects
        row_class (str): CSS class for row container (default: 'row')
        col_class_default (str): Default column class (default: 'col')
        col_map (dict): Custom column classes per field name
        button_map (dict): Custom button styles per field name
        button_style (str): Default button style
        button_size (str): Default button size
        form_group_classes (str): Form group classes (Bootstrap 5)
        form_type (str): Form layout type
        horizontal_columns (tuple): Horizontal form column configuration
        
    Returns:
        Rendered HTML row with fields in Bootstrap grid layout
        
    Example col_map:
        {
            'first_name': 'col-md-6',
            'last_name': 'col-md-6', 
            'email': 'col-12'
        }
    """

Hidden Field Error Handling

Render validation errors for hidden form fields.

def render_hidden_errors(form):
    """
    Render validation errors for hidden form fields.
    
    Args:
        form: WTForms form object
        
    Returns:
        Rendered HTML alert with hidden field errors
        
    Used for displaying validation errors from hidden fields like CSRF tokens
    that users cannot see but may have validation issues.
    """

Switch Field Component

Custom field type for Bootstrap switch components.

class SwitchField(BooleanField):
    """
    A wrapper field for BooleanField that renders as a Bootstrap switch.
    
    Inherits all BooleanField functionality but renders with switch styling
    instead of standard checkbox appearance.
    """
    
    def __init__(self, label=None, **kwargs):
        """
        Initialize switch field.
        
        Args:
            label (str): Field label
            **kwargs: Additional field arguments passed to BooleanField
        """

Form Layout Types

Basic Layout

Standard vertical form layout with fields stacked vertically.

<!-- Template usage -->
{% from 'bootstrap5/form.html' import render_form %}
{{ render_form(form, form_type="basic") }}

<!-- Rendered output structure -->
<form method="post" role="form">
    <div class="mb-3">
        <label class="form-label">Username</label>
        <input type="text" class="form-control" name="username">
    </div>
    <div class="mb-3">
        <label class="form-label">Password</label>
        <input type="password" class="form-control" name="password">
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Inline Layout

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

<!-- Template usage -->
{{ render_form(form, form_type="inline") }}

<!-- Rendered output structure (Bootstrap 5) -->
<form method="post" role="form" class="row row-cols-lg-auto g-3 align-items-center">
    <div class="col">
        <label class="visually-hidden">Username</label>
        <input type="text" class="form-control" name="username" placeholder="Username">
    </div>
    <div class="col">
        <label class="visually-hidden">Password</label>
        <input type="password" class="form-control" name="password" placeholder="Password">
    </div>
    <div class="col">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>

Horizontal Layout

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

<!-- Template usage -->
{{ render_form(form, form_type="horizontal", horizontal_columns=('lg', 2, 10)) }}

<!-- Rendered output structure -->
<form method="post" role="form">
    <div class="row mb-3">
        <label class="col-lg-2 col-form-label">Username</label>
        <div class="col-lg-10">
            <input type="text" class="form-control" name="username">
        </div>
    </div>
    <div class="row mb-3">
        <label class="col-lg-2 col-form-label">Password</label>
        <div class="col-lg-10">
            <input type="password" class="form-control" name="password">
        </div>
    </div>
    <div class="row">
        <div class="col-lg-10 offset-lg-2">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
</form>

Validation and Error Handling

Automatic Validation States

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

<!-- Field with validation error -->
<div class="mb-3">
    <label class="form-label">Email</label>
    <input type="email" class="form-control is-invalid" name="email" value="invalid-email">
    <div class="invalid-feedback">
        Please enter a valid email address.
    </div>
</div>

<!-- Field with valid input -->
<div class="mb-3">
    <label class="form-label">Username</label>
    <input type="text" class="form-control is-valid" name="username" value="john_doe">
    <div class="valid-feedback">
        Looks good!
    </div>
</div>

Multiple Error Messages

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

<div class="invalid-feedback">
    <ul class="mb-0">
        <li>This field is required.</li>
        <li>Must be between 8 and 150 characters long.</li>
    </ul>
</div>

Usage Examples

Basic Form Example

# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Length, Email

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(1, 20)])
    password = PasswordField('Password', validators=[DataRequired(), Length(8, 150)])
    remember = BooleanField('Remember me')
    submit = SubmitField('Sign In')
<!-- template.html -->
{% from 'bootstrap5/form.html' import render_form %}

<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-6">
            <h2>Login</h2>
            {{ render_form(form) }}
        </div>
    </div>
</div>

Customized Form with Styling

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

{{ render_form(form, 
    form_type="horizontal",
    horizontal_columns=('md', 3, 9),
    button_style="success", 
    button_size="lg",
    extra_classes="border p-4 rounded"
) }}

Multi-Column Form Layout

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

<form method="post">
    {{ form.hidden_tag() }}
    
    <!-- Name fields in one row -->
    {{ render_form_row([form.first_name, form.last_name], 
        col_map={'first_name': 'col-md-6', 'last_name': 'col-md-6'}) }}
    
    <!-- Full-width email field -->
    {{ render_field(form.email) }}
    
    <!-- Address fields in one row -->
    {{ render_form_row([form.address, form.city, form.zip_code],
        col_map={'address': 'col-md-6', 'city': 'col-md-4', 'zip_code': 'col-md-2'}) }}
    
    {{ render_field(form.submit) }}
</form>

Switch Field Usage

# forms.py
from flask_bootstrap import SwitchField

class SettingsForm(FlaskForm):
    notifications = SwitchField('Enable notifications')
    dark_mode = SwitchField('Dark mode')
    auto_save = SwitchField('Auto-save documents')
<!-- Renders as Bootstrap switches -->
{% from 'bootstrap5/form.html' import render_field %}

<div class="form-check form-switch">
    {{ render_field(form.notifications) }}
</div>

File Upload Forms

# forms.py
from wtforms import FileField
from flask_wtf.file import FileRequired, FileAllowed

class UploadForm(FlaskForm):
    file = FileField('Upload File', validators=[
        FileRequired(),
        FileAllowed(['jpg', 'png', 'pdf'], 'Images and PDFs only!')
    ])
    submit = SubmitField('Upload')
<!-- Automatically sets enctype="multipart/form-data" -->
{{ render_form(form) }}

Custom Button Styling

{{ render_form(form, 
    button_map={
        'submit': 'btn-success btn-lg',
        'cancel': 'btn-outline-secondary',
        'delete': 'btn-danger'
    }
) }}

Bootstrap 4 vs Bootstrap 5 Differences

<!-- Bootstrap 4 -->
{% from 'bootstrap4/form.html' import render_form %}
{{ render_form(form, form_type="inline") }}

<!-- Bootstrap 5 -->
{% from 'bootstrap5/form.html' import render_form %}
{{ render_form(form, 
    form_type="inline",
    form_inline_classes="row row-cols-lg-auto g-3 align-items-center"
) }}

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

Install with Tessl CLI

npx tessl i tessl/pypi-bootstrap-flask

docs

extension-setup.md

form-rendering.md

index.md

navigation.md

pagination.md

python-utilities.md

table-rendering.md

utilities.md

tile.json