HTMX: Execute Logic Before Swapping

HTMXJavaScript
HTMX is a great little library that allows you to make HTTP requests (among other things) from any node in the DOM. There is a lot to say about HTMX and it’s philosophy. The main idea is that the server should respond with html, rather than json. To read more about the HTMX approach please refer to their docs at https://htmx.org/docs/ and their essays at https://htmx.org/essays/. If you have the time, I recommend reading their book HYPERMEDIA SYSTEMS. It outlines a new way to code websites and apps, using tried and true, but largely forgotten, web dev principles.

When using a front end framework like React, you can make a request, wait for the response, and then apply logic on the returned data. If there is an error, you can run some error logic, if success then run success logic.

HTMX works a little differently. If the request comes back with a status code outside of the 200 range, it doesn’t do anything with the response. The page does not change. HTMX does provide a way for you to run logic after a request finishes, and before there is any HTML swapping. The example here is detecting a successful response, and closing a modal that contains a user form only if the response has a status code of 200.

The afterRequest event

Often you will want to POST form data, and if validation errors are returned, you want to display the validation messages in the modal while it is still open. If the POST is successful and has no validation errors, then close the modal. With HTMX this can be achieved by listening for the HTMX event afterRequest. This event is fired when the response settles, and before HTMX does any DOM node swapping.

In this ‘form inside a modal pattern’ example, we use the unassigned HTTP code 209 to mean the response contains error messages that need to be displayed. If the response has a status code of 209, the modal should remain open to display validation messages. A successful operation returns a 200 status code. If a 200 response comes in, we want to close the modal.

We do not want listen to just any successful response. We only care about the response triggered by the user form. HTMX uses headers that contain information regarding the source of the request. In our case, we can look at the "HX-Trigger" header to see the id of the DOM node that triggered the event. If the HTTP call was not triggered by the #htmx-user-form, we will ignore it.

To code out this behavior, first, listen for events coming from the modal (eventIsFromTheForm). Then, detect if the request was successful (eventWasSuccessful). If the request is from the modal (headers["HX-Trigger"] === "htmx-user-form") and is successful, then close the modal. If not, keep the modal open to display the validation messages.

In order to not bury this logic in some place hard to find, name the script in a way that is easy to understand, like userModalFormAfterRequestListener.js, and put it in the head of your HTML document.

htmx.on("htmx:afterRequest", (e) => {
  // assign the data we need to descriptive variables
  const eventIsFromTheForm =
    e.detail.requestConfig.headers["HX-Trigger"] === "htmx-user-form";
  const eventWasSuccessful = e.detail.xhr.status === 200;

  // we only care about events from the user form
  if (!eventIsFromTheUserForm) return;

  // only status code 200 close the modal. (our backend
  // gives a response with validation errors/messages a status of 209), so
  // keep the modal open in that case in order to display the messages
  if (!eventWasSuccessful) return;

  // if no validation errors come back,
  // reset the form and close the modal
  document.getElementById("htmx-user-form").reset();
  // assuming the modal is a <dialog> element with an
  // id #userModal, `userModal.close()` will close it
  userModal.close();

});

Although we are using the "htmx:afterRequest" event to determine whether or not to close a modal, listening for this event allows you to run any logic you need. You can grab status codes, the DOM node that issued the request, and anything else in the response in order to run your own logic based on response data.

"htmx:afterRequest" is only one of many events that HTMX emits. For a full list, please see the HTMX docs at https://htmx.org/events/

Do you need a software agency?

We want to hear from you!