diff --git a/CHANGELOG.md b/CHANGELOG.md index aa92ff4..abb6271 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ## [Unreleased] +## v1.3.0 + +### Added + +- feat: allow to handle request using json body" +- feat: add `WithJsonRequest` on form +- feat: add `MapToUrlValues` transformer + ## v1.2.0 ### Added diff --git a/form/form.go b/form/form.go index 348869f..168c7f2 100644 --- a/form/form.go +++ b/form/form.go @@ -16,6 +16,8 @@ package form // along with this program. If not, see . import ( + "encoding/json" + "io/ioutil" "maps" "net/http" "net/url" @@ -32,6 +34,7 @@ type Form struct { GlobalFields []*Field Errors []validation.Error Method string + JsonRequest bool Action string Name string Options []*Option @@ -201,6 +204,12 @@ func (f *Form) Mount(data any) error { return nil } +func (f *Form) WithJsonRequest() *Form { + f.JsonRequest = true + + return f +} + // Copies datas from the form to a struct func (f *Form) Bind(data any) error { toBind := make(map[string]any) @@ -216,11 +225,30 @@ func (f *Form) Bind(data any) error { func (f *Form) HandleRequest(req *http.Request) { var data url.Values - if f.Method != "GET" { - req.ParseForm() - data = req.Form + if f.JsonRequest { + body, err := ioutil.ReadAll(req.Body) + + if err != nil { + return + } + + mapping := make(map[string]any) + err = json.Unmarshal(body, &mapping) + + if err != nil { + return + } + + data = url.Values{} + util.MapToUrlValues(&data, f.Name, mapping) } else { - data = req.URL.Query() + switch f.Method { + case "GET": + data = req.URL.Query() + default: + req.ParseForm() + data = req.Form + } } isSubmitted := false diff --git a/go.mod b/go.mod index 3973949..20dda1e 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,9 @@ module gitnet.fr/deblan/go-form go 1.23.0 require ( + github.com/iancoleman/strcase v0.3.0 github.com/mitchellh/mapstructure v1.5.0 github.com/spf13/cast v1.9.2 github.com/yassinebenaid/godump v0.11.1 -) - -require ( - github.com/iancoleman/strcase v0.3.0 // indirect - github.com/samber/lo v1.51.0 // indirect - golang.org/x/text v0.22.0 // indirect - maragu.dev/gomponents v1.1.0 // indirect + maragu.dev/gomponents v1.1.0 ) diff --git a/go.sum b/go.sum index f6698b1..c6c8a71 100644 --- a/go.sum +++ b/go.sum @@ -12,13 +12,9 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/samber/lo v1.51.0 h1:kysRYLbHy/MB7kQZf5DSN50JHmMsNEdeY24VzJFu7wI= -github.com/samber/lo v1.51.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/yassinebenaid/godump v0.11.1 h1:SPujx/XaYqGDfmNh7JI3dOyCUVrG0bG2duhO3Eh2EhI= github.com/yassinebenaid/godump v0.11.1/go.mod h1:dc/0w8wmg6kVIvNGAzbKH1Oa54dXQx8SNKh4dPRyW44= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= maragu.dev/gomponents v1.1.0 h1:iCybZZChHr1eSlvkWp/JP3CrZGzctLudQ/JI3sBcO4U= maragu.dev/gomponents v1.1.0/go.mod h1:oEDahza2gZoXDoDHhw8jBNgH+3UR5ni7Ur648HORydM= diff --git a/util/transformer.go b/util/transformer.go new file mode 100644 index 0000000..743b117 --- /dev/null +++ b/util/transformer.go @@ -0,0 +1,42 @@ +package util + +import ( + "fmt" + "net/url" +) + +func MapToUrlValues(values *url.Values, prefix string, data map[string]any) { + keyFormater := "%s" + + if prefix != "" { + keyFormater = prefix + "[%s]" + } + + for key, value := range data { + keyValue := fmt.Sprintf(keyFormater, key) + + switch v := value.(type) { + case string: + values.Add(keyValue, v) + case []string: + case []int: + case []int32: + case []int64: + case []any: + for _, s := range v { + values.Add(keyValue, fmt.Sprintf("%v", s)) + } + case bool: + if v { + values.Add(keyValue, "1") + } else { + values.Add(keyValue, "0") + } + case int, int64, float64: + values.Add(keyValue, fmt.Sprintf("%v", v)) + case map[string]any: + MapToUrlValues(values, keyValue, v) + default: + } + } +}