forms

package module
v0.0.0-...-d661c96 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2017 License: MIT Imports: 6 Imported by: 1

README

Go-FORM-it

Build Status GoDoc

Description

go-form-it makes form creation and handling easy. It allows the creation of form without having to write HTML code or bother to make the code Bootstrap compatible. You can just create your form instance and add / populate / customize fields based on your needs. Or you can let go-form-it do that for you starting from any object instance.

To integrate go-form-it forms into your application simply pass the form object to the template and call its Render method. In your code:

tmpl.Execute(buf, map[string]interface{}{"form": form})

In your template:

{{ if .form }}{{ .form.Render }}{{ end }}

Installation

To install this package simply:

go get github.com/kirves/go-form-it

Forms

There are two predefined styles for forms: base HTML forms and Bootstrap forms: they have different structures and predefined classes. Style aside, forms can be created from scratch or starting from a base instance.

From scratch

You can create a form instance by simply deciding its style and providing its method and action:

form := BaseForm(POST, "/action.html")

or

form := BootstrapForm(POST, "/action.html")

to create a Bootstrap compatible form. Now that you have a form instance you can customize it by adding classes, parameters, CSS values or id. Each method returns a pointer to the same form, so multiple calls can be chained:

form.SetId("TestForm").AddClass("form").AddCss("border", "auto")

Obviously, elements can be added as well:

form.Elements(fields.TextField("text_field"))

Elements can be either FieldSets or Fields: the formers are simply collections of fields translated into a <fieldset></fieldset> element. Elements are added in order, and they are displayed in the exact same order. Note that single elements can be removed from a form referencing them by name:

form.RemoveElement("text_field")

Typical usage looks like this:

form := BaseForm(POST, "/action.html").Elements(
	fields.TextField("text_field").SetLabel("Username"),
	FieldSet("psw_fieldset",
		fields.PasswordField("psw1").AddClass("password_class").SetLabel("Password 1"),
		fields.PasswordField("psw2").AddClass("password_class").SetLabel("Password 2"),
		),
	fields.SubmitButton("btn1", "Submit"),
	)

A call to form.Render() returns the following form:

<form method="POST" action="/action.html">
	<label>Username</label>
	<input type="text" name="text_field">
	<fieldset>
		<label>Password 1</label>
		<input type="password" name="psw1" class="password_class ">
		<label>Password 2</label>
		<input type="password" name="psw2" class="password_class ">
	</fieldset>
	<button type="submit" name="btn1">Submit</button>
</form>

From model instance

Instead of manually creating a form, it can be automatically created from an existing model instance: the package will try to infer the field types based on the instance fields and fill them accordingly. Default type-to-field mapping is as follows:

  • string: TextField
  • bool: Checkbox
  • time.Time: DatetimeField
  • int: NumberField
  • struct: recursively parse

You can customize field behaviors by adding tags to instance fields. Without tags this code:

type User struct {
	Username 	string
	Password1 	string
	Password2	string
}

u := User{}

form := BaseFormFromModel(u, POST, "/action.html")
form.Render()

would yield this HTML form:

<form method="POST" action="/action.html">
	<label>Username</label>
	<input type="text" name="Username">
	<label>Password1</label>
	<input type="text" name="Password1">
	<label>Password2</label>
	<input type="text" name="Password2">
	<button type="submit" name="submit">Submit</button>
</form>

A submit button is added by default.

Notice that the form is still editable and fields can be added, modified or removed like before.

When creating a form from a model instance, field names are created by appending the field name to the baseline; the baseline is empty for single level structs but is crafted when nested structs are found: in this case it becomes the field name followed by a dot. So for example, if the struct is:

type A struct {
	field1 	int
	field2 	int
}

type B struct {
	field0 	int
	struct1	A
}

The final form will contain fields "field0", "struct1.field1" and "struct1.field2".

Tags

Struct tags can be used to slightly modify automatic form creation. In particular the following tags are parsed:

  • form_options: can contain the following keywords separated by comma
    • skip: skip field, do not convert to HTML field
    • checked: for Checkbox fields, check by default
    • multiple: for select fields, allows multiple choices
  • form_widget: override custom widget with one of the following
    • text
    • textarea
    • password
    • select
    • datetime
    • date
    • time
    • number
    • range
    • radio
    • static (simple text)
  • form_choices: defines options for select and radio input fields
  • form_max: max value (number, range, datetime, date and time fields)
  • form_min: min value (number, range, datetime, date and time fields)
  • form_step: step value (range field)
  • form_rows: number of rows (textarea field)
  • form_cols: number of columns (textarea field)
  • form_value: input field value (used if field is empty)
  • form_label: label for input field

The code would therefore be better like this:

type User struct {
	Username 	string
	Password1 	string 	`form_widget:"password" form_label:"Password 1"`
	Password2	string 	`form_widget:"password" form_label:"Password 2"`
	SkipThis	int 	`form_options:"skip"`
}

u := User{}

form := BaseFormFromModel(u, POST, "/action.html")
form.Render()

which translates into:

<form method="POST" action="/action.html">
	<label>Username</label>
	<input type="text" name="Username">
	<label>Password 1</label>
	<input type="password" name="Password1">
	<label>Password 2</label>
	<input type="password" name="Password2">
	<button type="submit" name="submit">Submit</button>
</form>

Fields

Field objects in go-form-it implement the fields.FieldInterface which exposes methods to edit classes, parameters, tags and CSS styles. See the documentation for details.

Most of the field widgets have already been created and integrate with Bootstrap. It is possible, however, to define custom widgets to render fields by simply assigning an object implementing the widgets.WidgetInterface to the Widget field.

Also, error messages can be added to fields via the AddError(err) method: in a Bootstrap environment they will be correctly rendered.

Text fields

This category includes text, password, textarea and hidden fields. They are all instantiated by providing the name, except the TextAreaField which also requires a dimension in terms of rows and columns.

f0 := fields.TextField("text")
f1 := fields.PasswordField("password")
f2 := fields.HiddenField("hidden")
f3 := fields.TextAreaField("textarea", 30, 50)

Option fields

This category includes checkbox, select and radio button fields. Checkbox field requires a name and a boolean to define its initial state (checked or not):

f := fields.Checkbox("checkbox", true)

Radio buttons, instead, require a name and a set of options to populate the field. The options are just a set of InputChoice (Id-Value pairs) objects:

opts := []fields.InputChoice{
	fields.InputChoice{"A", "Option A"},
	fields.InputChoice{"B", "Option B"},
}
f := fields.RadioField("radio", opts)

Select fields, on the other hand, allow option grouping. This can be achieved by passing a map[string][]InputChoice in which keys are groups containing choices given as values; the default (empty) group is "", which is not translated into any <optgroup></optgroup> element.

opts := map[string][]fields.InputChoice{
	"": []fields.InputChoice{fields.InputChoice{"A", "Option A"}},
	"group1": []fields.InputChoice{
		fields.InputChoice{"B", "Option B"},
		fields.InputChoice{"C", "Option C"},
	}
}
f := fields.SelectField("select", opts)

Select fields can allow multiple choices. To enable this option simply call the MultipleChoice() method on the field and provide the selected choices via AddSelected(...string):

f.MultipleChoice()
f.AddSelected("A", "B")

Number fields

Number and range fields are included. Number field only require a name to be instantiated; minimum and maximum values can optionally be set by adding min and max parameters respectively.

f := fields.NumberField("number")
f.SetParam("min", "1")

Range fields, on the other hand, require both minimum and maximum values (plus the identifier). The optional "step" value is set via SetParam.

f := fields.RangeField("range", 1, 10)
f.SetParam("step", "2")

Datetime fields

Datetime, date and time input fields are defined in go-form-it.

f0 := fields.DatetimeField("datetime")
f1 := fields.DateField("date")
f2 := fields.TimeField("time")

Values can be set via SetValue method; there's no input validation but format strings are provided to ensure the correct time-to-string conversion.

t := time.Now()
f0.SetValue(t.Format(fields.DATETIME_FORMAT))
f1.SetValue(t.Format(fields.DATE_FORMAT))
f2.SetValue(t.Format(fields.TIME_FORMAT))

Buttons

Buttons can be created calling either the Button, SubmitButton or ResetButton constructor methods and providing a text identifier and the content of the button itself.

btn0 := fields.Button("btn", "Click me!")

License

go-form-it is released under the MIT license. See LICENSE.

Documentation

Overview

This package provides form creation and rendering functionalities, as well as FieldSet definition. Two kind of forms can be created: base forms and Bootstrap3 compatible forms; even though the latters are automatically provided the required classes to make them render correctly in a Bootstrap environment, every form can be given custom parameters such as classes, id, generic parameters (in key-value form) and stylesheet options.

Index

Constants

View Source
const (
	POST = "POST"
	GET  = "GET"
)

Form methods: POST or GET.

Variables

This section is empty.

Functions

This section is empty.

Types

type FieldSetType

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

FieldSetType is a collection of fields grouped within a form.

func FieldSet

func FieldSet(name string, elems ...fields.FieldInterface) *FieldSetType

FieldSet creates and returns a new FieldSetType with the given name and list of fields. Every method for FieldSetType objects returns the object itself, so that call can be chained.

func (*FieldSetType) AddClass

func (f *FieldSetType) AddClass(class string) *FieldSetType

AddClass saves the provided class for the fieldset.

func (*FieldSetType) AddTag

func (f *FieldSetType) AddTag(tag string) *FieldSetType

AddTag adds a no-value parameter (e.g.: "disabled", "checked") to the fieldset.

func (*FieldSetType) Disable

func (f *FieldSetType) Disable() *FieldSetType

Disable adds tag "disabled" to the fieldset, making it unresponsive in some environment (e.g.: Bootstrap).

func (*FieldSetType) Enable

func (f *FieldSetType) Enable() *FieldSetType

Enable removes tag "disabled" from the fieldset, making it responsive.

func (*FieldSetType) Field

func (f *FieldSetType) Field(name string) fields.FieldInterface

Field returns the field identified by name. It returns an empty field if it is missing.

func (*FieldSetType) Name

func (f *FieldSetType) Name() string

Name returns the name of the fieldset.

func (*FieldSetType) RemoveClass

func (f *FieldSetType) RemoveClass(class string) *FieldSetType

RemoveClass removes the provided class from the fieldset, if it was present. Nothing is done if it was not originally present.

func (*FieldSetType) RemoveTag

func (f *FieldSetType) RemoveTag(tag string) *FieldSetType

RemoveTag removes a tag from the fieldset, if it was present.

func (*FieldSetType) Render

func (f *FieldSetType) Render() template.HTML

Render translates a FieldSetType into HTML code and returns it as a template.HTML object.

type Form

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

Form structure.

func BaseForm

func BaseForm(method, action string) *Form

BaseForm creates an empty form with no styling.

func BaseFormFromModel

func BaseFormFromModel(m interface{}, method, action string) *Form

BaseFormFromModel returns a base form inferring fields, data types and contents from the provided instance. A Submit button is automatically added as a last field; the form is editable and fields can be added, modified or removed as needed. Tags can be used to drive automatic creation: change default widgets for each field, skip fields or provide additional parameters. Basic field -> widget mapping is as follows: string -> textField, bool -> checkbox, time.Time -> datetimeField, int -> numberField; nested structs are also converted and added to the form.

func BootstrapForm

func BootstrapForm(method, action string) *Form

BootstrapForm creates an empty form compliant with Bootstrap3 CSS, both in structure and classes.

func BootstrapFormFromModel

func BootstrapFormFromModel(m interface{}, method, action string) *Form

Same as BaseFormFromModel but returns a Bootstrap3 compatible form.

func (*Form) AddClass

func (f *Form) AddClass(class string) *Form

AddClass associates the provided class to the Form.

func (*Form) AddCss

func (f *Form) AddCss(key, value string) *Form

AddCss add a CSS value (in the form of option-value - e.g.: border - auto) to the form.

func (*Form) DeleteParam

func (f *Form) DeleteParam(key string) *Form

DeleteParm removes the parameter identified by key from form parameters list.

func (*Form) Elements

func (f *Form) Elements(elems ...FormElement) *Form

Elements adds the provided elements to the form.

func (*Form) Field

func (f *Form) Field(name string) fields.FieldInterface

Field returns the field identified by name. It returns an empty field if it is missing.

func (*Form) FieldSet

func (f *Form) FieldSet(name string) *FieldSetType

Field returns the field identified by name. It returns an empty field if it is missing.

func (*Form) RemoveClass

func (f *Form) RemoveClass(class string) *Form

RemoveClass removes the given class (if present) from the Form.

func (*Form) RemoveCss

func (f *Form) RemoveCss(key string) *Form

RemoveCss removes CSS style from the form.

func (*Form) RemoveElement

func (f *Form) RemoveElement(name string) *Form

RemoveElement removes an element (identified by name) from the Form.

func (*Form) Render

func (f *Form) Render() template.HTML

Render executes the internal template and renders the form, returning the result as a template.HTML object embeddable in any other template.

func (*Form) SetId

func (f *Form) SetId(id string) *Form

SetId set the given id to the form.

func (*Form) SetParam

func (f *Form) SetParam(key, value string) *Form

SetParam adds the given key-value pair to form parameters list.

type FormElement

type FormElement interface {
	Render() template.HTML
}

FormElement interface defines a form object (usually a Field or a FieldSet) that can be rendered as a template.HTML object.

Directories

Path Synopsis
This package provides basic constants used by go-form-it packages.
This package provides basic constants used by go-form-it packages.
This package provides all the input fields logic and customization methods.
This package provides all the input fields logic and customization methods.
This package contains the base logic for the creation and rendering of field widgets.
This package contains the base logic for the creation and rendering of field widgets.

Jump to

Keyboard shortcuts

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