Similar to the profile form, the login form now parses and validates itself, with the InputField structs that the templates expect. I realized that i was doing more work than necessary when parsing fields fro the profile form because i was repeating the operation and the field name, so now it is a function of InputField. This time i needed extra attributes for the login form. I am not sure that the Go source code needs to know about HTML attributes, but it was the easiest way to pass them to the template.
89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
package pkg
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/mail"
|
|
"strings"
|
|
)
|
|
|
|
type Attribute struct {
|
|
Key, Val string
|
|
}
|
|
|
|
type InputField struct {
|
|
Name string
|
|
Label string
|
|
Type string
|
|
Value string
|
|
Required bool
|
|
Attributes []*Attribute
|
|
Errors []error
|
|
}
|
|
|
|
func (field *InputField) FillValue(r *http.Request) {
|
|
field.Value = strings.TrimSpace(r.FormValue(field.Name))
|
|
}
|
|
|
|
func (field *InputField) Equals(other *InputField) bool {
|
|
return field.Value == other.Value
|
|
}
|
|
|
|
func (field *InputField) IsEmpty() bool {
|
|
return field.Value == ""
|
|
}
|
|
|
|
func (field *InputField) HasValidEmail() bool {
|
|
_, err := mail.ParseAddress(field.Value)
|
|
return err == nil
|
|
}
|
|
|
|
type SelectOption struct {
|
|
Value string
|
|
Label string
|
|
}
|
|
|
|
type SelectField struct {
|
|
Name string
|
|
Label string
|
|
Selected string
|
|
Options []*SelectOption
|
|
Errors []error
|
|
}
|
|
|
|
func (field *SelectField) FillValue(r *http.Request) {
|
|
field.Selected = r.FormValue(field.Name)
|
|
}
|
|
|
|
func (field *SelectField) HasValidOption() bool {
|
|
for _, option := range field.Options {
|
|
if option.Value == field.Selected {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func MustGetOptions(ctx context.Context, conn *Conn, sql string, args ...interface{}) []*SelectOption {
|
|
rows, err := conn.Query(ctx, sql, args...)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var options []*SelectOption
|
|
for rows.Next() {
|
|
option := &SelectOption{}
|
|
err = rows.Scan(&option.Value, &option.Label)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
options = append(options, option)
|
|
}
|
|
if rows.Err() != nil {
|
|
panic(rows.Err())
|
|
}
|
|
|
|
return options
|
|
}
|