Skip to content

Instantly share code, notes, and snippets.

@deanebarker
Last active August 30, 2025 14:50
Show Gist options
  • Select an option

  • Save deanebarker/961aca1835df8aaf5413814f9940963d to your computer and use it in GitHub Desktop.

Select an option

Save deanebarker/961aca1835df8aaf5413814f9940963d to your computer and use it in GitHub Desktop.
Binds some JS to an input field to perform some action when the user pauses typing
<!--
Binds the JS required to do something when the user pauses typing (when the element "triggers," for the purposes of this comment)
<input submitdelay="300" eventname="body:inputEntry" submitfunction="submit" /">
* "submitdelay" is the millisecond delay in typing that will trigger. If not included, defaults to 300 milliseconds.
* "submitevent" is the name of the event that will dispatch from the element when the element triggers.
The event will have two properties:
1. event.target will be the element that triggered it
2. event.value will be the string value of the element
* Prefix the event with "element:" to dispatch from the element itself (this is also the default behavior if no prefix is specified).
* Prefix the event with "window:" to dispatch from the window instead of the element itself.
* Prefix the event with "document:" to dispatch from the document instead of the element itself.
* Prefix the event with "body:" to dispatch from the document body instead of the element itself.
* "submitfunction" is the JS function that will be called when the element triggers
The function needs to be in the global scope (accessible as window[functionName])
The function will get two parameters:
1. Just the string value of the element
2. The entire element object
Either "submitevent" or "submitfunction" must be declared.
BTW: to connect this up to HTMX, you can trigger your HTMX request off the event, like this:
<div
hx-get="/search"
hx-target="#results"
hx-trigger="inputEntry from:body"
hx-include="#idOfTheInput" />
And yes, I know that you can put the hx-get on the input, but in some cases, it's handy to disconnect them and trigger the HTMX element using an event.
-->
<html>
<body>
<input submitdelay="300" submitevent="inputEntry" submitfunction="submit" />
<script>
document.addEventListener("DOMContentLoaded", (e) => {
document
.querySelector("[submitevent],[submitfunction]")
.addEventListener("input", (e) => {
const eventName = e.target.getAttribute("submitevent");
const funcName = e.target.getAttribute("submitfunction");
if (!eventName && !funcName) return; // Note: this check actually shouldn't be required, because it shouldn't even bind without one of those two attributes
const onBody = eventName.startsWith("body:");
if (onBody) eventName = eventName.replace("body:", "");
const onDocument = eventName.startsWith("document:");
if (onDocument) eventName = eventName.replace("document:", "");
const onWindow = eventName.startsWith("window:");
if (onWindow) eventName = eventName.replace("window:", "");
const delay = parseInt(e.target.getAttribute("submitdelay")) || 300;
clearTimeout(e.target._submitTimeout);
e.target._submitTimeout = setTimeout(() => {
// If they specified an event name, dispatch it
if (eventName) {
let event = new Event(eventName);
event.target = e.target;
event.value = e.target.value;
if (onBody) {
document.body.dispatchEvent(event);
} else if (onDocument) {
document.dispatchEvent(event);
} else if (onWindow) {
window.dispatchEvent(event);
} else {
e.target.dispatchEvent(event);
}
}
// If they specified a function name, call it
if (window[funcName] && typeof window[funcName] === "function") {
window[funcName](e.target.value, e.target);
}
}, delay);
});
});
// Test the event dispathing
document.addEventListener("DOMContentLoaded", (e) => {
document.body.addEventListener("inputEntry", (e) => {
console.log("Event dispatched:", e);
});
});
// Test the function calling
function submit(value, element) {
console.log(`Function called with value: "${value}" from element:`, element);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment