I am using the following code combining thymeleaf and HTMX I wrote a code to receive a serial number from an input form, and when the focus is removed from this input form, a request is sent to the server and the response is received as html based on thymleaf. After the screen swap rendering is complete, I want to capture the htmx:afterSwap event in javascript and react based on the result. If the serial number is empty or duplicated, we want to implement a user UX that gives **focus()** to the input tag so that the user can input again. However, the focus is not assigned to the serial number and moves on to the next input tag. After entering the serial number, use the tab key or use the mouse to click the next input tag. ## Please tell me how to solve this problem. I tried using various events, such as **html:afterSettle** and **html:afterSwap**, but I couldn't solve it. ## input form ```html <label class="equipment-label" id="equipmentSn-label"> <strong class="label flex-1 flex justify-end-safe"> <span class="text-red-700">*</span> <span class="text-blue-700">Serial Num</span> </strong> <input class="equipment-input-text" id="equipmentSn" th:field="*{equipmentSn}" placeholder="ex) AFUXXXXXX" type="text" required oninvalid="this.setCustomValidity('Please enter your serial number')" oninput="this.setCustomValidity('')" th:hx-post="@{/equipment/check-serial}" hx-trigger="blure changed delay:100ms" hx-target="#sn-check-result"/> </label> <label class="equipment-label"> <strong class="label flex-1"></strong> <strong id="sn-check-result" class="flex-2 text-sm mt-1"></strong> </label> ``` ## Response HTML Code ```html <div th:fragment="result"> <span th:if="${#strings.isEmpty(equipmentSn)}" data-invalid="true" class="text-gray-400"> Please enter your serial number </span> <span th:if="${!#strings.isEmpty(equipmentSn) and exists}" data-invalid="true" class="text-red-700 font-bold"> ⚠ This serial number has already been registered. </span> <span th:if="${!#strings.isEmpty(equipmentSn) and !exists}" data-invalid="false" class="text-green-600"> ✔ Available serial numbers. </span> </div> ``` ```js document.body.addEventListener("htmx:afterSwap", function (evt) { const targetId = evt.target.id; if (targetId === "sn-check-result") { const dataInvalid = evt.detail.target.querySelector("[data-invalid='true']"); if (dataInvalid) { setTimeout(() => { const inputSn = document.querySelector("#equipmentSn"); console.log("equipmentSn element:", inputSn); console.log("is visible:", inputSn?.offsetParent !== null); console.log("is enabled:", !inputSn?.disabled); if (inputSn && inputSn.offsetParent !== null && !inputSn.disabled) { inputSn.focus(); inputSn.select(); } else { console.log("Focus failed - element not ready"); } }, 100); } } }); ```