Gothic Framework G symbol

HTMX Events & DOM Helpers

Beyond swapping HTML, the HTMX struct lets you listen for events and nudge the DOM — classes, lookups, form values — all from Go.

HTMX.On is scoped to your component and leak-safe: it only hears events inside your subtree, and its listener is released automatically on teardown. HTMX.OnGlobal listens across the whole page. HTMX.Off removes them. Handlers receive an Event.

// HTMX.On listens inside THIS component's subtree and is cleaned up
// automatically when the component tears down — no leaks. The handler
// receives the DOM Event (an alias for JSValue).
CreateWasmFunc("wire", func() {
	HTMX.On(EvtAfterSwap, func(e Event) {
		SetText("log", "a swap happened in my subtree")
	})
})

// HTMX.OnGlobal listens page-wide (document), for events from anywhere.
HTMX.OnGlobal(EvtBeforeRequest, func(e Event) {
	AddClass("spinner", "visible")
})

// HTMX.Off removes every On/OnGlobal handler for that event in this scope.
// (Go funcs aren't comparable, so the handler arg is accepted but ignored.)
HTMX.Off(EvtAfterSwap, nil)

Toggle classes with AddClass, RemoveClass, ToggleClass, and TakeClass (which also strips the class from siblings — ideal for tabs). Remove deletes an element outright.

// Class helpers — target is a CSS selector.
CreateWasmFunc("style", func() {
	HTMX.AddClass("#card", "active")
	HTMX.RemoveClass("#card", "hidden")
	HTMX.ToggleClass("#card", "open")
	// TakeClass gives the class to the target and removes it from its siblings
	// (great for "selected" tabs).
	HTMX.TakeClass("#tab-2", "selected")
})

// HTMX.Remove deletes an element from the DOM.
CreateWasmFunc("dismiss", func() {
	HTMX.Remove("#toast")
})

Look things up with Find (first match), FindAll (all matches), and Closest (nearest ancestor). Values reads what htmx would submit from a form as a map[string]any.

// Find / FindAll / Closest return JSValue(s); Truthy() tells you if it matched.
CreateWasmFunc("inspect", func() {
	el := HTMX.Find("#needle")            // first match, as JSValue
	SetText("found", strconv.FormatBool(el.Truthy()))

	all := HTMX.FindAll(".row")           // []JSValue
	SetText("count", strconv.Itoa(len(all)))

	form := HTMX.Closest("#submit", "form") // nearest ancestor matching selector

	// HTMX.Values reads what htmx would submit from a form -> map[string]any.
	vals := HTMX.Values("#login")
	if u, ok := vals["username"].(string); ok {
		SetText("user", u)
	}
	_ = form
})

Need several WASM components to share state and react to each other? Check out Topics next!