forms

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 25, 2024 License: MPL-2.0 Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const FormDone string = "$done"
View Source
const FormStart string = ""

Variables

This section is empty.

Functions

func DecodeLen

func DecodeLen(data []byte) (uint, int)

func DecodeStrMap

func DecodeStrMap(data []byte, yield StrmapYield)

func EncodeLen

func EncodeLen(val uint) []byte

func EncodeStrMap

func EncodeStrMap(iter StrmapIter) []byte

func SprintBytes

func SprintBytes(data []byte) string

func SprintMap

func SprintMap(data []byte) string

Types

type FieldHandler

type FieldHandler func(form *Form, w server.ResponseWriter, r *server.Request) bool

Handle the input for a specific field

Return true if a response was sent to w; false otherwise.

type Form

type Form struct {
	// Map of field handlers
	Fields map[string]FieldHandler
	// If Field is unset, use DefaultField
	DefaultField string

	// Current field being processed
	Field string
	// The last time the form has been handled
	LastUsed time.Time
	// The form data
	Data FormData
}

func NewForm

func NewForm(fields map[string]FieldHandler) *Form

Create a new SequenceForm using a map of field Handlers.

FieldHandler is very versatile, but can be difficult to use. There are several form builders that will cover most use cases:

* NewSequenceForm

func NewSequenceForm

func NewSequenceForm(fields []SequenceField) *Form

Create a new Sequential Form using SequenceField

The provided field options are requested in order.

After the form is complete, all the fields will be populated in Data using the key Field from the SequenceField options.

 	form := NewSequenceForm([]SequenceField{
		{
			Field: "username",
			Prompt: "Enter your username",
		},
		{
			Field: "password",
			Prompt: "Enter your password",
			Sensitive: true,
			Redirect: true,
		},
 	})
	form.UnmarshalBinary(saveData)
 	if form.HandleInput(w, r) {
		saveData, err = form.MarshalBinary()
		...
	}
	deleteSaveData()
 	username := form.Data["username"]
 	password := form.Data["password"]

func NewSmorgasForm

func NewSmorgasForm(home SmorgasHome, doneField string, fields []SmorgasField) *Form

Create a new smorgasboard form. This is a form where there is one main page generated by `home`. There are links on this page to the fields of the form in the format `=> {r.Path}?{field}`.

When a link is clicked, the mode is changed and a input response is sent for the corresponding field. Keep in mind that to maintain a good user experience, Field names entered as the value will change the mode to that field. This is so that if a client uses the back button instead of entering nothing to go back, the user interface will still act how they expect it to.

`doneField` is the field name that will mark the form as complete.

func (*Form) Clear

func (self *Form) Clear()

Clear the form data

This is generally used in conjunction with IsStale.

func (*Form) HandleInput

func (self *Form) HandleInput(w server.ResponseWriter, r *server.Request) bool

Handle the form input

When true is returned, that means that a response has been sent and that the form is not yet complete and no data should be sent to the client.

When false is returned, that means that nothing has been sent to the client and the form is complete.

After the form handles its input, the form data will have been updated so it should be saved to whichever medium is being used.

func (*Form) IsStale

func (self *Form) IsStale(maxAge time.Duration) bool

Check if the form has not used for maxAge time.

An unused form is not considered stale.

func (*Form) LoadData

func (self *Form) LoadData(data FormData) error

Load the form data from the provided FormData object

func (*Form) MarshalBinary

func (self *Form) MarshalBinary() ([]byte, error)

Marshal the data into binary

func (*Form) MarshalText

func (self *Form) MarshalText() ([]byte, error)

Marshal the data into json

func (*Form) SaveData

func (self *Form) SaveData() (FormData, error)

Save the data from the form into a FormData object.

func (*Form) UnmarshalBinary

func (self *Form) UnmarshalBinary(data []byte) error

Unmarshal the data from binary

func (*Form) UnmarshalText

func (self *Form) UnmarshalText(data []byte) error

Unmarshal the data from json

type FormData

type FormData map[string]string

func (FormData) MarshalBinary

func (self FormData) MarshalBinary() ([]byte, error)

Marshal the form data into binary data

func (FormData) MarshalText

func (self FormData) MarshalText() ([]byte, error)

Marshal the form data into json

func (FormData) UnmarshalBinary

func (self FormData) UnmarshalBinary(data []byte) error

func (FormData) UnmarshalText

func (self FormData) UnmarshalText(data []byte) error

type SequenceField

type SequenceField struct {
	// The name of the field (Required)
	Field string
	// The prompt sent for this field (Required)
	Prompt string
	// Whether true 11 (sensitive input) or false 10 (input) should be sent
	Sensitive bool
	// Whether the response should first redirect to the current Path
	//
	// This effectively erases the query from the clients path before prompting the
	// next field.
	//
	// 	gemini://my.site/foo/bar
	// 		11 Enter your password
	// 	gemini://my.site/foo/bar?mysecretpassword
	// 		30 /foo/bar
	// 	gemini://my.site/foo/bar
	// 		20 text/gmini
	// 		...
	Redirect bool
	// Validate the Input
	//
	// If err is an empty string, then the input is replaced with output and the
	// next field is requested.
	// If err is not empty, then the same field is requested with the given error
	// message
	Validator func(form *Form, input string) (output, err string)
	// Perform an action after the validator is called
	//
	// Returns the next field to change to. `forms.FormDone` to finish the form.
	//
	// If both nextField and err is empty, then the next field is the default
	// next field.
	Action func(form *Form, input string) (nextField, err string)
}

type SmorgasField

type SmorgasField struct {
	// The name of the field (Required)
	Field string
	// The prompt sent for this Field (Required)
	Prompt string
	// Whether true 11 (sensitive input) or false 10 (input) should be sent
	Sensitive bool
	// Whether the response should first redirect to the current Path
	//
	// This effectively erases the query from the clients path before prompting the
	// next field.
	Redirect bool
	// Validate the Input
	//
	// If err is an empty string, then the input is replaced with output and the
	// next field is requested.
	// If err is not empty, then the same field is requested with the given error
	// message
	Validator func(input string) (output, err string)
	// A custom handler for the input
	//
	// If Validator is not nil, then Validator will be called before Handler and
	// the transformed input will be provided.
	//
	// When Handler is provided, no logic will happen outside of Handler. So it's
	// the job of Handler to set the field value in form.
	//
	// Returns true if a response was made, and an error message if an error
	// occurred.
	Handler func(form *Form, input string, w server.ResponseWriter, r *server.Request) (responded bool, error string)
	// If the validator returns an error, should the response be the home page or
	// send the prompt again
	//
	// true  -> send the prompt again
	// false -> send the home page
	RepromptOnErr bool
}

type SmorgasHome

type SmorgasHome func(form *Form, errors map[string]string, w server.ResponseWriter, r *server.Request) bool

Render the home page of a smorgasboard form.

The data sent to the client should be a gemini page with links to all the available fields. Each of these links should look something like this

=> {r.Path}?{field}

`errors` is a map of field -> error for each field. These should be rendered alongside the link to the matching field.

Return true if a response was sent to the client

type StrmapIter

type StrmapIter func(yield StrmapYield)

type StrmapYield

type StrmapYield func(k, v []byte) bool

Jump to

Keyboard shortcuts

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