htmx

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2024 License: 0BSD Imports: 15 Imported by: 16

Documentation

Overview

package base provides Go functions for building HTMX attributes. These should usually be used through a proxy like templ/hx or gomponents/hx.

See typed-htmx-go.vercel.app for example usage.

Index

Examples

Constants

This section is empty.

Variables

DisabledEltRelative allows you to narrow a CSS selector with the allowed relative modifier `closest`, and pass it to the HX.DisabledElt attribute.

IncludeRelative allows you to narrow a CSS selector with an allowed relative modifier like `next`, and pass it to the [HX.Include()] attribute.

IndicatorRelative allows you to narrow a CSS selector with an allowed relative modifier like `next`, and pass it to the [HX.Indicator()] attribute.

SyncRelative allows you to narrow a CSS selector with an allowed relative modifier like `next`, and pass it to the [HX.Sync()] attribute.

TargetRelative allows you to narrow a CSS selector with an allowed relative modifier like `next`, and pass it to the [HX.Target()] attribute.

Functions

func TemplAttrs added in v0.0.5

func TemplAttrs(attrs ...templ.Attributes) templ.Attributes

TemplAttrs merges the given attributes into a single map. This is helpful for passing many attributes to a templ component.

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var templHx = htmx.NewTempl()

func main() {
	attrs := htmx.TemplAttrs(
		templHx.Post("/example"),
		templHx.ReplaceURL(true),
	)

	fmt.Println(attrs)
}
Output:

map[hx-post:/example hx-replace-url:true]

Types

type Attribute added in v0.0.5

type Attribute string

An Attribute is a valid HTMX attribute name. Used for general type changes like `unset` and `disinherit`.

const (
	Get         Attribute = "hx-get"
	Post        Attribute = "hx-post"
	PushURL     Attribute = "hx-push-url"
	Select      Attribute = "hx-select"
	SelectOOB   Attribute = "hx-select-oob"
	Swap        Attribute = "hx-swap"
	SwapOOB     Attribute = "hx-swap-oob"
	Target      Attribute = "hx-target"
	Trigger     Attribute = "hx-trigger"
	Vals        Attribute = "hx-vals"
	Boost       Attribute = "hx-boost"
	Confirm     Attribute = "hx-confirm"
	Delete      Attribute = "hx-delete"
	Disable     Attribute = "hx-disable"
	DisabledElt Attribute = "hx-disabled-elt"
	Disinherit  Attribute = "hx-disinherit"
	Encoding    Attribute = "hx-encoding"
	Ext         Attribute = "hx-ext"
	Headers     Attribute = "hx-headers"
	History     Attribute = "hx-history"
	HistoryElt  Attribute = "hx-history-elt"
	Include     Attribute = "hx-include"
	Indicator   Attribute = "hx-indicator"
	Params      Attribute = "hx-params"
	Patch       Attribute = "hx-patch"
	Preserve    Attribute = "hx-preserve"
	Prompt      Attribute = "hx-prompt"
	Put         Attribute = "hx-put"
	ReplaceURL  Attribute = "hx-replace-url"
	Request     Attribute = "hx-request"
	Sync        Attribute = "hx-sync"
	Validate    Attribute = "hx-validate"
)

type DisabledEltModifier added in v0.0.5

type DisabledEltModifier string

A DisabledEltModifier is a valid relative modifier for the HX.DisabledElt attribute.

const DisabledEltClosest DisabledEltModifier = "closest" // find the closest ancestor element or itself, that matches the given CSS selector

type DisabledEltSelector added in v0.0.5

type DisabledEltSelector string

A DisabledEltSelector is a CSS selector, or a non-standard selector for the [HX.DisabledElt()] attribute.

const DisabledEltThis DisabledEltSelector = "this" // indicates that this element should disable itself during the request.

type EncodingContentType added in v0.0.5

type EncodingContentType string

An EncodingContentType is a valid encoding override for an [HX.Encoding()].

const EncodingMultipart EncodingContentType = "multipart/form-data"

An EncodingMultipart supports file uploads in an ajax request with [HX.Encoding()].

type ExtAttribute added in v0.1.2

type ExtAttribute struct {
	Attribute string
	Value     any
}

type Extension added in v0.1.2

type Extension string

An Extension is the name of an htmx extension, to be passed to [HX.Ext()] to initialize the extension. Extensions are in packages under htmx/ext.

type GomponentsAttrs added in v0.0.5

type GomponentsAttrs struct {
	// contains filtered or unexported fields
}

func (GomponentsAttrs) Render added in v0.0.5

func (a GomponentsAttrs) Render(w io.Writer) error

func (GomponentsAttrs) String added in v0.0.5

func (n GomponentsAttrs) String() string

String satisfies fmt.Stringer.

func (GomponentsAttrs) Type added in v0.0.5

func (n GomponentsAttrs) Type() g.NodeType

Type satisfies nodeTypeDescriber.

type HX

type HX[T any] struct {
	// contains filtered or unexported fields
}

An HX constructs HTMX attributes.

func NewGomponents added in v0.0.5

func NewGomponents() HX[GomponentsAttrs]
Example
hx := htmx.NewGomponents()

component := FormEl(
	hx.Boost(true),
	hx.Post("/submit"),
	hx.Swap(swap.OuterHTML),
	ID("form"),
	Input(
		Name("firstName"),
	),
	Button(
		Type("submit"),
		g.Text("Submit"),
	),
)

_ = component.Render(os.Stdout)
Output:

<form hx-boost="true" hx-post="/submit" hx-swap="outerHTML" id="form"><input name="firstName"><button type="submit">Submit</button></form>

func NewHX added in v0.0.5

func NewHX[T any](attr NewAttr[T]) HX[T]

func NewStringAttrs added in v0.1.1

func NewStringAttrs() HX[string]

NewStringAttrs returns a HX instance that returns stringified attributes for direct use in HTML.

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

func main() {
	hx := htmx.NewStringAttrs()

	fmt.Println(hx.Target(htmx.TargetNext))
	fmt.Println(hx.Preserve())

}
Output:

hx-target='next'
hx-preserve

func NewTempl added in v0.0.5

func NewTempl() HX[templ.Attributes]

NewTempl returns a HX instance for use with Templ. Each attribute returns a templ.Attributes map, which can be spread into a templ element.

func (*HX[T]) Attr added in v0.1.2

func (hx *HX[T]) Attr(attribute Attribute, value any) T

func (*HX[T]) Boost added in v0.0.5

func (hx *HX[T]) Boost(boost bool) T

Boost allows you to “boost” normal anchors and form tags to use AJAX instead. This has the nice fallback that, if the user does not have javascript enabled, the site will continue to work.

For anchor tags, clicking on the anchor will issue a GET request to the url specified in the href and will push the url so that a history entry is created. The target is the <body> tag, and the innerHTML swap strategy is used by default. All of these can be modified by using the appropriate attributes, except the click trigger.

For forms the request will be converted into a GET or POST, based on the method in the method attribute and will be triggered by a submit. Again, the target will be the body of the page, and the innerHTML swap will be used. The url will not be pushed, however, and no history entry will be created. (You can use the [HX.PushUrl] attribute if you want the url to be pushed.)

<div { hx.Boost(true)... } >
	<a href="/page1">Go To Page 1</a>
	<a href="/page2">Go To Page 2</a>
</div>

These links will issue an ajax GET request to the respective URLs and replace the body’s inner content with it.

Here is an example of a boosted form:

<form { hx.Boost(true)... } action="/example" method="post">
	<input name="email" type="email" placeholder="Enter email...">
	<button>Submit</button>
</form>

This form will issue an ajax POST to the given URL and replace the body’s inner content with it.

Notes

  • hx-boost is inherited and can be placed on a parent element
  • Only links that are to the same domain and that are not local anchors will be boosted
  • All requests are done via AJAX, so keep that in mind when doing things like redirects
  • To find out if the request results from a boosted anchor or form, look for HX-Boosted in the request header
  • Selectively disable boost on child elements with hx-boost="false"
  • Disable the replacement of elements via boost, and their children, with hx-preserve="true"

HTMX Attribute: hx-boost

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Boost(true))
}
Output:

hx-boost='true'

func (*HX[T]) Config added in v0.0.7

func (hx *HX[T]) Config(config *hxconfig.Builder) T

Config sets the htmx configuration options on a meta element.

<meta
	name="htmx-config"
	hx.Config(
		hxconfig.New().DefaultSwapStyle(swap.OuterHTML),
	)
/>

HTMX Docs

Example

ExampleHX_Config shows the default values, which can be omitted in normal use.

config := hx.Config(hxconfig.New().
	HistoryEnabled(true).
	HistoryCacheSize(10).
	RefreshOnHistoryMiss(false).
	DefaultSwapStyle(swap.InnerHTML).
	DefaultSwapDelay(0).
	DefaultSettleDelay(20 * time.Millisecond).
	IncludeIndicatorStyles(true).
	IndicatorClass("htmx-indicator").
	RequestClass("htmx-request").
	AddedClass("htmx-added").
	SettlingClass("htmx-settling").
	SwappingClass("htmx-swapping").
	AllowEval(true).
	AllowScriptTags(true).
	InlineScriptNonce("nonce").
	AttributesToSettle([]string{"foo"}).
	UseTemplateFragments(false).
	WSReconnectDelay("full-jitter").
	WSBinaryType("blob").
	DisableSelector("[hx-disable], [data-hx-disable]").
	WithCredentials(false).
	Timeout(time.Second). // Default is 0, this is an example
	ScrollBehavior(hxconfig.ScrollBehaviorSmooth).
	DefaultFocusScroll(false).
	GetCacheBusterParam(false).
	GlobalViewTransitions(false).
	MethodsThatUseUrlParams([]hxconfig.HTTPMethod{hxconfig.MethodGet}).
	SelfRequestsOnly(false).
	IgnoreTitle(false).
	ScrollIntoViewOnBoost(true).
	TriggerSpecsCache("cacheObject"), // Default is nil, this is an example
)

fmt.Println(config)
Output:

content='{"addedClass":"htmx-added","allowEval":true,"allowScriptTags":true,"attributesToSettle":["foo"],"defaultFocusScroll":false,"defaultSettleDelay":20,"defaultSwapDelay":0,"defaultSwapStyle":"innerHTML","disableSelector":"[hx-disable], [data-hx-disable]","getCacheBusterParam":false,"globalViewTransitions":false,"historyCacheSize":10,"historyEnabled":true,"ignoreTitle":false,"includeIndicatorStyles":true,"indicatorClass":"htmx-indicator","inlineScriptNonce":"nonce","methodsThatUseUrlParams":["get"],"refreshOnHistoryMiss":false,"requestClass":"htmx-request","scrollBehavior":"smooth","scrollIntoViewOnBoost":true,"selfRequestsOnly":false,"settlingClass":"htmx-settling","swappingClass":"htmx-swapping","timeout":1000,"triggerSpecsCache":"cacheObject","useTemplateFragments":false,"withCredentials":false,"wsBinaryType":"blob","wsReconnectDelay":"full-jitter"}'

func (*HX[T]) Confirm added in v0.0.5

func (hx *HX[T]) Confirm(msg string) T

Confirm allows you to confirm an action before issuing a request. This can be useful in cases where the action is destructive and you want to ensure that the user really wants to do it.

Here is an example:

<button { hx.Delete("/account")... } {hx.Confirm("Are you sure you wish to delete you account?")... }>
  Delete My Account
</button>

Event details

The event triggered by hx-confirm contains additional properties in its detail:

  • triggeringEvent: the event that triggered the original request
  • issueRequest(skipConfirmation=false): a callback which can be used to confirm the AJAX request
  • question: the value of the hx-confirm attribute on the HTML element

Notes

  • hx-confirm is inherited and can be placed on a parent element
  • hx-confirm uses the browser’s window.confirm by default. You can customize this behavior as shown in this example.
  • a boolean skipConfirmation can be passed to the issueRequest callback; if true (defaults to false), the window.confirm will not be called and the AJAX request is issued directly

HTMX Attribute: hx-confirm

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Confirm("Are you sure?"))
}
Output:

hx-confirm='Are you sure?'

func (*HX[T]) Delete added in v0.0.5

func (hx *HX[T]) Delete(url string, a ...any) T

Delete will cause an element to issue a DELETE to the specified URL and swap the HTML into the DOM using a swap strategy:

<button { hx.Delete("/account")... } { hx.Target("body")... } >
	Delete Your Account
</button>

This example will cause the button to issue a DELETE to /account and swap the returned HTML into the innerHTML of the body.

Notes

  • hx-delete is not inherited
  • You can control the target of the swap using the HX.Target attribute
  • You can control the swap strategy by using the HX.Swap attribute
  • You can control what event triggers the request with the HX.Trigger attribute
  • You can control the data submitted with the request in various ways, documented here: Parameters
  • To remove the element following a successful DELETE, return a 200 status code with an empty body; if the server responds with a 204, no swap takes place, documented here: Requests & Responses

HTMX Attribute: hx-delete

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Delete("/example"))
}
Output:

hx-delete='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Delete("/example/%d", 1))
}
Output:

hx-delete='/example/1'

func (*HX[T]) Disable added in v0.0.5

func (hx *HX[T]) Disable() T

Disable will disable htmx processing for a given element and all its children. This can be useful as a backup for HTML escaping, when you include user generated content in your site, and you want to prevent malicious scripting attacks.

The value of the tag is ignored, and it cannot be reversed by any content beneath it.

HTMX Attribute: hx-disable

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Disable())
}
Output:

hx-disable

func (*HX[T]) DisabledElt added in v0.0.5

func (hx *HX[T]) DisabledElt(extendedSelector DisabledEltSelector) T

DisabledElt allows you to specify elements that will have the disabled attribute added to them for the duration of the request.

The value of this attribute is a CSS query selector of the element or elements to apply the class to, or the keyword closest, followed by a CSS selector, which will find the closest ancestor element or itself, that matches the given CSS selector (e.g. closest tr), or the keyword this

Here is an example with a button that will disable itself during a request:

<button { hx.Post("/example")... } { hx.DisabledElt(hx.This)... } >
	Post It!
</button>

When a request is in flight, this will cause the button to be marked with the disabled attribute, which will prevent further clicks from occurring.

HTMX Attribute: hx-disabled-elt

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.DisabledElt("#example"))
}
Output:

hx-disabled-elt='#example'
Example (Relative)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.DisabledElt(
		htmx.DisabledEltRelative(htmx.DisabledEltClosest, "#example"),
	))
}
Output:

hx-disabled-elt='closest #example'
Example (This)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.DisabledElt(htmx.DisabledEltThis))
}
Output:

hx-disabled-elt='this'

func (*HX[T]) Disinherit added in v0.0.5

func (hx *HX[T]) Disinherit(attr ...Attribute) T

Disinherit allows you to disable automatic attribute inheritance for one or multiple specified attributes.

The default behavior for htmx is to “inherit” many attributes automatically: that is, an attribute such as hx-target may be placed on a parent element, and all child elements will inherit that target.

An example scenario is to allow you to place an hx-boost on the body element of a page, but overriding that behavior in a specific part of the page to allow for more specific behaviors.

<div
	{ hx.Boost(true).. }
	{ hx.Select("#content").. }
	{ hx.Target("#content").. }
	{ hx.Disinherit(hx.Target)... }
>
	<!-- hx-select is automatically set to parent value; hx-target is not inherited -->
  <button { hx.Get("/test")... }></button>
</div>

<div { hx.Select("#content")... } >
	<div
		{ hx.Boost(true)... }
		{ hx.Target("#content")... }
		{ hx.Disinherit(hx.Select)... }
	>
  	<!-- hx-target is automatically inherited from parent value -->
    <!-- hx-select is not inherited, because the direct parent does
    disables inheritance, despite not specifying hx-select itself -->
    <button { hx.Get("/test")... }></button>
  </div>
</div>

Notes

HTMX Attribute: hx-disinherit

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Disinherit(htmx.Get, htmx.Boost))
}
Output:

hx-disinherit='hx-get hx-boost'

func (*HX[T]) DisinheritAll added in v0.0.5

func (hx *HX[T]) DisinheritAll() T

DisinheritAll allows you to disable automatic attribute inheritance for all attributes.

The default behavior for htmx is to “inherit” many attributes automatically: that is, an attribute such as hx-target may be placed on a parent element, and all child elements will inherit that target.

An example scenario is to allow you to place an hx-boost on the body element of a page, but overriding that behavior in a specific part of the page to allow for more specific behaviors.

<div
	{ hx.Boost(true)... }
	{ hx.Select("#content")... }
	{ hx.Target("#content")... }
	{ hx.DisinheritAll()... }
>
	<a href="/page1">Go To Page 1</a> <!-- boosted with the attribute settings above -->
	<a href="/page2" { hx.Unset(hx.Boost)... } >Go To Page 1</a> <!-- not boosted -->
	<button { hx.Get("/test")... } { hx.TargetNonStandard(hx.TargetThis)... }></button> <!-- hx-select is not inherited -->
</div>

Notes

HTMX Attribute: hx-disinherit

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.DisinheritAll())
}
Output:

hx-disinherit='*'

func (*HX[T]) Encoding added in v0.0.5

func (hx *HX[T]) Encoding(encoding EncodingContentType) T

Encoding allows you to switch the request encoding from the usual application/x-www-form-urlencoded encoding to multipart/form-data, usually to support file uploads in an ajax request.

The value of this attribute should be "multipart/form-data".

The hx-encoding tag may be placed on parent elements.

Notes

  • hx-encoding is inherited and can be placed on a parent element

HTMX Attribute: hx-encoding

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Encoding(htmx.EncodingMultipart))
}
Output:

hx-encoding='multipart/form-data'

func (*HX[T]) Ext added in v0.0.5

func (hx *HX[T]) Ext(ext ...Extension) T

Ext enables an htmx extension for an element and all its children.

The value can be one or more extension names to apply.

The hx-ext tag may be placed on parent elements if you want a plugin to apply to an entire swath of the DOM, and on the body tag for it to apply to all htmx requests.

Notes

  • hx-ext is both inherited and merged with parent elements, so you can specify extensions on any element in the DOM hierarchy and it will apply to all child elements.

HTMX Attribute: hx-ext

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Ext("example-extension"))
}
Output:

hx-ext='example-extension'

func (*HX[T]) ExtIgnore added in v0.0.5

func (hx *HX[T]) ExtIgnore(ext string) T

ExtIgnore ignores an extension that is defined by a parent node.

<div { hx.Ext("example")... }>
  "Example" extension is used in this part of the tree...
  <div { hx.ExtIgnore("example")... }>
    ... but it will not be used in this part.
  </div>
</div>

HTMX Attribute: hx-ext

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ExtIgnore("example-extension"))
}
Output:

hx-ext='ignore:example-extension'

func (*HX[T]) Get added in v0.0.5

func (hx *HX[T]) Get(url string, a ...any) T

Get will cause an element to issue a GET to the specified URL and swap the HTML into the DOM using a swap strategy.

<div { hx.Get("/example")... }>Get Some HTML</div>

This example will cause the div to issue a GET to /example and swap the returned HTML into the innerHTML of the div.

Notes:

  • hx-get is not inherited
  • By default hx-get does not include any parameters. You can use the hx-params attribute to change this
  • You can control the target of the swap using the hx-target attribute
  • You can control the swap strategy by using the hx-swap attribute
  • You can control what event triggers the request with the hx-trigger attribute
  • You can control the data submitted with the request in various ways, documented here: Parameters

HTMX Attribute: hx-get

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Get("/example"))
}
Output:

hx-get='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Get("/example/%d", 1))
}
Output:

hx-get='/example/1'

func (*HX[T]) Headers added in v0.0.5

func (hx *HX[T]) Headers(headers any) T

Headers allows you to add to the headers that will be submitted with an AJAX request.

The value of this attribute is a list of name-expression values in JSON (JavaScript Object Notation) format.

For values computed at runtime, see [HX.HeadersJS()].

Notes

  • hx-headers is inherited and can be placed on a parent element.
  • A child declaration of a header overrides a parent declaration.

HTMX Attribute: hx-headers

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Headers(map[string]string{"Content-Type": "application/json"}))
}
Output:

hx-headers='{"Content-Type":"application/json"}'
Example (Error)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Headers(func() {}))
}
Output:

hx-headers='{}'

func (*HX[T]) HeadersJS added in v0.0.5

func (hx *HX[T]) HeadersJS(headers map[string]string) T

HeadersJS allows you to add to the headers that will be submitted with an AJAX request, with values evaluated as JavaScript expressions at runtime.

Security Considerations

Be aware that you are introducing security considerations, especially when dealing with user input such as query strings or user-generated content, which could introduce a Cross-Site Scripting (XSS) vulnerability.

For values static JSON, see [HX.Headers()].

Notes

  • hx-headers is inherited and can be placed on a parent element.
  • A child declaration of a header overrides a parent declaration.

HTMX Attribute: hx-headers

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.HeadersJS(map[string]string{"Content-Type": "getContentType()"}))
}
Output:

hx-headers='js:{"Content-Type":getContentType()}'

func (*HX[T]) History added in v0.0.5

func (hx *HX[T]) History(on bool) T

History when set to false on any element in the current document, or any html fragment loaded into the current document by htmx, will prevent sensitive data being saved to the localStorage cache when htmx takes a snapshot of the page state.

History navigation will work as expected, but on restoration the URL will be requested from the server instead of the history cache.

Here is an example:

<html>
<body>
<div { hx.History(false)... }>
 ...
</div>
</body>
</html>

Notes

  • hx-history="false" can be present anywhere in the document to embargo the current page state from the history cache (i.e. even outside the element specified for the history snapshot hx-history-elt).

HTMX Attribute: hx-history

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.History(true))
}
Output:

hx-history='true'
Example (Off)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.History(false))
}
Output:

hx-history='false'

func (*HX[T]) HistoryElt added in v0.0.5

func (hx *HX[T]) HistoryElt() T

HistoryElt allows you to specify the element that will be used to snapshot and restore page state during navigation. By default, the body tag is used. This is typically good enough for most setups, but you may want to narrow it down to a child element. Just make sure that the element is always visible in your application, or htmx will not be able to restore history navigation properly.

Here is an example:

<html>
<body>
<div id="content" { hx.HistoryElt()... }>
 ...
</div>
</body>
</html>

Notes

- hx-history-elt is not inherited - In most cases we don’t recommend narrowing the history snapshot

HTMX Attribute: hx-history-elt

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.HistoryElt())
}
Output:

hx-history-elt

func (*HX[T]) Include added in v0.0.5

func (hx *HX[T]) Include(extendedSelector IncludeSelector) T

Include allows you to include additional element values in an AJAX request.

HTMX Attribute: hx-include

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Include("#example"))
}
Output:

hx-include='#example'
Example (Relative)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Include(
		htmx.IncludeRelative(htmx.Closest, "#example"),
	))
}
Output:

hx-include='closest #example'
Example (This)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Include(htmx.IncludeThis))
}
Output:

hx-include='this'

func (*HX[T]) Indicator added in v0.0.5

func (hx *HX[T]) Indicator(extendedSelector IndicatorSelector) T

The hx-indicator attribute allows you to specify the element that will have the htmx-request class added to it for the duration of the request. This can be used to show spinners or progress indicators while the request is in flight.

The value of this attribute is a CSS query selector of the element or elements to apply the class to, or the keyword `closest` followed by a CSS selector, which will find the closest ancestor element or itself, that matches the given CSS selector (e.g. closest tr);

HTMX Attribute: hx-indicator

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Indicator("#example"))
}
Output:

hx-indicator='#example'
Example (Relative)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Indicator(
		htmx.IndicatorRelative(htmx.IndicatorClosest, "#example"),
	))
}
Output:

hx-indicator='closest #example'

func (*HX[T]) On added in v0.0.5

func (hx *HX[T]) On(event on.Event, action string) T

On allows you to embed scripts inline to respond to events directly on an element; similar to the onevent properties found in HTML, such as onClick.

The hx-on* attributes improve upon onevent by enabling the handling of any arbitrary JavaScript event, for enhanced Locality of Behaviour (LoB) even when dealing with non-standard DOM events. For example, pass an on.Event to use HTMX events.

<div { hx.On("click", "alert('Clicked!')")... }>Click</div>

Note that, in addition to the standard DOM events, all htmx and other custom events can be captured, too!

<button
	{ hx.Get("/info")... }
	{ hx.On(on.BeforeRequest, "alert('Making a request!')")... }>
	Get Info!
</button>

If you wish to handle multiple different events, you can simply add multiple attributes to an element.

<button
	{ hx.Get("/info")... }
	{ hx.On(on.BeforeRequest, "alert('Making a request!')")... }
	{ hx.On(on.AfterRequest, "alert('Done making a request!')")... } >
	Get Info!
</button>

Symbols

Like onevent, two symbols are made available to event handler scripts:

  • this - The element on which the hx-on attribute is defined
  • event - The event that triggered the handler

Notes

  • hx-on is not inherited, however due to event bubbling, hx-on attributes on parent elements will typically be triggered by events on child elements.

HTMX Attribute: hx-on

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.On("click", `alert("clicked")`))
}
Output:

hx-on:click='alert("clicked")'
Example (HtmxEvent)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/on"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.On(on.BeforeRequest, `alert("before")`))
}
Output:

hx-on:htmx:before-request='alert("before")'

func (*HX[T]) Params added in v0.0.5

func (hx *HX[T]) Params(paramNames ...string) T

Params allows you to filter the parameters that will be submitted with an AJAX request.

Notes

  • hx-params is inherited and can be placed on a parent element

HTMX Attribute: hx-params

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Params("one", "two"))
}
Output:

hx-params='one,two'

func (*HX[T]) ParamsAll added in v0.0.5

func (hx *HX[T]) ParamsAll() T

ParamsAll allows you to include all parameters with an AJAX request (default).

<div { hx.Get("/example")... } { hx.ParamsAll()... }>Get Some HTML, Including Params</div>

This div will include all the parameters that a POST would, but they will be URL encoded and included in the URL, as per usual with a GET.

Notes

  • hx-params is inherited and can be placed on a parent element

HTMX Attribute: hx-params

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ParamsAll())
}
Output:

hx-params='*'

func (*HX[T]) ParamsNone added in v0.0.5

func (hx *HX[T]) ParamsNone() T

ParamsNone allows you to include no parameters with an AJAX request.

Notes

  • hx-params is inherited and can be placed on a parent element

HTMX Attribute: hx-params

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ParamsNone())
}
Output:

hx-params='none'

func (*HX[T]) ParamsNot added in v0.0.5

func (hx *HX[T]) ParamsNot(paramNames ...string) T

ParamsNot allows you to include all params except the comma separated list of parameter when submitting an AJAX request.

Notes

  • hx-params is inherited and can be placed on a parent element

HTMX Attribute: hx-params

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ParamsNot("one", "two"))
}
Output:

hx-params='not one,two'

func (*HX[T]) Patch added in v0.0.5

func (hx *HX[T]) Patch(url string, a ...any) T

Patch will cause an element to issue a PATCH to the specified URL and swap the HTML into the DOM using a swap strategy.

<button { hx.Patch("/account")... } { hx.Target("body")...} >
  Patch Your Account
</button>

This example will cause the button to issue a PATCH to /account and swap the returned HTML into the innerHTML of the body.

Notes

  • hx-patch is not inherited
  • You can control the target of the swap using the [HX.Target()] attribute
  • You can control the swap strategy by using the [HX.Swap()] attribute
  • You can control what event triggers the request with the [HX.Trigger()] attribute
  • You can control the data submitted with the request in various ways, documented here: Parameters

HTMX Attribute: hx-patch

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Patch("/example"))
}
Output:

hx-patch='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Patch("/example/%d", 1))
}
Output:

hx-patch='/example/1'

func (*HX[T]) Post added in v0.0.5

func (hx *HX[T]) Post(url string, a ...any) T

Post will cause an element to issue a POST to the specified URL and swap the HTML into the DOM using a swap strategy.

<button { hx.Post("/accounts/enable")... } { hx.Target("body")... }>
  Enable Your Account
</button>

This example will cause the button to issue a POST to /account/enable and swap the returned HTML into the innerHTML of the body.

Notes

  • hx-post is not inherited
  • You can control the target of the swap using the hx-target attribute
  • You can control the swap strategy by using the hx-swap attribute
  • You can control what event triggers the request with the hx-trigger attribute
  • You can control the data submitted with the request in various ways, documented here: Parameters

HTMX Attribute: hx-post

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Post("/example"))
}
Output:

hx-post='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Post("/example/%d", 1))
}
Output:

hx-post='/example/1'

func (*HX[T]) Preserve added in v0.0.5

func (hx *HX[T]) Preserve() T

Preserve allows you to keep an element unchanged during HTML replacement. Elements with hx-preserve set are preserved by id when htmx updates any ancestor element. You must set an unchanging id on elements for hx-preserve to work. The response requires an element with the same id, but its type and other attributes are ignored.

Note that some elements cannot unfortunately be preserved properly, such as <input type="text"> (focus and caret position are lost), iframes or certain types of videos. To tackle some of these cases we recommend the morphdom extension, which does a more elaborate DOM reconciliation.

Notes

  • hx-preserve is not inherited

HTMX Attribute: hx-preserve

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Preserve())
}
Output:

hx-preserve

func (*HX[T]) Prompt added in v0.0.5

func (hx *HX[T]) Prompt(msg string) T

Prompt allows you to show a prompt before issuing a request. The value of the prompt will be included in the request in the HX-Prompt header. Here is an example:

<button { hx.Delete("/account")... } { hx.Prompt("Enter your account name to confirm deletion")... }>
  Delete My Account
</button>

Notes

  • hx-prompt is inherited and can be placed on a parent element

HTMX Attribute: hx-prompt

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Prompt("Enter a value"))
}
Output:

hx-prompt='Enter a value'

func (*HX[T]) PushURL added in v0.0.5

func (hx *HX[T]) PushURL(on bool) T

PushURL allows you to push a URL into the browser location history. This creates a new history entry, allowing navigation with the browser’s back and forward buttons. htmx snapshots the current DOM and saves it into its history cache, and restores from this cache on navigation.

The possible values of this attribute are:

  • true, which pushes the fetched URL into history.
  • false, which disables pushing the fetched URL if it would otherwise be pushed due to inheritance or hx-boost.

To push a specific URL into history, use [attributes.PushURLPath].

Example

<div { hx.Get("/account")... } { hx.PushURL(true)... }>
	Go to My Account
</div>

Notes

  • hx-push-url is inherited and can be placed on a parent element
  • The HX-Push-Url response header has similar behavior and can override this attribute.
  • The hx-history-elt attribute allows changing which element is saved in the history cache.

HTMX Attribute: hx-push-url

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.PushURL(true))
}
Output:

hx-push-url='true'

func (*HX[T]) PushURLPath added in v0.0.5

func (hx *HX[T]) PushURLPath(url string, a ...any) T

PushURLPath allows you to push a URL into the browser location history. This creates a new history entry, allowing navigation with the browser’s back and forward buttons. htmx snapshots the current DOM and saves it into its history cache, and restores from this cache on navigation.

This method takes a URL to be pushed into the location bar. This may be relative or absolute, as per history.pushState().

To simply toggle pushing the URL associated with a link, use [attributes.PushURL].

Example

<div { hx.Get("/account")...} { hx.PushURLPath("/account/home")... }>
	Go to My Account
</div>

Notes

  • hx-push-url is inherited and can be placed on a parent element
  • The HX-Push-Url response header has similar behavior and can override this attribute.
  • The hx-history-elt attribute allows changing which element is saved in the history cache.

HTMX Attribute: hx-push-url

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.PushURLPath("/example"))
}
Output:

hx-push-url='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.PushURLPath("/example/%d", 1))
}
Output:

hx-push-url='/example/1'

func (*HX[T]) Put added in v0.0.5

func (hx *HX[T]) Put(url string, a ...any) T

Put will cause an element to issue a PUT to the specified URL and swap the HTML into the DOM using a swap strategy.

<button { hx.Patch("/account")... } { hx.Target("body")...} >
	Put Money In Your Account
</button>

This example will cause the button to issue a PUT to /account and swap the returned HTML into the innerHTML of the body.

Notes

  • hx-put is not inherited
  • You can control the target of the swap using the [HX.Target()] attribute
  • You can control the swap strategy by using the [HX.Swap()] attribute
  • You can control what event triggers the request with the [HX.Trigger()] attribute
  • You can control the data submitted with the request in various ways, documented here: Parameters

HTMX Attribute: hx-put

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Put("/example"))
}
Output:

hx-put='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Put("/example/%d", 1))
}
Output:

hx-put='/example/1'

func (*HX[T]) ReplaceURL added in v0.0.5

func (hx *HX[T]) ReplaceURL(on bool) T

ReplaceURL allows you to replace the current url of the browser location history.

The possible values of this attribute are:

  • true, which replaces the fetched URL in the browser navigation bar.
  • false, which disables replacing the fetched URL if it would otherwise be replaced due to inheritance.

Here is an example:

<div { hx.Get("/account")... } { hx.ReplaceURL(true)... } >
	Go to My Account
</div>

This will cause htmx to snapshot the current DOM to localStorage and replace the URL `/account’ in the browser location bar.

Notes

  • hx-replace-url is inherited and can be placed on a parent element
  • The HX-Replace-Url response header has similar behavior and can override this attribute.
  • The hx-history-elt attribute allows changing which element is saved in the history cache.
  • The hx-push-url attribute is a similar and more commonly used attribute, which creates a new history entry rather than replacing the current one.

HTMX Attribute: hx-replace

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ReplaceURL(true))
}
Output:

hx-replace-url='true'

func (*HX[T]) ReplaceURLWith added in v0.0.5

func (hx *HX[T]) ReplaceURLWith(url string, a ...any) T

ReplaceURLWith allows you to replace the current url of the browser location history with a URL to be replaced into the location bar. This may be relative or absolute, as per history.replaceState().

<div { hx.Get("/account")... } { hx.ReplaceURLWith("/account/home")... } >
	Go to My Account
</div>

This will replace the URL `/account/home’ in the browser location bar.

Notes

  • hx-replace-url is inherited and can be placed on a parent element
  • The HX-Replace-Url response header has similar behavior and can override this attribute.
  • The hx-history-elt attribute allows changing which element is saved in the history cache.
  • The hx-push-url attribute is a similar and more commonly used attribute, which creates a new history entry rather than replacing the current one.

HTMX Attribute: hx-replace

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ReplaceURLWith("/example"))
}
Output:

hx-replace-url='/example'
Example (Format)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ReplaceURLWith("/example/%d", 1))
}
Output:

hx-replace-url='/example/1'

func (*HX[T]) Request added in v0.0.5

func (hx *HX[T]) Request(request RequestConfig) T

Request allows you to configure various aspects of the request via attributes. See RequestConfig for the available options.

These attributes are set using a JSON-like syntax:

<div
	{ hx.Request(htmx.RequestConfig{
		Timeout:     time.Second,
		Credentials: true,
		NoHeaders:   true,
	})... }
>...</div>

HTMX Attribute: hx-request

Example
package main

import (
	"fmt"
	"time"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Request(htmx.RequestConfig{
		Timeout:     time.Second,
		Credentials: true,
		NoHeaders:   true,
	}))
}
Output:

hx-request='"timeout":1000,"credentials":true,"noHeaders":true'

func (*HX[T]) RequestJS added in v0.0.5

func (hx *HX[T]) RequestJS(request RequestConfigJS) T

RequestJS allows you to configure various aspects of the request, with each value being a valid JavaScript expression. See RequestConfigJS for the available options.

<div
	{ hx.RequestJS(htmx.RequestConfigJS{
		Timeout:     "getTimeoutSetting()",
		Credentials: "true",
		NoHeaders:   "noHeaders()",
	})... }
>...</div>

HTMX Attribute: hx-request

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.RequestJS(htmx.RequestConfigJS{
		Timeout:     "getTimeoutSetting()",
		Credentials: "true",
		NoHeaders:   "noHeaders()",
	}))
}
Output:

hx-request='js: timeout:getTimeoutSetting(),credentials:true,noHeaders:noHeaders()'

func (*HX[T]) Select added in v0.0.5

func (hx *HX[T]) Select(selector StandardCSSSelector) T

Select allows you to select the content you want swapped from a response. The value of this attribute is a CSS query selector of the element or elements to select from the response.

Here is an example that selects a subset of the response content:

<div>
	<button
		{ hx.Get("/info")... }
		{ hx.Select("#info-details")... }
		{ hx.Swap(swap.OuterHTML)... }
	>
		Get Info!
	</button>
</div>

So this button will issue a GET to /info and then select the element with the id info-detail, which will replace the entire button in the DOM.

Notes

hx-select is inherited and can be placed on a parent element

HTMX Attribute: hx-select

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Select("#example"))
}
Output:

hx-select='#example'

func (*HX[T]) SelectOOB added in v0.0.5

func (hx *HX[T]) SelectOOB(selectors ...StandardCSSSelector) T

SelectOOB allows you to select content from a response to be swapped in via an out-of-band swap. The value of this attribute is comma separated list of elements to be swapped out of band. This attribute is almost always paired with hx-select.

Here is an example that selects a subset of the response content:

<div>
	<div id="alert"></div>
  	<button
			{ hx.Get("/info")... }
			{ hx.Select("#info-details")... }
			{ hx.Swap(swap.OuterHTML)... }
			{ hx.SelectOOB("#alert")... }
		>
    	Get Info!
    </button>
</div>

This button will issue a GET to /info and then select the element with the id info-details, which will replace the entire button in the DOM, and, in addition, pick out an element with the id alert in the response and swap it in for div in the DOM with the same ID.

Each value in the comma separated list of values can specify any valid hx-swap strategy by separating the selector and the swap strategy with a :.

For example, to prepend the alert content instead of replacing it:

<div>
<div id="alert"></div>
   <button
			{ hx.Get("/info")... }
			{ hx.Select("#info-details")... }
			{ hx.Swap(swap.OuterHTML)... }
			{ hx.SelectOOB("#alert:afterbegin")... }
		>
        Get Info!
    </button>
</div>

Notes

hx-select-oob is inherited and can be placed on a parent element

HTMX Attribute: hx-select-oob

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SelectOOB("#info-details", "#other-details"))
}
Output:

hx-select-oob='#info-details,#other-details'

func (*HX[T]) SelectOOBWithStrategy added in v0.0.5

func (hx *HX[T]) SelectOOBWithStrategy(selectors ...SelectOOBStrategy) T

SelectOOBWithStrategy allows you to select content from a response to be swapped in via an out-of-band swap, with an optional strategy for each selector.

The value of this attribute is comma separated list of elements to be swapped out of band. This attribute is almost always paired with hx-select.

Each value in the comma separated list of values can specify any valid hx-swap strategy by separating the selector and the swap strategy with a :.

For example, to prepend the alert content instead of replacing it:

<div>
   <div id="alert"></div>
    <button
			{ hx.Get("/info")... }
				{ hx.Select("#info-details")... }
				{ hx.Swap(swap.OuterHTML)... }
				{ hx.SelectOOBWithStrategy(
					htmx.SelectOOBStrategy{Selector:"#alert", Strategy: swap.AfterBegin},
				)... }
		>
        Get Info!
    </button>
</div>

Notes

hx-select-oob is inherited and can be placed on a parent element

HTMX Attribute: hx-select-oob

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/swap"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SelectOOBWithStrategy(
		htmx.SelectOOBStrategy{Selector: "#info-details", Strategy: swap.AfterBegin},
		htmx.SelectOOBStrategy{Selector: "#other-details", Strategy: ""},
	))
}
Output:

hx-select-oob='#info-details:afterbegin,#other-details'

func (*HX[T]) Swap added in v0.0.5

func (hx *HX[T]) Swap(strategy swap.Strategy) T

Swap allows you to specify how the response will be swapped in relative to the target of an AJAX request.

So in this code:

<div { hx.Get("/example")... } { hx.Swap(swap.AfterEnd)... } >
	Get Some HTML & Append It
</div>

The div will issue a request to /example and append the returned content after the div.

For advanced usage with modifiers, see [HX.SwapExtended()].

HTMX Attribute: hx-swap

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/swap"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Swap(swap.OuterHTML))
}
Output:

hx-swap='outerHTML'

func (*HX[T]) SwapExtended added in v0.0.5

func (hx *HX[T]) SwapExtended(swap *swap.Builder) T

SwapExtended allows you to specify how the response will be swapped in relative to the target of an AJAX request, with modifiers for changing the behavior of the swap.

So in this code:

<div
	{ hx.Get("/example")... }
	{ hx.SwapExtended(swap.New().Strategy(swap.AfterEnd))... }
>
	Get Some HTML & Append It
</div>

The div will issue a request to /example and append the returned content after the div.

For documentation about modifiers, see swap.Builder.

HTMX Attribute: hx-swap

Example
package main

import (
	"fmt"
	"time"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/swap"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SwapExtended(
		swap.New().
			Strategy(swap.OuterHTML).
			Settle(time.Second).
			ShowElement("#example", swap.Top),
	))
}
Output:

hx-swap='outerHTML settle:1s show:#example:top'

func (*HX[T]) SwapOOB added in v0.0.5

func (hx *HX[T]) SwapOOB() T

SwapOOP allows you to specify that some content in a response should be swapped into the DOM somewhere other than the target by ID, that is “Out of Band”. This allows you to piggy back updates to other element updates on a response.

Consider the following response HTML:

<div>
...
</div>
<div id="alerts" { hx.SwapOOB()... }>
	 Saved!
</div>

The first div will be swapped into the target the usual manner. The second div, however, will be swapped in as a replacement for the element with the id alerts, and will not end up in the target.

If the value is true or outerHTML (which are equivalent) the element will be swapped inline.

Notes

hx-swap-oob is not inherited

HTMX Attribute: hx-swap-oob

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SwapOOB())
}
Output:

hx-swap-oob='true'

func (*HX[T]) SwapOOBSelector added in v0.0.5

func (hx *HX[T]) SwapOOBSelector(strategy swap.Strategy, cssSelector string) T

SwapOOP allows you to specify that some content in a response should be swapped into the DOM somewhere other than the target by selector, that is “Out of Band”. This allows you to piggy back updates to other element updates on a response.

Consider the following response HTML:

<div>
...
</div>
<div { hx.SwapOOBSelector(swap.OuterHTML, "#alerts")... }>
	 Saved!
</div>

The first div will be swapped into the target the usual manner. The second div, however, will be swapped in as a replacement for the element with the id #alerts, and will not end up in the target.

If the value is outerHTML the element will be swapped inline.

Notes

hx-swap-oob is not inherited

HTMX Attribute: hx-swap-oob

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/swap"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SwapOOBSelector(swap.AfterBegin, "#example"))
}
Output:

hx-swap-oob='afterbegin:#example'

func (*HX[T]) SwapOOBWithStrategy added in v0.0.5

func (hx *HX[T]) SwapOOBWithStrategy(strategy swap.Strategy) T

SwapOOBWithStrategy allows you to specify that some content in a response should be swapped into the DOM somewhere other than the target by ID with a swap strategy, that is “Out of Band”. This allows you to piggy back updates to other element updates on a response.

Consider the following response HTML:

<div>
...
</div>
<div id="alerts" { hx.SwapOOBWithStrategy(swap.AfterBegin)... }>
	 Saved!
</div>

The first div will be swapped into the target the usual manner. The second div, however, will be swapped in after the start of the element with the id #alerts, and will not end up in the target.

If the value is outerHTML (which is equivalent to HX.SwapOOB) the element will be swapped inline.

Notes

hx-swap-oob is not inherited

HTMX Attribute: hx-swap-oob

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/swap"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SwapOOBWithStrategy(swap.AfterBegin))
}
Output:

hx-swap-oob='afterbegin'

func (*HX[T]) Sync added in v0.0.5

func (hx *HX[T]) Sync(extendedSelector SyncSelector) T

Sync allows you to synchronize AJAX requests between multiple elements, using a CSS selector to indicate the element to synchronize on.

The hx-sync attribute consists of a CSS selector to indicate the element to synchronize on. By default, this will use the SyncDrop strategy.

You can pass SyncThis as a selector to synchronize requests from the current element.

Notes

  • hx-sync is inherited and can be placed on a parent element

HTMX Attribute: hx-sync

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Sync(htmx.SyncThis))
}
Output:

hx-sync='this'

func (*HX[T]) SyncStrategy added in v0.0.5

func (hx *HX[T]) SyncStrategy(extendedSelector SyncSelector, strategy SyncStrategy) T

SyncStrategy allows you to synchronize AJAX requests between multiple elements.

The hx-sync attribute consists of a CSS selector to indicate the element to synchronize on, followed optionally by a colon and then by an optional syncing strategy.

You can pass "hx.This" as a selector to synchronize requests from the current element.

Notes

  • hx-sync is inherited and can be placed on a parent element

HTMX Attribute: hx-sync

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SyncStrategy(htmx.SyncThis, htmx.SyncDrop))
}
Output:

hx-sync='this:drop'
Example (Relative)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.SyncStrategy(
		htmx.SyncRelative(htmx.Closest, "#example"),
		htmx.SyncDrop,
	))
}
Output:

hx-sync='closest #example:drop'

func (*HX[T]) Target added in v0.0.5

func (hx *HX[T]) Target(extendedSelector TargetSelector) T

Target allows you to target a different element for swapping than the one issuing the AJAX request.

You can pass an extended selector to this method, using [RelativeSelector].

Here is an example that targets a div:

<div>
	<div id="response-div"></div>
 	<button
		{ hx.Post("/register")... }
		{ hx.Target("#response-div")... }
		{ hx.Swap(swap.BeforeEnd)... }
		>
 		Register!
 	</button>
</div>

The response from the /register url will be appended to the div with the id response-div.

Notes

hx-target is inherited and can be placed on a parent element

HTMX Attribute: hx-target

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Target("#example"))
}
Output:

hx-target='#example'
Example (NonStandard)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Target(htmx.TargetThis))
}
Output:

hx-target='this'
Example (RelativeSelector)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Target(
		htmx.TargetRelative(htmx.Closest, "#example"),
	))
}
Output:

hx-target='closest #example'

func (*HX[T]) Trigger added in v0.0.5

func (hx *HX[T]) Trigger(event trigger.TriggerEvent) T

Trigger allows you to specify what event triggers an AJAX request.

For usage with modifiers and polling, see [HX.TriggerExtended()].

HTMX Attribute: hx-trigger

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Trigger("click"))
}
Output:

hx-trigger='click'
Example (NonStandard)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/trigger"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Trigger(trigger.Load))
}
Output:

hx-trigger='load'

func (*HX[T]) TriggerExtended added in v0.0.5

func (hx *HX[T]) TriggerExtended(triggers ...trigger.Trigger) T

TriggerExtended allows you to specify what triggers an AJAX request, with modifiers for changing the behavior of the trigger. A trigger value can be one of the following:

  • An event name (e.g. “click” or “my-custom-event”) followed by an event filter and a set of event modifiers
  • A polling definition of the form every <timing declaration>
  • A comma-separated list of such events

See trigger.Event and trigger.Poll for more information on options.

HTMX Attribute: hx-trigger

Example
package main

import (
	"fmt"
	"time"

	"github.com/will-wow/typed-htmx-go/htmx"
	"github.com/will-wow/typed-htmx-go/htmx/trigger"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.TriggerExtended(
		trigger.On("click").When("ctrlKey").Target("#element"),
		trigger.Every(time.Second),
		trigger.Intersect().Root("#element").Threshold(0.2),
	))
}
Output:

hx-trigger='click[ctrlKey] target:#element, every 1s, intersect root:#element threshold:0.2'

func (*HX[T]) Unset added in v0.0.5

func (hx *HX[T]) Unset(attr Attribute) T

Unset sets the value of the selected attributes as "unset" to clear a property that would normally be inherited (e.g. hx-confirm).

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Unset(htmx.Boost))
}
Output:

hx-boost='unset'

func (*HX[T]) Validate added in v0.0.5

func (hx *HX[T]) Validate(validate bool) T

Validate will cause an element to validate itself by way of the HTML5 Validation API before it submits a request.

Only <form> elements validate data by default, but other elements do not. Adding hx-validate="true" to <input>, <textarea> or <select> enables validation before sending requests.

Notes

  • hx-validate is not inherited

HTMX Attribute: hx-validate

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Validate(true))
}
Output:

hx-validate='true'

func (*HX[T]) Vals added in v0.0.5

func (hx *HX[T]) Vals(vals any) T

Vals allows you to add to the parameters that will be submitted with an AJAX request.

The value of this attribute is a list of name-expression values in JSON (JavaScript Object Notation) format, marshaled from a struct or map.

By default, the value of hx-vals must be valid JSON. It is not dynamically computed.

Notes

hx-vals is inherited and can be placed on a parent element. A child declaration of a variable overrides a parent declaration. Input values with the same name will be overridden by variable declarations.

HTMX Attribute: hx-vals

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Vals(map[string]int{"one": 1, "two": 2}))
}
Output:

hx-vals='{"one":1,"two":2}'
Example (Error)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.Vals(func() {}))
}
Output:

hx-vals='{}'
Example (Invalid)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	// You would expect this to be an error, but `Vals` doesn't check the type of the value for performance reasons.
	fmt.Println(hx.Vals(0))
}
Output:

hx-vals='0'

func (*HX[T]) ValsJS added in v0.0.5

func (hx *HX[T]) ValsJS(vals map[string]string) T

ValsJS allows you to add to the parameters that will be submitted with an AJAX request, using JavaScript to compute the values.

Pass a map[string]string to this method, to generate a Javascript object. The values should be valid JavaScript expressions.

When using evaluated code you can access the event object. This example includes the value of the last typed key within the input.

<div
	{ hx.Get("/example")... }
	{ hx.Trigger("keyup")... }
	{ hx.ValsJS(map[string]string{"lastKey": "event.key"})... }
>
	<input type="text" />
</div>

Security Considerations

If you use the javascript: prefix, be aware that you are introducing security considerations, especially when dealing with user input such as query strings or user-generated content, which could introduce a Cross-Site Scripting (XSS) vulnerability.

Notes

hx-vals is inherited and can be placed on a parent element. A child declaration of a variable overrides a parent declaration. Input values with the same name will be overridden by variable declarations.

HTMX Attribute: hx-vals

Example
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ValsJS(map[string]string{"lastKey": "event.key"}))
}
Output:

hx-vals='js:{lastKey:event.key}'
Example (WithInvalidIdentifier)
package main

import (
	"fmt"

	"github.com/will-wow/typed-htmx-go/htmx"
)

var hx = htmx.NewStringAttrs()

func main() {
	fmt.Println(hx.ValsJS(map[string]string{"last-key": "event.key"}))
}
Output:

hx-vals='js:{"last-key":event.key}'

type IncludeSelector added in v0.0.5

type IncludeSelector string
const IncludeThis IncludeSelector = "this"

type IndicatorModifier added in v0.0.5

type IndicatorModifier string
const IndicatorClosest IndicatorModifier = "closest"

type IndicatorSelector added in v0.0.5

type IndicatorSelector string

type NewAttr added in v0.0.5

type NewAttr[T any] func(key Attribute, value any) T

type RelativeModifier added in v0.0.7

type RelativeModifier string

A RelativeModifier is a relative modifier to a CSS selector. This is used for "extended selectors". Some attributes only support a subset of these, but any Relative function that takes this type supports the full set..

const (
	Closest  RelativeModifier = "closest"  // find the closest ancestor element or itself, that matches the given CSS selector
	Find     RelativeModifier = "find"     // find the first child descendant element that matches the given CSS selector
	Next     RelativeModifier = "next"     // scan the DOM forward for the first element that matches the given CSS selector. (e.g. next .error will target the closest following sibling element with error class)
	Previous RelativeModifier = "previous" // scan the DOM backwards fo
)

type RequestConfig added in v0.0.5

type RequestConfig struct {
	Timeout     time.Duration // the timeout for the request
	Credentials bool          // if the request will send credentials
	NoHeaders   bool          // strips all headers from the request
}

RequestConfig describes static [HX.Request()] attributes See https://htmx.org/attributes/hx-request/

func (RequestConfig) String added in v0.0.5

func (r RequestConfig) String() string

String returns the string representation of the RequestConfig, used internally by [HX.Request()].

type RequestConfigJS added in v0.0.5

type RequestConfigJS struct {
	Timeout     string // the timeout for the request in milliseconds
	Credentials string // if the request will send credentials
	NoHeaders   string // strips all headers from the request
}

A RequestConfigJS describes runtime [HX.RequestJS()] attributes.

To pass a literal string, use wrap it in quotes like "'string'".

See https://htmx.org/attributes/hx-request/ for more details

func (RequestConfigJS) String added in v0.0.5

func (r RequestConfigJS) String() string

String returns the string representation of the RequestConfig, used internally by [HX.RequestJS()].

type SelectOOBStrategy added in v0.0.5

type SelectOOBStrategy struct {
	Selector StandardCSSSelector
	Strategy swap.Strategy
}

type StandardCSSSelector added in v0.0.5

type StandardCSSSelector string

A StandardCSSSelector is any valid CSS selector, like #element or `.class > button`.

type SyncSelector added in v0.0.5

type SyncSelector string

A SyncSelector is a CSS selector, or a non-standard selector for the [HX.Sync()] attribute.

const SyncThis SyncSelector = "this" // synchronize requests from the current element.

type SyncStrategy

type SyncStrategy string

A SyncStrategy describes how to synchronize AJAX requests with [HX.SyncStrategy()].

const (
	SyncDrop       SyncStrategy = "drop"        // drop (ignore) this request if an existing request is in flight (the default)
	SyncAbort      SyncStrategy = "abort"       // drop (ignore) this request if an existing request is in flight, and, if that is not the case, abort this request if another request occurs while it is still in flight
	SyncReplace    SyncStrategy = "replace"     // abort the current request, if any, and replace it with this request
	SyncQueue      SyncStrategy = "queue"       // place this request in the request queue associated with the given element
	SyncQueueFirst SyncStrategy = "queue first" // queue the first request to show up while a request is in flight
	SyncQueueLast  SyncStrategy = "queue last"  // queue the last request to show up while a request is in flight
	SyncQueueAll   SyncStrategy = "queue all"   // queue all requests that show up while a request is in flight
)

type TargetSelector added in v0.0.5

type TargetSelector string

A TargetSelector is a CSS selector, or a non-standard selector for the [HX.Target()] attribute.

const (
	TargetThis     TargetSelector = "this"     // indicates that the element that the hx-target attribute is on is the target.
	TargetNext     TargetSelector = "next"     // resolves to element.nextElementSibling
	TargetPrevious TargetSelector = "previous" // resolves to element.previousElementSibling
)

Directories

Path Synopsis
ext
ajaxheader
package ajaxheader adds the X-Requested-With header to requests with the value “XMLHttpRequest”.
package ajaxheader adds the X-Requested-With header to requests with the value “XMLHttpRequest”.
alpinemorph
package alpinemorph allows you to use the Alpine.js lightweight [morph plugin] as the swapping mechanism in htmx which is necessary to retain Alpine state when you have entire Alpine components swapped by htmx.
package alpinemorph allows you to use the Alpine.js lightweight [morph plugin] as the swapping mechanism in htmx which is necessary to retain Alpine state when you have entire Alpine components swapped by htmx.
classtools
package classtools allows you to specify CSS classes that will be swapped onto or off of the elements by using a classes or data-classes attribute.
package classtools allows you to specify CSS classes that will be swapped onto or off of the elements by using a classes or data-classes attribute.
debug
package debug logs all htmx events for the element it is on, either through the console.debug function or through the console.log function with a DEBUG: prefix.
package debug logs all htmx events for the element it is on, either through the console.debug function or through the console.log function with a DEBUG: prefix.
eventheader
package eventheader adds the Triggering-Event header to requests.
package eventheader adds the Triggering-Event header to requests.
loadingstates
package loadingstates allows you to easily manage loading states while a request is in flight, including disabling elements, and adding and removing CSS classes.
package loadingstates allows you to easily manage loading states while a request is in flight, including disabling elements, and adding and removing CSS classes.
preload
package preload allows you to load HTML fragments into your browser’s cache before they are requested by the user, so that additional pages appear to users to load nearly instantaneously.
package preload allows you to load HTML fragments into your browser’s cache before they are requested by the user, so that additional pages appear to users to load nearly instantaneously.
removeme
package removeme allows you to remove an element after a specified interval.
package removeme allows you to remove an element after a specified interval.
responsetargets
package responsetargets allows you to specify different target elements to be swapped when different HTTP response codes are received.
package responsetargets allows you to specify different target elements to be swapped when different HTTP response codes are received.
restored
package restored triggers an event restored whenever a back button even is detected while using [htmx.HX.boost].
package restored triggers an event restored whenever a back button even is detected while using [htmx.HX.boost].
sse
package sse connects to an EventSource directly from HTML.
package sse connects to an EventSource directly from HTML.
internal
mod
package mod providers utilities for working with modifiers.
package mod providers utilities for working with modifiers.
package on holds constants for the camel-cased HTMX event names.
package on holds constants for the camel-cased HTMX event names.
package swap provides a builder for the hx-swap attribute value.
package swap provides a builder for the hx-swap attribute value.
package trigger provides builders for hx-trigger attribute values.
package trigger provides builders for hx-trigger attribute values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL