htmgo/htmgo-site/md/docs/4_interactivity/2_events.md
2024-09-25 17:03:12 -05:00

2.7 KiB

Events

Sometimes you need to update elements client side without having to do a network call. For this you generally have to target an element with javascript and set an attribute, change the innerHTML, etc.

To make this work while still keeping a pure go feel, we offer a few utility methods to execute various javascript on an element.

Example: When the form is submitted, set the button text to submitting and disable it, and vise versa after submit is done.

func MyForm() *h.Element {
	return h.Form(
		h.Button(
			h.Text("Submit"),
			h.HxBeforeRequest(
				js.SetDisabled(true),
				js.SetText("Submitting..."),
			),
			h.HxAfterRequest(
				js.SetDisabled(false),
				js.SetText("Submit"),
			),
		),
	)
}

The structure of this comes down to:

  1. Add an event handler to the element
  2. Add commands (found in the js package) as children to that event handler

Event Handlers:

HxBeforeRequest(cmd ...Command) *LifeCycle
HxAfterRequest(cmd ...Command) *LifeCycle
HxOnMutationError(cmd ...Command) *LifeCycle
OnEvent(event hx.Event, cmd ...Command) *LifeCycle
OnClick(cmd ...Command) *LifeCycle
HxOnAfterSwap(cmd ...Command) *LifeCycle
HxOnLoad(cmd ...Command) *LifeCycle

If you use the OnEvent directly, event names may be any HTML DOM events, or any HTMX events.

Commands:

js.AddAttribute(string, value)
js.RemoveAttribute(string)
js.AddClass(string, value)
js.SetText(string)
js.Increment(count)
js.SetInnerHtml(Ren)
js.SetOuterHtml(Ren)
js.SetDisabled(bool)
js.RemoveClass(string)
js.Alert(string)
js.EvalJs(string) // eval arbitrary js, use 'self' to get the current element as a reference
js.InjectScript(string)
js.InjectScriptIfNotExist(string)
js.GetPartial(PartialFunc)
js.GetPartialWithQs(PartialFunc, Qs)
js.PostPartial(PartialFunc)
js.PostPartialWithQs(PartialFunc, Qs)
js.GetWithQs(string, Qs)
js.PostWithQs(string, Qs)
js.ToggleClass(string)
js.ToggleClassOnElement(string, string)

Example: Evaluating arbitrary JS

func MyButton() *h.Element {
	return h.Button(
		h.Text("Submit"),
		h.OnClick(
        // make sure you use 'self' instead of 'this' 
        // for referencing the current element
			h.EvalJs(`
				   if(Math.random() > 0.5) {
				       self.innerHTML = "Success!";
				   }
		       `,
			),
		),
	)
}

tip: If you are using Jetbrains IDE's, you can write // language=js as a comment above the function call (h.EvalJS) and it will automatically give you syntax highlighting on the raw JS.

// language=js
h.EvalJs(`
     if(Math.random() > 0.5) {
         self.innerHTML = "Success!";
     }
     `,
),