Simplest Example of HTMX

Simplest Example of HTMX

Just as Interia is to Laravel, HTMX is to Django ?

HTMX is one of the less popular libraries/adapters out there - in fact there isn't yet a wikipedia page on HTMX. Just as Interia is to Laravel, HTMX is to Django - but this is a misconception. Intertia can be used in Django as well and HTMX can be used in Laravel too.

HTMX is JavaScript-less AJAX for the end-user (developer). Under the hood, HTMX uses JavaScript by including its library.

The simplest example of using HTMX is by having an HTML <form> in your web page and some inputs a standard submit button. The JavaScript way to handle form submissions is the use e.preventdefault() React, Angular, Vue or Svelte and have client-side validation and then submit the form via JSON via axios or the like and get back a JSON response to the browser which the client-side framework will parse and re-render the component to update the DOM. All this is without refreshing the page via JavaScript code.

But the same non-refreshing page effect can be achieved via HTMX, except that, instead of returning a JSON from the server API call, we render back an HTML snippet from the server that's sent back to the browser and the entire HTML snippet is inserted into the webpage without page re-loading. It's still AJAX under the hood, but instead of JSON, it's HTML and you can do server-side validation just as if like you're submitting a traditional HTML form.

Here's an example (using vanilla PHP) where there exists a timer on the page just to show that the page doesn't get refreshed on clicking the submit button in the form - a full page refresh would reset the timer back to 0.

form-page.php :

<!DOCTYPE html>
<head>
    <title>HTMX Example</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"/>
    <script src="https://unpkg.com/htmx.org@1.9.3"></script>
</head>
<body>

<div class="container mt-5 border border-danger">

    Content in red DIV with live time does not reset.<br/>

    <script type="text/javascript" charset="utf-8">
    let timer = 0;    
    setInterval(() =>
    {        
        timer += 1;
        document.getElementById('time').innerHTML = timer;
    }, 1000);
    </script>

    <div class="mt-2">Timer : <span id="time"></span></div>

    <form
        hx-post="form-post.php"
        hx-target="this"
        hx-swap="innerHTML"
    >
        <?php require_once "form-post.php" ?>
    </form>

</div>


</body>
</html>

The following php snippet inserted into the form-page above will be used for both GET and POST. Ideally, you would render different files in Laravel based on the REQUEST type.

form-post.php :

<?php
if (isset($_POST['name']) && isset($_POST['email']))
{
    ?>
    <div class="py-2">        
        <strong>Data POSTed</strong>
        <div>
            Name : <?php echo $_POST['name'] ?><br/>
            Email : <?php echo $_POST['email'] ?><br/>
        </div>
        <button
            type="button"
            hx-get="form-post.php"
            class="mt-3 btn btn-primary"
        >
            Add Data again
        </button>
    </div>
    <?php
}
else
{
    ?>
    <div class="py-2">
        <div class="form-group py-2">
            <label for="txt-name">Name</label>
            <input type="text" class="form-control" id="txt-Name" name="name" placeholder="Enter your name" />
        </div>
        <div class="form-group py-2">
            <label for="txt-Email">Email</label>
            <input type="email" class="form-control" id="txt-Email" name="email" placeholder="Enter your email address" />
        </div>        
        <button type="submit" class="btn btn-primary mt-1">Submit</button>
    </div>
    <?php
}
?>

Run this as php -S localhost:8001 in the terminal powershell and goto http://localhost:8001/form-page.php and click the submit button to see it in action - the timer will continue as it is (not from 0) since it's not a full page refresh.

hx-post="form-post.php"
hit the form-post.php page when the submit button is clicked
hx-target="this"
target is the same HTML Element which is this current <form> - you can have the HTML snippet returned to be updated on another DOM element though and it doesn't necessarily have to be a <form>, it can be a <div> as well.
hx-swap="innerHTML"
innerHTML specifies that only the <form>'s innerHTML to be replaced and not the entire <form hx-post="form-post.php" hx-target="this" hx-swap="innerHTML"> ... </form>, hx-swap="outerHTML" will replace the <form hx-post="form-post.php" hx-target="this" hx-swap="innerHTML"> ... </form> as well.