Forms is a fast, powerful, flexible, sortable web form rendering library written in golang.

forms

GoDoc

Description

forms 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 forms do that for you starting from any object instance.

To integrate forms 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/coscms/forms

Forms

There are two predefined themes 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 theme and providing its method and action:

form := NewWithConfig(&config.Config{
    Theme:"base", 
    Method:POST, 
    Action:"/action.html",
})

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

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 := NewWithConfig(&config.Config{
    Theme:"base", 
    Method:POST, 
    Action:"/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"),
    )

validation:

type User struct {
    Username     string    `valid:"Required;AlphaDash;MaxSize(30)"`
    Password1     string    `valid:"Required"`
    Password2    string    `valid:"Required"`
}
u := &User{}
form.SetModel(u) //Must set model
err := form.valid()
if err != nil { 
    // validation does not pass
}

Details about validation, please visit: https://github.com/webx-top/validation

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

">
<form method="POST" action="/action.html">
    <label>Usernamelabel>
    <input type="text" name="text_field">
    <fieldset>
        <label>Password 1label>
        <input type="password" name="psw1" class="password_class ">
        <label>Password 2label>
        <input type="password" name="psw2" class="password_class ">
    fieldset>
    <button type="submit" name="btn1">Submitbutton>
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 := NewFromModel(u, &config.Config{
    Theme:"bootstrap3", 
    Method:POST, 
    Action:"/action.html",
})

validation:

err := form.valid()
if err != nil { 
    // validation does not pass
}
form.Render()

would yield this HTML form:

">
<form method="POST" action="/action.html">
    <label>Usernamelabel>
    <input type="text" name="Username">
    <label>Password1label>
    <input type="text" name="Password1">
    <label>Password2label>
    <input type="text" name="Password2">
    <button type="submit" name="submit">Submitbutton>
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 Semicolon (;)

    • -: 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
    • hidden
    • textarea
    • password
    • select
    • datetime
    • date
    • time
    • number
    • range
    • radio
    • checkbox
    • static (simple text)
  • form_fieldset: define fieldset name

  • form_sort: sort number (asc, 0 ~ total-1)

  • form_choices: defines options for select and radio input fields

    • radio/checkbox example(format: id|value): 1|Option One|2|Option 2|3|Option 3
    • select example(format: group|id|value): G1|A|Option A|G1|B|Option B
      • "" group is the default one and does not trigger a rendering.
  • 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:"-"`
}
u := User{}
form := NewFromModel(u, &config.Config{
    Theme:"bootstrap3", 
    Method:POST, 
    Action:"/action.html",
})
form.Render()

which translates into:

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

Fields

Field objects in forms 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 set of options to populate the field. The options are just a set of InputChoice (ID-Value pairs) objects:

opts := []fields.InputChoice{
    fields.InputChoice{ID:"A", Val:"Option A"},
    fields.InputChoice{ID:"B", Val:"Option B"},
}
f := fields.CheckboxField("checkbox", opts)
f.AddSelected("A", "B")

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{ID:"A", Val:"Option A"},
    fields.InputChoice{ID:"B", Val:"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 element.

opts := map[string][]fields.InputChoice{
    "": []fields.InputChoice{fields.InputChoice{"A", "Option A"}},
    "group1": []fields.InputChoice{
        fields.InputChoice{ID:"B", Val:"Option B"},
        fields.InputChoice{ID:"C", Val:"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 forms.

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

forms is released under the MIT license. See LICENSE.

Similar Resources

staticfiles is an asset manager for a web applications written in Go.

Overview staticfiles is an asset manager for a web applications written in Go. It collects asset files (CSS, JS, images, etc.) from a different locati

Dec 7, 2022

Account Generator Bot, written in GoLang via gotgbot library

Account Generator Bot Account Generator Bot, written in GoLang via gotgbot library. Variables Env Vars - BOT_TOKEN - Get it from @BotFather CHANNEL_ID

Dec 28, 2021

A simple web library collection based fasthttp

A simple web library collection based fasthttp

Aug 17, 2022

Jump start with the golang, start building fast REST or GraphQL API's

personalized overview and instruction for everyday use golang projects and language structure.

Feb 7, 2022

GoCondor is a golang web framework with an MVC like architecture, it's based on Gin framework

GoCondor is a golang web framework with an MVC like architecture, it's based on Gin framework

GoCondor is a golang web framework with an MVC like architecture, it's based on Gin framework, it features a simple organized directory structure for your next project with a pleasant development experience, made for developing modern APIs and microservices.

Dec 29, 2022

A web forum built in Golang and SQLite and designed in SCSS

A web forum built in Golang and SQLite and designed in SCSS

Forum "Fairfax" 👉 What is it? A web forum built in Golang and SQLite and designed in SCSS. Members of the forum can take a personality test and be so

Nov 10, 2021

Using golang framework (Gin) to create a web-application

News feeder Using golang framework (Gin) to create a web-application. This simpl

Aug 22, 2022

Go-service-gin - Simple Web api application developed in Golang and Gin

Simple Web api application developed in Golang and Gin Initial Tutorial URL http

Jan 4, 2022

Creating Web Content in Golang

Creating Web Content in Golang From GoWebExamples.com Go is an open source programming language designed for building simple, fast, and reliable softw

Jan 16, 2022
[爬虫框架 (golang)] An awesome Go concurrent Crawler(spider) framework. The crawler is flexible and modular. It can be expanded to an Individualized crawler easily or you can use the default crawl components only.

go_spider A crawler of vertical communities achieved by GOLANG. Latest stable Release: Version 1.2 (Sep 23, 2014). QQ群号:337344607 Features Concurrent

Dec 30, 2022
Go kickstart is a simple repository that I'm managing to a have a fast setup for Go web application

Go kickstart is a simple repository that I'm managing to a have a fast setup for Go web application with my most common use cases using practices that I found useful and easy to maintain.

Jan 30, 2022
A simple web application written in Golang which listens on port 8080

GoWebApp It's a simple web application written in Golang which listens on port 8080 Building It can be build using the command go build -o metricsweba

Oct 21, 2021
Extract structured data from web sites. Web sites scraping.
Extract structured data from web sites. Web sites scraping.

Dataflow kit Dataflow kit ("DFK") is a Web Scraping framework for Gophers. It extracts data from web pages, following the specified CSS Selectors. You

Jan 7, 2023
記帳-PWA-web-app (Bookkeeping-PWA-web-app)
記帳-PWA-web-app (Bookkeeping-PWA-web-app)

GoKeep (bookkeeping web app) 記帳-PWA-web-app (Bookkeeping-PWA-web-app) demo link : https://bookkepping.herokuapp.com/ 測試用帳密 : tester002 , tester002 (亦可

Jan 31, 2022
log4jScanner: provides you with the ability to scan internal (only) subnets for vulnerable log4j web servicelog4jScanner: provides you with the ability to scan internal (only) subnets for vulnerable log4j web service
log4jScanner: provides you with the ability to scan internal (only) subnets for vulnerable log4j web servicelog4jScanner: provides you with the ability to scan internal (only) subnets for vulnerable log4j web service

log4jScanner Goals This tool provides you with the ability to scan internal (only) subnets for vulnerable log4j web services. It will attempt to send

Jan 5, 2023
Web terminal - A (unsafe) technical demo to export a shell to web browser
Web terminal - A (unsafe) technical demo to export a shell to web browser

Web Terminal A (unsafe) technical demo to export a shell to web browser. This pr

Dec 27, 2022
Go-web-scaffold - A simple scaffold for building web app quickly

Go-web-scaffold A simple scaffold for building web app quickly. features This sc

Jan 21, 2022
Tiny to-do list web app written in Go

Simple Lists Simple Lists is a tiny to-do list web app. It's written in Go in an old-school way with no JavaScript, plain old HTTP GET and POST, and a

Oct 19, 2022
🖖🏻 A self-hosted Quora like web application written in Go
🖖🏻 A self-hosted Quora like web application written in Go

Guora ???? A self-hosted Quora like web application written in Go 基于 Golang 类似知乎的私有部署问答应用 包含问答、评论、点赞、管理后台等功能 Quick Start (Docker Deploy) $ docker-comp

Dec 27, 2022