Exploring HTMX: Enhancing Web Development with Interactive Mini Projects

Exploring HTMX: Enhancing Web Development with Interactive Mini Projects

HTMX is a powerful library that allows developers to create dynamic web applications with ease, leveraging the full potential of HTML attributes. By using HTMX, we can handle server requests directly from HTML elements, making our applications more responsive and interactive without needing complex JavaScript code. In this blog, we’ll explore the importance of HTMX and walk through some mini-projects demonstrating its capabilities.

Why HTMX?

  1. Simplified Development: HTMX simplifies the development process by allowing server interactions through HTML attributes, reducing the need for extensive JavaScript.

  2. Enhanced User Experience: By providing instant feedback and interactions, HTMX enhances the user experience, making web applications feel more responsive.

  3. Progressive Enhancement: HTMX can be progressively added to existing projects, allowing for a smooth transition and incremental improvements.

How to Install and Use HTMX

HTMX is a powerful library that allows you to add AJAX requests, CSS transitions, WebSocket updates, and server-sent events directly in your HTML. Here's a quick guide on how to get started with HTMX:

Installation

To use HTMX in your project, you can include it directly via a CDN or by downloading the library.

Using CDN: Add the following script tag to the <head> of your HTML document:

<script src="https://unpkg.com/htmx.org@2.0.1" integrity="sha384-QWGpdj554B4ETpJJC9z+ZHJcA/i59TyjxEPXiiUgN2WmTyV5OEZWCD6gQhgkdpB/" crossorigin="anonymous"></script>

Downloading HTMX: You can also download HTMX from the official website and include it in your project.

Mini Projects with HTMX

1. Simple Request

In this project, we’ll create a simple interface to fetch user data from the server and display it dynamically on the webpage.

HTML (simple_request.html):

<body>
    <div class="text-center">
        <h1 class="text-2xl font-bold my-5">Simple Request</h1>
        <button hx-get="/users" hx-target="#users" hx-confirm="Are you sure?" hx-indicator="#loading" hx-vals='{"limit":3}' class="bg-blue-500 text-white py-2 px-3 my-5 rounded-lg">Fetch Users</button>
        <span class="htmx-indicator" id="loading">
            <img src="loader.gif" alt="Loading..." class="m-auto h-10" />
        </span>
        <div id="users"></div>
    </div>
</body>

Server-side Code (server.js):

app.get('/users', async (req, res) => {
    setTimeout(async () => {
        const limit = +req.query.limit || 10;
        const response = await fetch(`https://jsonplaceholder.typicode.com/users?_limit=${limit}`);
        const users = await response.json();

        res.send(`
            <h1 class="text-2xl font-bold my-4">Users</h1>
            <ul>
                ${users.map(user => `<li>${user.name}</li>`).join('')}
            </ul>
        `);
    }, 2000);
});

This project demonstrates how to use HTMX for live searching through a list of contacts.

HTML (contact.html):

<body class="bg-blue-900">
    <div class="container mx-auto py-8 max-w-lg">
        <span class="htmx-indicator" id="loading">
            <img src="/loader.gif" alt="Loading..." class="m-auto h-10" />
        </span>
        <div class="bg-gray-900 text-white p-4 border border-gray-600 rounded-lg max-w-lg m-auto">
            <h3 class="text-2xl mb-3 text-center">Search Contacts</h3>
            <input class="border border-gray-600 bg-gray-800 p-2 rounded-lg w-full mb-5" type="search" name="search" placeholder="Begin Typing To Search Users..." hx-post="/search" hx-trigger="input changed delay:500ms, search" hx-target="#search-results" hx-indicator="#loading" />
            <table class="min-w-full divide-y divide-gray-200">
                <thead class="bg-gray-800 text-white">
                    <tr>
                        <th scope="col" class="px-6 py-3 text-center text-xs font-medium uppercase tracking-wider">Name</th>
                        <th scope="col" class="px-6 py-3 text-center text-xs font-medium uppercase tracking-wider">Email</th>
                    </tr>
                </thead>
                <tbody id="search-results" class="divide-y divide-gray-600">
                    <!-- Your search results go here -->
                </tbody>
            </table>
        </div>
    </div>
</body>

Server-side Code (server.js):

app.post('/search', (req, res) => {
    const searchTerm = req.body.search.toLowerCase();
    if (!searchTerm) {
        return res.send('<tr></tr>');
    }

    const searchResults = contacts.filter((contact) => {
        const name = contact.name.toLowerCase();
        const email = contact.email.toLowerCase();
        return name.includes(searchTerm) || email.includes(searchTerm);
    });

    setTimeout(() => {
        const searchResultHtml = searchResults.map(contact => `
            <tr>
                <td><div class="my-4 p-2">${contact.name}</div></td>
                <td><div class="my-4 p-2">${contact.email}</div></td>
            </tr>
        `).join('');
        res.send(searchResultHtml);
    }, 1000);
});

3. Temperature Converter

This project shows how to convert Fahrenheit to Celsius using HTMX for form submission.

HTML (temperature.html):

<body>
    <div class="text-center">
        <h1 class="text-2xl font-bold my-5">Temperature Converter</h1>
        <div class="container mx-auto mt-8 text-center">
            <div class="bg-white p-4 border rounded-lg max-w-lg m-auto">
                <form hx-trigger="submit" hx-post="/convert" hx-target="#result" hx-indicator="#loading">
                    <label for="fahrenheit">Fahrenheit:</label>
                    <input type="number" id="fahrenheit" name="fahrenheit" class="border p-2 rounded" value="32" required>
                    <button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded">Convert</button>
                    <div id="result" class="mt-6 text-xl"></div>
                    <div id="indicator" class="htmx-indicator">
                        <img src="./loader.gif" alt="Loading..." class="m-auto h-10" />
                    </div>
                </form>
            </div>
        </div>
    </div>
</body>

Server-side Code (server.js):

app.post('/convert', async (req, res) => {
    setTimeout(() => {
        const fahrenheit = parseFloat(req.body.fahrenheit);
        const celsius = (fahrenheit - 32) * 5 / 9;
        res.send(`
            <p>
                ${fahrenheit}°F is ${celsius.toFixed(2)}°C
            </p>
        `);
    }, 2000);
});

Conclusion

HTMX is a valuable tool for modern web development, providing a way to create dynamic and interactive applications with minimal JavaScript. By leveraging the power of HTML attributes, HTMX allows for cleaner, more maintainable code and enhances the user experience. These mini-projects are just a glimpse of what HTMX can achieve, and I encourage you to explore further and incorporate HTMX into your own projects for a more interactive web.

Feel free to check out the complete code for these projects on my GitHub. Happy coding!