Skip to content

Commit 8ba6ae7

Browse files
committed
improved
1 parent 429da68 commit 8ba6ae7

File tree

6 files changed

+202
-40
lines changed

6 files changed

+202
-40
lines changed

config/config.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,34 @@ type Config struct {
3333
Data map[string]interface{} `json:"data,omitempty"`
3434
}
3535

36+
func (c *Config) AddElement(elements ...*Element) *Config {
37+
c.Elements = append(c.Elements, elements...)
38+
return c
39+
}
40+
41+
func (c *Config) AddLanguage(languages ...*Language) *Config {
42+
c.Languages = append(c.Languages, languages...)
43+
return c
44+
}
45+
46+
func (c *Config) AddButton(buttons ...string) *Config {
47+
c.Buttons = append(c.Buttons, buttons...)
48+
return c
49+
}
50+
51+
func (c *Config) AddAttribute(attributes ...string) *Config {
52+
c.Attributes = append(c.Attributes, attributes)
53+
return c
54+
}
55+
56+
func (c *Config) Set(name string, value interface{}) *Config {
57+
if c.Data == nil {
58+
c.Data = map[string]interface{}{}
59+
}
60+
c.Data[name] = value
61+
return c
62+
}
63+
3664
func (c *Config) Clone() *Config {
3765
r := *c
3866
return &r

config/element.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,31 @@ func (e *Element) HasAttr(attrs ...string) bool {
4242
}
4343
return false
4444
}
45+
46+
func (e *Element) AddElement(elements ...*Element) *Element {
47+
e.Elements = append(e.Elements, elements...)
48+
return e
49+
}
50+
51+
func (e *Element) AddLanguage(languages ...*Language) *Element {
52+
e.Languages = append(e.Languages, languages...)
53+
return e
54+
}
55+
56+
func (e *Element) AddAttribute(attributes ...string) *Element {
57+
e.Attributes = append(e.Attributes, attributes)
58+
return e
59+
}
60+
61+
func (e *Element) AddChoice(choices ...*Choice) *Element {
62+
e.Choices = append(e.Choices, choices...)
63+
return e
64+
}
65+
66+
func (e *Element) Set(name string, value interface{}) *Element {
67+
if e.Data == nil {
68+
e.Data = map[string]interface{}{}
69+
}
70+
e.Data[name] = value
71+
return e
72+
}

forms_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package forms
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/coscms/forms/config"
8+
"github.com/webx-top/com"
9+
)
10+
11+
func TestForms(t *testing.T) {
12+
type Data struct {
13+
Test string
14+
}
15+
mp := map[string]interface{}{
16+
`name`: `test`,
17+
`age`: 20,
18+
`items`: map[string]string{
19+
`itemK1`: `itemV1`,
20+
},
21+
`data`: &Data{
22+
Test: `test-data`,
23+
},
24+
`list`: []string{
25+
`1`, `2`,
26+
},
27+
`listData`: []*Data{
28+
&Data{
29+
Test: `test-listdata-1`,
30+
}, &Data{
31+
Test: `test-listdata-2`,
32+
},
33+
},
34+
}
35+
cfg := NewConfig()
36+
cfg.AddElement(&config.Element{
37+
ID: `input-name`,
38+
Type: `text`,
39+
Name: `name`,
40+
Label: `名称`,
41+
}, &config.Element{
42+
ID: `input-items-k1`,
43+
Type: `text`,
44+
Name: `items.itemK1`,
45+
Label: `Item K1`,
46+
}, &config.Element{
47+
ID: `input-data-test`,
48+
Type: `text`,
49+
Name: `data.test`,
50+
Label: `Data`,
51+
}, &config.Element{
52+
ID: `input-list-0`,
53+
Type: `text`,
54+
Name: `list.0`,
55+
Label: `List 0`,
56+
}, &config.Element{
57+
ID: `input-list-2`,
58+
Type: `text`,
59+
Name: `list.2`,
60+
Label: `List 2`,
61+
}, &config.Element{
62+
ID: `input-listdata-0`,
63+
Type: `text`,
64+
Name: `listData.0.test`,
65+
Label: `ListData 0`,
66+
})
67+
form := NewWithModelConfig(mp, cfg)
68+
com.Dump(form.Data())
69+
result := form.String()
70+
fmt.Println(result)
71+
}

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ require (
66
github.com/admpub/fsnotify v1.5.0 // indirect
77
github.com/admpub/json5 v0.0.1
88
github.com/francoispqt/gojay v1.2.13 // indirect
9-
github.com/goccy/go-json v0.7.6 // indirect
10-
github.com/json-iterator/go v1.1.11 // indirect
9+
github.com/goccy/go-json v0.7.8 // indirect
10+
github.com/json-iterator/go v1.1.12 // indirect
1111
github.com/stretchr/testify v1.7.0
12-
github.com/webx-top/com v0.2.7
12+
github.com/webx-top/com v0.2.8
1313
github.com/webx-top/tagfast v0.0.0-20161020041435-9a2065ce3dd2
1414
github.com/webx-top/validation v0.0.3
1515
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
16-
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 // indirect
16+
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect
1717
)

go.sum

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1
88
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
99
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
1010
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
11-
github.com/admpub/fsnotify v1.4.4 h1:LhmWQAC3la+JtwlVZ42uRSahOU0lccSOZV7/hB4gqCA=
12-
github.com/admpub/fsnotify v1.4.4/go.mod h1:IE7rjoj2vwr4cYUYQFUeBV1KgldTeXTQy7TwOe0Zwlk=
1311
github.com/admpub/fsnotify v1.5.0 h1:8eYm3SBw3Y4cNt0sQIcWKd0IcsRXNYH9j308GNu66mk=
1412
github.com/admpub/fsnotify v1.5.0/go.mod h1:2YN7o9RdisXYVueAUsZxjx0Rbsiz6bu6B9XCgovJHY0=
1513
github.com/admpub/json5 v0.0.1 h1:ZgD9YKNEpOqjcg553hqi1Zv8f8tNWLjxZrFcoksCRCw=
@@ -33,6 +31,8 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
3331
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
3432
github.com/goccy/go-json v0.7.6 h1:H0wq4jppBQ+9222sk5+hPLL25abZQiRuQ6YPnjO9c+A=
3533
github.com/goccy/go-json v0.7.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
34+
github.com/goccy/go-json v0.7.8 h1:CvMH7LotYymYuLGEohBM1lTZWX4g6jzWUUl2aLFuBoE=
35+
github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
3636
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
3737
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
3838
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
@@ -56,6 +56,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
5656
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
5757
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
5858
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
59+
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
60+
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
5961
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
6062
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
6163
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -72,6 +74,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
7274
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
7375
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
7476
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
77+
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
78+
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
7579
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
7680
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
7781
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
@@ -118,6 +122,8 @@ github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49u
118122
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
119123
github.com/webx-top/com v0.2.7 h1:RPpbx9PRYo8+SbP2KwyHm1102zGW1ElTQleyyXyzqWM=
120124
github.com/webx-top/com v0.2.7/go.mod h1:DDfATzu1w5+vD5XmG3YRTfLjaIqZWi/yeJ7HQEGsM2Q=
125+
github.com/webx-top/com v0.2.8 h1:i7xHg7Ms9nJqU+z68oHyxUlMNXSLLgUKx3auLe4xMlQ=
126+
github.com/webx-top/com v0.2.8/go.mod h1:DDfATzu1w5+vD5XmG3YRTfLjaIqZWi/yeJ7HQEGsM2Q=
121127
github.com/webx-top/tagfast v0.0.0-20161020041435-9a2065ce3dd2 h1:lqnGa1BnWT7pN+c9V31bik0lTp5XxyOMRp7ICsZ6K5M=
122128
github.com/webx-top/tagfast v0.0.0-20161020041435-9a2065ce3dd2/go.mod h1:pMe3sJitHxbxX2EAI/v9HEAXjodP4c+yUVw3rbKcljI=
123129
github.com/webx-top/validation v0.0.3 h1:6vBoAp5iqjIpfFA+XoCnIzBHcuLjQzxv7MRlshptUqk=
@@ -156,12 +162,11 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
156162
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
157163
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
158164
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
159-
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
160165
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
161-
golang.org/x/sys v0.0.0-20210816032535-30e4713e60e3 h1:7hHxyYeKyS0AU/brXAMuc+9BxCO/a4vL1DoUVLDTVIo=
162-
golang.org/x/sys v0.0.0-20210816032535-30e4713e60e3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
163166
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4=
164167
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
168+
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw=
169+
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
165170
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
166171
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
167172
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

json.go

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"net/url"
2525
"path/filepath"
2626
"reflect"
27+
"strconv"
2728
"strings"
2829

2930
"github.com/admpub/json5"
@@ -319,31 +320,62 @@ func (form *Form) parseElement(ele *config.Element, typ reflect.Type, val reflec
319320
parts := strings.Split(ele.Name, `.`)
320321
isValid := true
321322
for _, field := range parts {
322-
field = strings.Title(field)
323323
if value.Kind() == reflect.Ptr {
324324
if value.IsNil() {
325-
value.Set(reflect.New(value.Type().Elem()))
325+
isValid = false
326+
break
326327
}
327328
value = value.Elem()
328329
}
329-
value = value.FieldByName(field)
330+
switch typ.Kind() {
331+
case reflect.Map:
332+
index := reflect.ValueOf(field)
333+
value = value.MapIndex(index)
334+
case reflect.Slice:
335+
index, _ := strconv.Atoi(field)
336+
if index >= value.Len() {
337+
isValid = false
338+
goto OUTLOOP
339+
}
340+
value = value.Index(index)
341+
case reflect.Struct:
342+
field = strings.Title(field)
343+
value = value.FieldByName(field)
344+
default:
345+
isValid = false
346+
goto OUTLOOP
347+
}
330348
if !value.IsValid() {
331349
isValid = false
332350
break
333351
}
352+
if value.Kind() == reflect.Interface {
353+
value = reflect.ValueOf(value.Interface())
354+
}
355+
value = reflect.Indirect(value)
356+
kind := value.Kind()
357+
if kind != reflect.Struct && kind != reflect.Map && kind != reflect.Slice {
358+
break
359+
}
360+
typ = value.Type()
334361
}
362+
363+
OUTLOOP:
335364
if isValid {
336365
sv = fmt.Sprintf("%v", value.Interface())
337366
}
338367
}
368+
isStruct := typ.Kind() == reflect.Struct
339369
switch ele.Type {
340370
case common.DATE:
341371
dateFormat := fields.DATE_FORMAT
342372
if len(ele.Format) > 0 {
343373
dateFormat = ele.Format
344-
} else if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
345-
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
346-
dateFormat = format
374+
} else if isStruct {
375+
if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
376+
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
377+
dateFormat = format
378+
}
347379
}
348380
}
349381
f = fields.TextField(ele.Name, ele.Type)
@@ -359,9 +391,11 @@ func (form *Form) parseElement(ele *config.Element, typ reflect.Type, val reflec
359391
dateFormat := fields.DATETIME_FORMAT
360392
if len(ele.Format) > 0 {
361393
dateFormat = ele.Format
362-
} else if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
363-
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
364-
dateFormat = format
394+
} else if isStruct {
395+
if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
396+
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
397+
dateFormat = format
398+
}
365399
}
366400
}
367401
f = fields.TextField(ele.Name, ele.Type)
@@ -377,9 +411,11 @@ func (form *Form) parseElement(ele *config.Element, typ reflect.Type, val reflec
377411
dateFormat := fields.DATETIME_FORMAT
378412
if len(ele.Format) > 0 {
379413
dateFormat = ele.Format
380-
} else if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
381-
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
382-
dateFormat = format
414+
} else if isStruct {
415+
if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
416+
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
417+
dateFormat = format
418+
}
383419
}
384420
}
385421
f = fields.TextField(ele.Name, ele.Type)
@@ -395,9 +431,11 @@ func (form *Form) parseElement(ele *config.Element, typ reflect.Type, val reflec
395431
dateFormat := fields.TIME_FORMAT
396432
if len(ele.Format) > 0 {
397433
dateFormat = ele.Format
398-
} else if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
399-
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
400-
dateFormat = format
434+
} else if isStruct {
435+
if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
436+
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
437+
dateFormat = format
438+
}
401439
}
402440
}
403441
f = fields.TextField(ele.Name, ele.Type)
@@ -411,26 +449,18 @@ func (form *Form) parseElement(ele *config.Element, typ reflect.Type, val reflec
411449

412450
case common.TEXT:
413451
f = fields.TextField(ele.Name, ele.Type)
414-
if len(ele.Format) > 0 { //时间格式
452+
format := ele.Format
453+
if len(format) == 0 && isStruct {
454+
if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
455+
format = tagfast.Value(typ, structField, `form_format`)
456+
}
457+
}
458+
if len(format) > 0 { //时间格式
415459
if vt, isEmpty := fields.ConvertTime(sv); !vt.IsZero() {
416-
f.SetValue(vt.Format(ele.Format))
460+
f.SetValue(vt.Format(format))
417461
} else if isEmpty {
418462
f.SetValue(``)
419463
}
420-
} else if structField, ok := typ.FieldByName(strings.Title(ele.Name)); ok {
421-
if format := tagfast.Value(typ, structField, `form_format`); len(format) > 0 {
422-
if vt, isEmpty := fields.ConvertTime(sv); !vt.IsZero() {
423-
f.SetValue(vt.Format(format))
424-
} else if isEmpty {
425-
f.SetValue(``)
426-
}
427-
} else {
428-
if len(sv) == 0 {
429-
f.SetValue(ele.Value)
430-
} else {
431-
f.SetValue(sv)
432-
}
433-
}
434464
} else {
435465
if len(sv) == 0 {
436466
f.SetValue(ele.Value)

0 commit comments

Comments
 (0)