From 594971fc31584c7c0a1d9c1afd58da4c8b73456f Mon Sep 17 00:00:00 2001 From: Yonghwan SO Date: Fri, 12 Nov 2021 10:39:09 +0900 Subject: [PATCH 1/2] updated module dependencies (flect and validate) --- .github/workflows/tests.yml | 6 ++---- README.md | 8 -------- go.mod | 6 +++--- go.sum | 17 +++++------------ 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0e52eb6..267fc73 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,22 +1,20 @@ name: Tests on: [push] jobs: - tests-on: name: ${{matrix.go-version}} ${{matrix.os}} runs-on: ${{ matrix.os }} strategy: matrix: - go-version: [1.12.x, 1.13.x] + go-version: [1.16.x, 1.17.x] os: [macos-latest, windows-latest, ubuntu-latest] steps: - name: Checkout Code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 1 - name: Test env: GOPROXY: https://proxy.golang.org run: | - go mod tidy -v go test -race ./... diff --git a/README.md b/README.md index 69c814f..9ddae83 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,3 @@ Documentation is currently in [this repository Wiki](https://github.com/gobuffal If you want to contribute, please read this article first: [Contributing to Open Source Git Repositories in Go](https://splice.com/blog/contributing-open-source-git-repositories-go/). It shows how to configure your git environment to avoid common pitfalls. This article is recommended to all those who are looking to contribute to any Go projects. ^ Taken from [gobuffalo.io](https://https://gobuffalo.io/docs/contributing) - -### ⚠️ Send PRs to development branch - -The way we release in Tags is: - -1. We use `development` branch to accumulate changes to be released -2. Once we decide to make a release we send a PR from `development` to `master` with those changes to be added. -3. Once that PR gets merged we tag a new release with the vX.X.X scheme. \ No newline at end of file diff --git a/go.mod b/go.mod index c20ed96..73aabd3 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/gobuffalo/tags/v3 -go 1.13 +go 1.16 require ( github.com/fatih/structs v1.1.0 - github.com/gobuffalo/flect v0.2.3 - github.com/gobuffalo/validate/v3 v3.3.0 + github.com/gobuffalo/flect v0.2.4 + github.com/gobuffalo/validate/v3 v3.3.1 github.com/gofrs/uuid v4.1.0+incompatible github.com/stretchr/testify v1.7.0 ) diff --git a/go.sum b/go.sum index 848ddfd..8971844 100644 --- a/go.sum +++ b/go.sum @@ -1,26 +1,19 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/flect v0.2.3 h1:f/ZukRnSNA/DUpSNDadko7Qc0PhGvsew35p/2tu+CRY= -github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= -github.com/gobuffalo/validate/v3 v3.3.0 h1:j++FFx9gtjTmIQeI9xlaIDZ0nV4x8YQZz4RJAlZNUxg= -github.com/gobuffalo/validate/v3 v3.3.0/go.mod h1:HFpjq+AIiA2RHoQnQVTFKF/ZpUPXwyw82LgyDPxQ9r0= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gobuffalo/flect v0.2.4 h1:BSYA8+T60cdyq+vynaSUjqSVI9mDEg9ZfQUXKmfjo4I= +github.com/gobuffalo/flect v0.2.4/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8= +github.com/gobuffalo/validate/v3 v3.3.1 h1:5YLQL22YARUsYS5ZGsPU6TrD0Utiu53N1JJ5qi+foYk= +github.com/gobuffalo/validate/v3 v3.3.1/go.mod h1:Ehu8ieNJQuUM4peDDr/0VapzdGA7RgTc3wbe51vHfS0= github.com/gofrs/uuid v4.1.0+incompatible h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk= github.com/gofrs/uuid v4.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 93693610f3b22d906fa690a14e9a950c30f563cd Mon Sep 17 00:00:00 2001 From: Yonghwan SO Date: Sun, 14 Nov 2021 23:00:22 +0900 Subject: [PATCH 2/2] bootstrap 5 support for form tags (label things, help message,...) --- form/bootstrap/common.go | 63 ++++++++++++++++++++---- form/bootstrap/common_test.go | 4 +- form/bootstrap/form_for.go | 61 ++++++++++++----------- form/bootstrap/form_for_test.go | 86 ++++++++++++++++++++++++--------- form/form_for.go | 10 ++-- form/form_for_test.go | 2 +- form/select_tag_test.go | 5 +- tag.go | 5 +- 8 files changed, 159 insertions(+), 77 deletions(-) diff --git a/form/bootstrap/common.go b/form/bootstrap/common.go index d1fc778..aca962b 100644 --- a/form/bootstrap/common.go +++ b/form/bootstrap/common.go @@ -14,26 +14,37 @@ func buildOptions(opts tags.Options, err bool) { } if opts["tag_only"] != true { - opts["class"] = strings.Join([]string{fmt.Sprint(opts["class"]), "form-control"}, " ") + if opts["type"] == "checkbox" { + opts["class"] = strings.Join([]string{fmt.Sprint(opts["class"]), "form-check-input"}, " ") + } else { + opts["class"] = strings.Join([]string{fmt.Sprint(opts["class"]), "form-control"}, " ") + } } if err { opts["class"] = strings.Join([]string{fmt.Sprint(opts["class"]), "is-invalid"}, " ") } + opts["class"] = strings.TrimSpace(opts["class"].(string)) delete(opts, "hide_label") } func divWrapper(opts tags.Options, fn func(opts tags.Options) tags.Body) *tags.Tag { - divClass := "form-group" + divClass := "form-group" // btw, form-group was deprecated in Bootstrap 5 + labelClass := "form-label" hasErrors := false errors := []string{} + hasHelp := false + helpMessage := "" - if opts["errors"] != nil && len(opts["errors"].([]string)) > 0 { - divClass = "form-group has-error" - hasErrors = true - errors = opts["errors"].([]string) - delete(opts, "errors") + if opts["div_class"] != nil { + divClass = opts["div_class"].(string) + delete(opts, "div_class") + } + + if opts["label_class"] != nil { + labelClass = opts["label_class"].(string) + delete(opts, "label_class") } if opts["bootstrap"] != nil { @@ -45,6 +56,19 @@ func divWrapper(opts tags.Options, fn func(opts tags.Options) tags.Body) *tags.T delete(opts, "bootstrap") } + if opts["help"] != nil { + hasHelp = true + helpMessage = opts["help"].(string) + delete(opts, "help") + } + + if opts["errors"] != nil && len(opts["errors"].([]string)) > 0 { + divClass += " has-error" + hasErrors = true + errors = opts["errors"].([]string) + delete(opts, "errors") + } + div := tags.New("div", tags.Options{ "class": divClass, }) @@ -55,13 +79,14 @@ func divWrapper(opts tags.Options, fn func(opts tags.Options) tags.Body) *tags.T opts["label"] = flect.Titleize(tf) } } - delete(opts, "tags-field") useLabel := opts["hide_label"] == nil if useLabel && opts["label"] != nil { div.Prepend(tags.New("label", tags.Options{ - "body": opts["label"], + "for": opts["id"], + "body": opts["label"], + "class": labelClass, })) delete(opts, "label") } @@ -72,7 +97,16 @@ func divWrapper(opts tags.Options, fn func(opts tags.Options) tags.Body) *tags.T return fn(opts).(*tags.Tag) } - div.Append(fn(opts)) + isFloatingLabel := strings.Contains(divClass, "form-floating") + if opts["type"] == "checkbox" || isFloatingLabel { + if isFloatingLabel && opts["placeholder"] == nil { + // bootstrap 5 floating label requires this + opts["placeholder"] = opts["name"] + } + div.Prepend(fn(opts)) + } else { + div.Append(fn(opts)) + } if hasErrors { for _, err := range errors { @@ -82,5 +116,14 @@ func divWrapper(opts tags.Options, fn func(opts tags.Options) tags.Body) *tags.T })) } } + + if hasHelp { + div.Append(tags.New("div", tags.Options{ + "id": fmt.Sprintf("%v-help", opts["name"]), + "class": "form-text", + "body": helpMessage, + })) + } + return div } diff --git a/form/bootstrap/common_test.go b/form/bootstrap/common_test.go index c795e0a..bfb94ba 100644 --- a/form/bootstrap/common_test.go +++ b/form/bootstrap/common_test.go @@ -16,7 +16,7 @@ func Test_BootstrapFormGroupClass(t *testing.T) { expected string }{ { - expected: `
`, + expected: `
`, options: tags.Options{ "bootstrap": map[string]interface{}{ "form-group-class": "form-group row", @@ -25,7 +25,7 @@ func Test_BootstrapFormGroupClass(t *testing.T) { }, { - expected: `
`, + expected: `
`, options: tags.Options{}, }, } diff --git a/form/bootstrap/form_for.go b/form/bootstrap/form_for.go index 514adad..5ccc5b6 100644 --- a/form/bootstrap/form_for.go +++ b/form/bootstrap/form_for.go @@ -1,8 +1,7 @@ package bootstrap import ( - "fmt" - "strings" + "html/template" "github.com/gobuffalo/tags/v3" "github.com/gobuffalo/tags/v3/form" @@ -16,37 +15,43 @@ type FormFor struct { //CheckboxTag adds a checkbox to a form wrapped with a form-control and a label func (f FormFor) CheckboxTag(field string, opts tags.Options) *tags.Tag { + opts["type"] = "checkbox" + opts = f.buildOptions(field, opts) - label := field - if opts["label"] != nil { - label = fmt.Sprint(opts["label"]) - } - hl := opts["hide_label"] - delete(opts, "label") - - fieldKey := validators.GenerateKey(field) - if err := f.Errors.Get(fieldKey); err != nil { - opts["errors"] = err - } + opts["div_class"] = "form-check" + opts["label_class"] = "form-check-label" return divWrapper(opts, func(o tags.Options) tags.Body { - if o["class"] != nil { - cls := strings.Split(o["class"].(string), " ") - ncls := make([]string, 0, len(cls)) - for _, c := range cls { - if c != "form-control" { - ncls = append(ncls, c) - } - } - o["class"] = strings.Join(ncls, " ") + value := opts["value"] + delete(opts, "value") + + checked := opts["checked"] + delete(opts, "checked") + if checked == nil { + checked = "true" } - if label != "" { - o["label"] = label + opts["value"] = checked + + unchecked := opts["unchecked"] + delete(opts, "unchecked") + + if opts["tag_only"] == true { + tag := f.FormFor.InputTag(field, opts) + tag.Checked = template.HTMLEscaper(value) == template.HTMLEscaper(checked) + return tag } - if hl != nil { - o["hide_label"] = hl + + tag := f.FormFor.InputTag(field, opts) + tag.Checked = template.HTMLEscaper(value) == template.HTMLEscaper(checked) + + if opts["name"] != nil && unchecked != nil { + tag.AfterTag = append(tag.AfterTag, tags.New("input", tags.Options{ + "type": "hidden", + "name": opts["name"], + "value": unchecked, + })) } - return f.FormFor.CheckboxTag(field, o) + return tag }) } @@ -126,6 +131,6 @@ func (f FormFor) buildOptions(field string, opts tags.Options) tags.Options { if err := f.Errors.Get(fieldName); err != nil { opts["errors"] = err } - + f.FormFor.BuildOptions(field, opts) return opts } diff --git a/form/bootstrap/form_for_test.go b/form/bootstrap/form_for_test.go index 524e20c..8a33063 100644 --- a/form/bootstrap/form_for_test.go +++ b/form/bootstrap/form_for_test.go @@ -13,7 +13,16 @@ func Test_InputFieldLabel(t *testing.T) { r := require.New(t) f := NewFormFor(struct{ Name string }{}, tags.Options{}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) +} + +func Test_Input_Floating(t *testing.T) { + r := require.New(t) + f := NewFormFor(struct{ Name string }{}, tags.Options{}) + l := f.InputTag("Name", tags.Options{ + "bootstrap": map[string]interface{}{"form-group-class": "form-floating"}, + }) + r.Equal(`
`, l.String()) } func Test_InputFieldLabelWithAchronym(t *testing.T) { @@ -28,7 +37,7 @@ func Test_InputFieldLabelWithAchronym(t *testing.T) { for key, expectedLabel := range cases { l := f.InputTag(key, tags.Options{}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } } @@ -36,7 +45,7 @@ func Test_InputFieldLabel_Humanized(t *testing.T) { r := require.New(t) f := NewFormFor(struct{ LongName string }{}, tags.Options{}) l := f.InputTag("LongName", tags.Options{}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_InputFieldSchema(t *testing.T) { @@ -46,7 +55,7 @@ func Test_InputFieldSchema(t *testing.T) { }{}, tags.Options{}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_InputFieldFormInsteadOfSchema(t *testing.T) { @@ -56,7 +65,7 @@ func Test_InputFieldFormInsteadOfSchema(t *testing.T) { }{}, tags.Options{}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_InputFieldFormAndSchema(t *testing.T) { @@ -66,7 +75,7 @@ func Test_InputFieldFormAndSchema(t *testing.T) { }{}, tags.Options{}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_InputFieldSchema_FieldNotPresent(t *testing.T) { @@ -76,7 +85,7 @@ func Test_InputFieldSchema_FieldNotPresent(t *testing.T) { }{}, tags.Options{}) l := f.InputTag("Other", tags.Options{}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_InputFieldSchema_FieldDash(t *testing.T) { @@ -86,14 +95,14 @@ func Test_InputFieldSchema_FieldDash(t *testing.T) { }{}, tags.Options{}) l := f.InputTag("Name", tags.Options{}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_SelectLabel(t *testing.T) { r := require.New(t) f := NewFormFor(struct{ Name string }{}, tags.Options{}) l := f.SelectTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_Select_With_String_As_BeforeTag_Opt(t *testing.T) { @@ -103,7 +112,7 @@ func Test_Select_With_String_As_BeforeTag_Opt(t *testing.T) { s := `Test` l := f.SelectTag("Name", tags.Options{"before_tag": s}) - r.Equal(`
Test
`, l.String()) + r.Equal(`
Test
`, l.String()) } func Test_Select_With_Nested_Tag_As_BeforeTag_Opt(t *testing.T) { @@ -113,7 +122,7 @@ func Test_Select_With_Nested_Tag_As_BeforeTag_Opt(t *testing.T) { s := tags.New("span", tags.Options{"body": "Test"}) l := f.SelectTag("Name", tags.Options{"before_tag": s}) - r.Equal(`
Test
`, l.String()) + r.Equal(`
Test
`, l.String()) } func Test_Select_With_String_As_AfterTag_Opt(t *testing.T) { @@ -123,7 +132,7 @@ func Test_Select_With_String_As_AfterTag_Opt(t *testing.T) { b := `` l := f.SelectTag("Name", tags.Options{"after_tag": b}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_Select_With_Nested_Tag_As_AfterTag_Opt(t *testing.T) { @@ -136,27 +145,55 @@ func Test_Select_With_Nested_Tag_As_AfterTag_Opt(t *testing.T) { }) l := f.SelectTag("Name", tags.Options{"after_tag": b}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_RadioButton(t *testing.T) { r := require.New(t) f := NewFormFor(struct{ Name string }{}, tags.Options{}) l := f.RadioButton("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_TextArea(t *testing.T) { r := require.New(t) f := NewFormFor(struct{ Name string }{}, tags.Options{}) l := f.TextArea("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) +} + +func Test_SubmitTag(t *testing.T) { + r := require.New(t) + f := NewFormFor(struct{ Name string }{}, tags.Options{}) + i := f.SubmitTag("Send", tags.Options{"class": "btn btn-primary"}) + + r.Equal(``, i.String()) } func Test_CheckBox(t *testing.T) { r := require.New(t) f := NewFormFor(struct{ Name string }{}, tags.Options{}) l := f.CheckboxTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) +} + +func Test_CheckBox_Unchecked(t *testing.T) { + r := require.New(t) + f := NewFormFor(struct{ Name string }{}, tags.Options{}) + l := f.CheckboxTag("Name", tags.Options{ + "label": "Custom", + "unchecked": "false", + }) + r.Equal(`
`, l.String()) +} + +func Test_CheckBox_WithHelp(t *testing.T) { + r := require.New(t) + f := NewFormFor(struct{ Name string }{}, tags.Options{}) + l := f.CheckboxTag("Name", tags.Options{ + "label": "Custom", + "help": "Help message", + }) + r.Equal(`
Help message
`, l.String()) } type CustomError struct{} @@ -172,7 +209,7 @@ func Test_InputError_CustomError(t *testing.T) { f := NewFormFor(struct{ Name string }{}, tags.Options{"errors": errors}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
My Custom Error
`, l.String()) + r.Equal(`
My Custom Error
`, l.String()) } func Test_InputError(t *testing.T) { @@ -183,7 +220,7 @@ func Test_InputError(t *testing.T) { f := NewFormFor(struct{ Name string }{}, tags.Options{"errors": errors}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
Name shoud be AJ.
`, l.String()) + r.Equal(`
Name shoud be AJ.
`, l.String()) } func Test_InputHidden(t *testing.T) { @@ -209,7 +246,7 @@ func Test_InputError_Map(t *testing.T) { f := NewFormFor(struct{ Name string }{}, tags.Options{"errors": errors}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
Name shoud be AJ.
`, l.String()) + r.Equal(`
Name shoud be AJ.
`, l.String()) } func Test_InputError_InvalidMap(t *testing.T) { @@ -221,7 +258,7 @@ func Test_InputError_InvalidMap(t *testing.T) { f := NewFormFor(struct{ Name string }{}, tags.Options{"errors": errors}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
`, l.String()) + r.Equal(`
`, l.String()) } func Test_InputMultipleError(t *testing.T) { @@ -233,7 +270,7 @@ func Test_InputMultipleError(t *testing.T) { f := NewFormFor(struct{ Name string }{}, tags.Options{"errors": errors}) l := f.InputTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
Name shoud be AJ.
Name shoud start with A.
`, l.String()) + r.Equal(`
Name shoud be AJ.
Name shoud start with A.
`, l.String()) } func Test_CheckBoxError(t *testing.T) { @@ -244,7 +281,7 @@ func Test_CheckBoxError(t *testing.T) { f := NewFormFor(struct{ Name string }{}, tags.Options{"errors": errors}) l := f.CheckboxTag("Name", tags.Options{"label": "Custom"}) - r.Equal(`
Name shoud be AJ.
`, l.String()) + r.Equal(`
Name shoud be AJ.
`, l.String()) } type Person struct { @@ -270,7 +307,7 @@ func Test_FormFor_Nested_Struct(t *testing.T) { f := NewFormFor(p, tags.Options{}) tag := f.InputTag("Address.State", tags.Options{}) - exp := `
` + exp := `
` r.Equal(exp, tag.String()) } @@ -318,8 +355,9 @@ func Test_Field_TagOnly(t *testing.T) { name: "Name", opts: tags.Options{ "tag_only": true, + "class": "custom-input", }, - output: ``, + output: ``, }, { diff --git a/form/form_for.go b/form/form_for.go index 44b33ff..eaf50f1 100644 --- a/form/form_for.go +++ b/form/form_for.go @@ -15,7 +15,7 @@ import ( "github.com/gofrs/uuid" ) -var arrayFieldRegExp = regexp.MustCompile("^([A-Za-z0-9]+)\\[(\\d+)\\]$") +var arrayFieldRegExp = regexp.MustCompile(`^([A-Za-z0-9]+)\[(\d+)\]$`) // FormFor is a form made for a struct type FormFor struct { @@ -164,8 +164,11 @@ func (f FormFor) SubmitTag(value string, opts tags.Options) *tags.Tag { return f.Form.SubmitTag(value, opts) } -func (f FormFor) buildOptions(field string, opts tags.Options) { +func (f FormFor) BuildOptions(field string, opts tags.Options) { + f.buildOptions(field, opts) +} +func (f FormFor) buildOptions(field string, opts tags.Options) { if opts["value"] == nil { opts["value"] = f.value(field) } @@ -177,7 +180,6 @@ func (f FormFor) buildOptions(field string, opts tags.Options) { if opts["id"] == nil { opts["id"] = fmt.Sprintf("%s-%s", f.dashedName, opts["name"]) } - } type interfacer interface { @@ -191,7 +193,7 @@ type tagValuer interface { func (f FormFor) value(field string) interface{} { fn := f.reflection.FieldByName(field) - if fn.IsValid() == false { + if !fn.IsValid() { dots := strings.Split(field, ".") if len(dots) == 1 && !arrayFieldRegExp.Match([]byte(dots[0])) { diff --git a/form/form_for_test.go b/form/form_for_test.go index 910c166..af8f2dc 100644 --- a/form/form_for_test.go +++ b/form/form_for_test.go @@ -266,7 +266,7 @@ func Test_FormFor_Nested_Slice_Pointer_Elements(t *testing.T) { Persons []*Person }{ []*Person{ - &Person{Name: "Mark"}, + {Name: "Mark"}, }, } diff --git a/form/select_tag_test.go b/form/select_tag_test.go index cb3727a..070093c 100644 --- a/form/select_tag_test.go +++ b/form/select_tag_test.go @@ -404,10 +404,7 @@ func (sm SelectableMultipleModel) SelectValue() interface{} { } func (sm SelectableMultipleModel) IsSelected() bool { - if sm.Name == "Mark" { - return true - } - return false + return sm.Name == "Mark" } type SelectableUUIDModel struct { diff --git a/tag.go b/tag.go index 289cc90..cd0b110 100644 --- a/tag.go +++ b/tag.go @@ -170,7 +170,6 @@ func New(name string, opts Options) *Tag { tag.BeforeTag = []BeforeTag{tag.Options["before_tag"]} delete(tag.Options, "before_tag") } - if tag.Options["after_tag"] != nil { tag.AfterTag = []AfterTag{tag.Options["after_tag"]} delete(tag.Options, "after_tag") @@ -189,9 +188,8 @@ func New(name string, opts Options) *Tag { delete(tag.Options, "format") tag.Options["value"] = val.(time.Time).Format(format.(string)) default: - r := reflect.ValueOf(val) - if r.IsValid() == false { + if !r.IsValid() { tag.Options["value"] = "" } @@ -205,7 +203,6 @@ func New(name string, opts Options) *Tag { tag.Options["value"] = fmt.Sprintf("%v", value) } - } }