Open In App

Dynamic Forms Handling with HTMX and Python Flask

Last Updated : 30 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Dynamic forms enhance the user experience by updating the parts of a web page without the full page reload, the powerful library can allow for the AJAX requests and dynamic updates, while Flask can provide a robust backend framework for Python. This article will guide you through integrating the HTMX with Flask to create dynamic forms.

  • HTMX: It can allow you to use the AJAX, CSS transitions, and WebSockets directly in the HTML. It can enable you to update the parts of the Web page dynamically based on the user interactions without needing to write the extensive JavaScript Code.
  • Flask: It is a micro web framework for Python. It can be designed to be simple and easy to use, making it a good choice for small to medium-sized applications. Flask is based on the WSGI toolkit and Jinja2 template engine.

Setting up Flask and HTMX

Installing the Flask

We need to install the Flask using pip:

pip install Flask

Installing the HTMX

HTMX is the JavaScript library that can be included via the CDN and add the following scripts to the HTML template.

<script src="https://unpkg.com/[email protected]"></script>

Creating the Basic Flask Application

Create the new file named as app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
return render_template('index.html')

if __name__ == '__main__':
app.run(debug=True)
  • Flask(__name__): It can be initializes the Flask application.
  • @app.route('/'): It can defines the routes for the homepage and renders the index.html template.
  • app.run(debug=True): It can be starts the development server with debug mode enabled.

HTMX Setup:

Include the HTMX in HTML

Add the HTMX library to the HTML via CDN

<script src="https://unpkg.com/[email protected]"></script>

This script can allows you to use the HTMX features such as the AJAX requests and dynamic content updates directly into the HTML page.

Create the new directory for the project and setup the basic Flask application.

Project Structure

flaskfile

templates/index.html

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Forms with HTMX and Flask</title>
    <script src="https://unpkg.com/[email protected]"></script>
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
    <div class="container">
        <h1>Dynamic Forms with HTMX and Flask</h1>
        
        <form hx-get="/update-fields" hx-target="#dynamic-fields">
            <div class="form-group">
                <label for="type">Form Type:</label>
                <select id="type" name="type" class="form-control">
                    <option value="basic">Basic</option>
                    <option value="advanced">Advanced</option>
                </select>
            </div>
        </form>

        <form hx-post="/submit" hx-target="#response" hx-swap="innerHTML">
            <div class="form-group">
                <label for="name">Name:</label>
                <input type="text" id="name" name="name" class="form-control" required>
            </div>

            <div class="form-group">
                <label for="email">Email:</label>
                <input type="email" id="email" name="email" class="form-control" required>
            </div>

            <div class="form-group">
                <label for="phone">Phone:</label>
                <input type="tel" id="phone" name="phone" class="form-control">
            </div>

            <div class="form-group">
                <label for="address">Address:</label>
                <textarea id="address" name="address" class="form-control"></textarea>
            </div>

            <div id="dynamic-fields"></div>

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

        <div id="response"></div>
    </div>
</body>
</html>

static/styles.css

CSS
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    width: 80%;
    max-width: 800px;
    margin: 20px auto;
    padding: 20px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1 {
    text-align: center;
    color: #333;
}

form {
    margin-bottom: 20px;
}

.form-group {
    margin-bottom: 15px;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input[type="text"],
input[type="email"],
input[type="tel"],
textarea {
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

textarea {
    height: 100px;
}

button {
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    background-color: #007bff;
    color: #fff;
    font-size: 16px;
    cursor: pointer;
}

button:hover {
    background-color: #0056b3;
}

.alert {
    padding: 15px;
    margin-top: 20px;
    border-radius: 4px;
}

.alert-success {
    background-color: #d4edda;
    color: #155724;
}

.alert-error {
    background-color: #f8d7da;
    color: #721c24;
}

test/test_app.py

Python
import pytest
from app import app

@pytest.fixture
def client():
    app.config['TESTING'] = True
    with app.test_client() as client:
        yield client

def test_index(client):
    response = client.get('/')
    assert b'Dynamic Forms with HTMX and Flask' in response.data

def test_update_fields_basic(client):
    response = client.get('/update-fields', query_string={'type': 'basic'})
    assert b'' in response.data

def test_update_fields_advanced(client):
    response = client.get('/update-fields', query_string={'type': 'advanced'})
    assert b'Additional Information' in response.data

def test_submit(client):
    response = client.post('/submit', data={'name': 'Alice', 'email': '[email protected]'})
    assert b'Hello, Alice!' in response.data

def test_submit_with_extra_field(client):
    response = client.post('/submit', data={'name': 'Alice', 'email': '[email protected]', 'extra': 'Extra Value'})
    assert b'Hello, Alice! Extra field value: Extra Value' in response.data

def test_submit_no_name(client):
    response = client.post('/submit', data={'email': '[email protected]'})
    assert b'Error: Name and Email are required!' in response.data

app.py

Python
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/update-fields')
def update_fields():
    type_ = request.args.get('type')
    if type_ == 'advanced':
        fields = '''
        <div class="form-group">
            <label for="extra">Additional Information:</label>
            <input type="text" id="extra" name="extra" class="form-control">
        </div>
        '''
    else:
        fields = ''
    return fields

@app.route('/submit', methods=['POST'])
def submit():
    name = request.form.get('name')
    email = request.form.get('email')
    phone = request.form.get('phone')
    address = request.form.get('address')
    extra = request.form.get('extra', '')
    
    if not name or not email:
        return "<p>Error: Name and Email are required!</p>", 400
    
    response = f"""
    <div class="alert alert-success">
        <h4>Submission Successful!</h4>
        <p><strong>Name:</strong> {name}</p>
        <p><strong>Email:</strong> {email}</p>
        <p><strong>Phone:</strong> {phone}</p>
        <p><strong>Address:</strong> {address}</p>
        <p><strong>Additional Info:</strong> {extra}</p>
    </div>
    """
    return response

if __name__ == '__main__':
    app.run(debug=True)

Output

Conclusion

Combining the HTMX with Flask for the powerful dynamic form handling. By the following these steps outlined above, we can create the responsive, interactive web applications that improve the user experience. Continue to explore the HTMX and Flask documentation for more advanced features and best pratices.


Next Article
Article Tags :
Practice Tags :

Similar Reads