WIP html forms

This commit is contained in:
Niko Abeler 2023-07-05 22:03:00 +02:00
parent 1742728639
commit 936a0a0d80
4 changed files with 143 additions and 21 deletions

View File

@ -10,7 +10,7 @@ type ImageEntry struct {
} }
type ImageEntryMetaData struct { type ImageEntryMetaData struct {
ImagePath string `owl:"type=upload"` ImagePath string `owl:"inputType=file"`
} }
func (e *ImageEntry) ID() string { func (e *ImageEntry) ID() string {

View File

@ -0,0 +1,77 @@
package editor_test
import (
"owl-blogs/domain/model"
"owl-blogs/web/editor"
"reflect"
"testing"
"time"
"github.com/stretchr/testify/require"
)
type MockEntryMetaData struct {
Image string `owl:"inputType=file"`
Content string `owl:"inputType=text"`
}
type MockEntry struct {
id string
content model.EntryContent
publishedAt *time.Time
metaData *MockEntryMetaData
}
func (e *MockEntry) ID() string {
return e.id
}
func (e *MockEntry) Content() model.EntryContent {
return e.content
}
func (e *MockEntry) PublishedAt() *time.Time {
return e.publishedAt
}
func (e *MockEntry) MetaData() interface{} {
return e.metaData
}
func (e *MockEntry) Create(id string, content string, publishedAt *time.Time, metaData model.EntryMetaData) error {
e.id = id
e.content = model.EntryContent(content)
e.publishedAt = publishedAt
e.metaData = metaData.(*MockEntryMetaData)
return nil
}
func TestFieldToFormField(t *testing.T) {
field := reflect.TypeOf(&MockEntryMetaData{}).Elem().Field(0)
formField, err := editor.FieldToFormField(field)
require.NoError(t, err)
require.Equal(t, "Image", formField.Name)
require.Equal(t, "file", formField.Params.InputType)
}
func TestStructToFields(t *testing.T) {
fields, err := editor.StructToFormFields(&MockEntryMetaData{})
require.NoError(t, err)
require.Len(t, fields, 2)
require.Equal(t, "Image", fields[0].Name)
require.Equal(t, "file", fields[0].Params.InputType)
require.Equal(t, "Content", fields[1].Name)
require.Equal(t, "text", fields[1].Params.InputType)
}
func TestEditorEntryForm_HtmlForm(t *testing.T) {
formService := editor.NewEditorFormService(&MockEntry{})
form, err := formService.HtmlForm()
require.NoError(t, err)
require.Contains(t, form, "<form")
require.Contains(t, form, "method=\"POST\"")
require.Contains(t, form, "<input type=\"file\" name=\"Image\" />")
require.Contains(t, form, "<input type=\"text\" name=\"Content\" />")
require.Contains(t, form, "<input type=\"submit\" value=\"Submit\" />")
}

View File

@ -11,9 +11,13 @@ type EditorEntryForm struct {
entry model.Entry entry model.Entry
} }
type EntryFormFieldParams struct {
InputType string
}
type EntryFormField struct { type EntryFormField struct {
Name string Name string
Params map[string]string Params EntryFormFieldParams
} }
func NewEditorFormService(entry model.Entry) *EditorEntryForm { func NewEditorFormService(entry model.Entry) *EditorEntryForm {
@ -22,28 +26,66 @@ func NewEditorFormService(entry model.Entry) *EditorEntryForm {
} }
} }
func (s *EditorEntryForm) HtmlForm() string { func (s *EntryFormFieldParams) ApplyTag(tagKey string, tagValue string) error {
meta := s.entry.MetaData() switch tagKey {
case "inputType":
s.InputType = tagValue
default:
return fmt.Errorf("unknown tag key: %v", tagKey)
}
return nil
}
func (s *EntryFormField) Html() string {
return fmt.Sprintf("<input type=\"%v\" name=\"%v\" />\n", s.Params.InputType, s.Name)
}
func FieldToFormField(field reflect.StructField) (EntryFormField, error) {
formField := EntryFormField{
Name: field.Name,
Params: EntryFormFieldParams{},
}
tag := field.Tag.Get("owl")
for _, param := range strings.Split(tag, " ") {
parts := strings.Split(param, "=")
if len(parts) != 2 {
continue
}
err := formField.Params.ApplyTag(parts[0], parts[1])
if err != nil {
return EntryFormField{}, err
}
}
return formField, nil
}
func StructToFormFields(meta interface{}) ([]EntryFormField, error) {
entryType := reflect.TypeOf(meta).Elem() entryType := reflect.TypeOf(meta).Elem()
numFields := entryType.NumField() numFields := entryType.NumField()
fields := []EntryFormField{} fields := []EntryFormField{}
for i := 0; i < numFields; i++ { for i := 0; i < numFields; i++ {
field := EntryFormField{ field, err := FieldToFormField(entryType.Field(i))
Name: entryType.Field(i).Name, if err != nil {
Params: map[string]string{}, return nil, err
}
tag := entryType.Field(i).Tag.Get("owl")
for _, param := range strings.Split(tag, " ") {
parts := strings.Split(param, "=")
if len(parts) == 2 {
field.Params[parts[0]] = parts[1]
} else {
field.Params[param] = ""
}
} }
fields = append(fields, field) fields = append(fields, field)
} }
return fields, nil
return fmt.Sprintf("%v", fields) }
func (s *EditorEntryForm) HtmlForm() (string, error) {
meta := s.entry.MetaData()
fields, err := StructToFormFields(meta)
if err != nil {
return "", err
}
html := "<form method=\"POST\">\n"
for _, field := range fields {
html += field.Html()
}
html += "<input type=\"submit\" value=\"Submit\" />\n"
html += "</form>\n"
return html, nil
} }

View File

@ -17,10 +17,13 @@ func NewEditorHandler(entryService *app.EntryService) *EditorHandler {
} }
func (h *EditorHandler) HandleGet(c *fiber.Ctx) error { func (h *EditorHandler) HandleGet(c *fiber.Ctx) error {
form := editor.NewEditorFormService(&model.ImageEntry{}) c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
return c.SendString(form.HtmlForm()) formService := editor.NewEditorFormService(&model.ImageEntry{})
form, _ := formService.HtmlForm()
return c.SendString(form)
} }
func (h *EditorHandler) HandlePost(c *fiber.Ctx) error { func (h *EditorHandler) HandlePost(c *fiber.Ctx) error {
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
return c.SendString("Hello, Editor!") return c.SendString("Hello, Editor!")
} }