Gothic Framework G symbol

Event Handlers

CreateWasmFunc, CreateWasmStringFunc, and CreateWasmBoolFunc register a Go function under a global name so your HTML can call it from onclick, oninput, or onchange.

Important: You must dot-import pkg/wasm (import . "github.com/felipegenef/gothicframework/v2/pkg/wasm") for use these helpers, otherwise you will get a tinygo compile error.

Note: functions registered in a component's ClientSideState are scoped to that component. Each copy of the component gets its own isolated function and state. To share a function across the whole page, register it in the page-level ClientSideState instead. For shared reactive values between components, use Topics.

Pick the variant that matches the argument you want from the DOM: no argument, a string, or a bool. Here is each one in action:

// HTML event attributes wire to named Go callbacks
 CreateWasmFunc("increment", func() {
    count.Set(count.Get() + 1)
})

 CreateWasmStringFunc("setName", func(val string) {
    name.Set(val)
})

 CreateWasmBoolFunc("setChecked", func(val bool) {
    checked.Set(val)
})

 // Matching HTML usage:
 // <button onclick="increment()">+</button>
 // <input oninput="setName(this.value)" />
 // <input type="checkbox" onchange="setChecked(this.checked)" /> 

When the listener lives entirely in Go and no HTML attribute is involved, use AddEventListener. It attaches a persistent listener to any JSValue element for a given event name.

Important: you cannot pass a Go func() straight into JSValue.Call. Always go through AddEventListener instead.

To attach a listener, use:

// Re-sync after every HTMX swap, no event object needed
 body := Document().Get("body")
 AddEventListener(body, "htmx:afterSwap", func() {
    SetText("status", "swapped")
})

 // React to the native <details> toggle event
 menu := QuerySelector("details#menu")
 AddEventListener(menu, "toggle", func() {
    open.Set(!open.Get())
}) 

When you need the browser Event object, reach for AddEventListenerWithEvent. The callback receives the event as a JSValue, so you can read event.key, call preventDefault(), or inspect event.target.

Here is a global keyboard shortcut and a form submit handler:

// Global keydown listener, close modal on Escape
 AddEventListenerWithEvent(Document(), "keydown", func(e JSValue) {
     if e.Get("key").String() == "Escape" {
        modalOpen.Set(false)
    }
})

 // Form submit, preventDefault then read the value
 form := GetElementById("my-form")
 AddEventListenerWithEvent(form, "submit", func(e JSValue) {
    e.Call("preventDefault")
     val := GetValue("my-input")
    SetText("echo", val)
}) 

Need to call a browser API that has no named helper? Native Browser APIs give you direct access to JSValue and the global scope. Learn it next!