Skip to content

Custom Field

You can provide your own custom templ component as a field apart of your form. This does not have to be a traditional form element with a <input/>, it can be anything you need within your form. If you want to create a custom element that works similarly to other form elements, with the same hooks, that is possible as well.

You can create a custom field as so:

go
FormCustom("my-custom-field")

Creating your component

It's best to freshen up on templ's documentation for how to create a custom component.

Here, for the purposes of illustration, we're using templ component functions to inline our custom components. We recommend for larger component, placing them in their own area in your project with a dedicated .templ file.

Common Methods

For a list of common field component methods, see here.

Component

The component method allows you to provide a single .templ component to be rendered as a field on your form.

go
// Iridium has it's own `context` package, so please be mindful of collisions.
// You can alias either one to avoid this.
import netCtx "context"

FormCustom("custom").
    Component(
        templ.ComponentFunc(
            func(netCtx netCtx.Context, w io.Writer) error {
                _, err := io.WriteString(
                    w, "<span>Hey! This is a custom field!</span>",
                )
                return err
            },
        ),
    )

Component Callback

The ComponentFn method allows you to customize what templ component gets rendered based on the current request. You'll be provided the current form context, and can return the appropriate component based on your callback method

go
// Iridium has it's own `context` package, so please be mindful of collisions.
// You can alias either one to avoid this.
import netCtx "context"

FormCustom("Custom").
    ComponentFn(
        func(ctx *FieldContext) templ.Component {
            return templ.ComponentFunc(
                func(netContext netContext.Context, w io.Writer) error {
                    name := "Default"
                    if val, err := ctx.GetModel; err != nil {
                        name = val
                    }
                    
                    _, err := io.WriteString(
                        w, fmt.Sprintf(`
                            <button class="btn btn-destructive">%s</button>
                        `, name),
                    )
                    return err
                },
            )
        },
    ),

Lifecycle Wiring

Notice

This lifecycle area is underdevelopped and may not work properly for your needs. Please let us know if you encounter issues via GitHub, or better yet, our discord

Wanna better develop this area? Check here

Optional Section

This is optional, and only required if you want your custom form field to actualy behave like a legitimate form field, meaning it can be tied into like other Iridium field with our hooks and features.

By default, form posts will collect all the <input/> tags nested inside themselves and send them whenever a user performs a request back to the server.

In order to access your custom fields' value, when your form submits, or in any of the reactivity or validation hooks, you're going to need to place in an <input/> tag somewhere yourself.

You can make your custom component behave like a live component if desired. This is getting into plugin territory. Iridium does not have a guide for this level of intergration yet, but it's not too hard to figure out how to wire this yourself for it's alpha version.

Please refer to these locations and use inspect element:

  • Take a look at the src code for common component like our TextInput for how we built our components. Link
  • We're applying HTMX attributes in certain cases, to trigger the live endpoints on certain changes.
    • You can either use inspect element or check out this src file.

Security

Please be cautious when writing your own custom components. If you source your html/templ component from a location where it directly injects user content into your template, you can accidentally open yourself up to XSS attacks. Be mindful of the source of your templates' structure & any alpine or htmx hooks you inject.

Templ by default escapes user content injected into templates, but this is something you should be vigilant about!

Released under the MIT License.