@@ -10,19 +10,26 @@ import (
1010 "fmt"
1111 "net/url"
1212 "reflect"
13+ "strings"
1314 "time"
1415)
1516
1617var (
1718 ErrInvalidType = errors .New ("value does not match the expected type" )
1819)
1920
21+ var replacers = strings .NewReplacer ("." , "_" , "[" , "_" , "]" , "" )
22+
23+ func generateId (name string ) string {
24+ return replacers .Replace (name )
25+ }
26+
2027func iterateFields (form * Form , fields []* FormField ) {
2128 for _ , field := range fields {
2229 field .Input .Name = field .Name
2330 configure (field , form )
2431 marshal (field , form )
25- field .Input .Id = replacers . Replace (field .Input .Name )
32+ field .Input .Id = generateId (field .Input .Name )
2633 }
2734}
2835
@@ -61,6 +68,7 @@ type MarshallerResult struct {
6168}
6269
6370func findMarshaller (rv reflect.Value ) * MarshallerResult {
71+
6472 if rv .Kind () == reflect .String {
6573 return & MarshallerResult {
6674 Marshaller : defaultMarshal ,
@@ -69,6 +77,14 @@ func findMarshaller(rv reflect.Value) *MarshallerResult {
6977 }
7078 }
7179
80+ if rv .Kind () == reflect .Slice {
81+ return & MarshallerResult {
82+ Marshaller : sliceMarshal ,
83+ Unmarshaller : sliceUnmarshal ,
84+ Type : "slice" ,
85+ }
86+ }
87+
7288 if rv .Kind () == reflect .Int ||
7389 rv .Kind () == reflect .Int8 ||
7490 rv .Kind () == reflect .Int16 ||
@@ -105,6 +121,8 @@ func findMarshaller(rv reflect.Value) *MarshallerResult {
105121 Type : "date" ,
106122 }
107123 }
124+
125+ panic (fmt .Sprintf ("Unable to find marshaller for %s" , rv .Type ()))
108126 }
109127
110128 if rv .Kind () == reflect .Ptr {
@@ -123,6 +141,8 @@ func findMarshaller(rv reflect.Value) *MarshallerResult {
123141 Type : "collection" ,
124142 }
125143 }
144+
145+ panic (fmt .Sprintf ("Unable to find marshaller for %s" , rv .Type ()))
126146 }
127147
128148 return & MarshallerResult {
@@ -139,7 +159,6 @@ func configure(field *FormField, form *Form) {
139159 }
140160
141161 if field .reflect .Kind () == reflect .Invalid && field .InitialValue != nil {
142-
143162 field .reflect = reflect .ValueOf (field .InitialValue )
144163 }
145164
@@ -162,10 +181,21 @@ func configure(field *FormField, form *Form) {
162181 }
163182}
164183
184+ func sliceMarshal (field * FormField , form * Form ) error {
185+ defaultMarshal (field , form )
186+
187+ return nil
188+ }
189+
190+ func sliceUnmarshal (field * FormField , form * Form , values url.Values ) error {
191+
192+ return nil
193+ }
194+
165195func defaultMarshal (field * FormField , form * Form ) error {
166196 field .Input .Value = fmt .Sprintf ("%s" , field .InitialValue )
167197 field .Input .Name = fmt .Sprintf ("%s%s" , field .Prefix , field .Name )
168- field .Input .Id = replacers . Replace (field .Input .Name )
198+ field .Input .Id = generateId (field .Input .Name )
169199
170200 return nil
171201}
@@ -299,7 +329,7 @@ func formMarshal(field *FormField, form *Form) error {
299329
300330 for _ , subField := range field .Children {
301331 subField .Input .Name = fmt .Sprintf ("%s.%s" , field .Name , subField .Name )
302- subField .Input .Id = replacers . Replace (subField .Input .Name )
332+ subField .Input .Id = generateId (subField .Input .Name )
303333 subField .Prefix = field .Input .Name + "."
304334 configure (subField , subForm )
305335 marshal (subField , subForm )
@@ -320,15 +350,15 @@ func collectionMarshal(field *FormField, form *Form) error {
320350 options := field .Options .(* FieldCollectionOptions )
321351
322352 field .Input .Name = fmt .Sprintf ("%s%s" , field .Prefix , field .Name )
323- field .Input .Id = replacers . Replace (field .Input .Name )
353+ field .Input .Id = generateId (field .Input .Name )
324354
325355 for _ , value := range options .Items {
326356 subForm := options .Configure (value .Value )
327357
328358 subField := create (value .Key , "form" , subForm )
329359 subField .Input .Name = fmt .Sprintf ("%s[%s]" , field .Input .Name , value .Key )
330360
331- subField .Input .Id = replacers . Replace (subField .Input .Name )
361+ subField .Input .Id = generateId (subField .Input .Name )
332362 subField .Prefix = field .Input .Name + "."
333363
334364 field .Children = append (field .Children , subField )
@@ -354,14 +384,14 @@ func collectionUnmarshal(field *FormField, form *Form, values url.Values) error
354384
355385func checkboxMarshal (field * FormField , form * Form ) error {
356386 field .Input .Name = fmt .Sprintf ("%s%s" , field .Prefix , field .Name )
357- field .Input .Id = replacers . Replace (field .Input .Name )
387+ field .Input .Id = generateId (field .Input .Name )
358388
359389 for i , option := range field .Options .(FieldOptions ) {
360390 // find a nice way to generate the name
361391 subField := CreateFormField ()
362392 subField .Name = fmt .Sprintf ("%d" , i )
363393 subField .Input .Name = fmt .Sprintf ("%s[%s]" , field .Input .Name , subField .Name )
364- subField .Input .Id = replacers . Replace (subField .Input .Name )
394+ subField .Input .Id = generateId (subField .Input .Name )
365395 subField .Label .Value = option .Label
366396 subField .Input .Type = "checkbox"
367397 subField .InitialValue = option .Checked
@@ -406,23 +436,45 @@ func checkboxUnmarshal(field *FormField, form *Form, values url.Values) error {
406436
407437func selectMarshal (field * FormField , form * Form ) error {
408438 field .Input .Name = fmt .Sprintf ("%s%s" , field .Prefix , field .Name )
409- field .Input .Id = replacers .Replace (field .Input .Name )
439+ field .Input .Id = generateId (field .Input .Name )
440+
441+ marshallers := findMarshaller (field .reflect )
442+ marshallers .Marshaller (field , form )
443+
444+ if field .reflect .Kind () == reflect .Slice {
445+ field .SetMultiple (true )
446+ }
410447
411448 for i , option := range field .Options .(FieldOptions ) {
412449 marshallers := findMarshaller (reflect .ValueOf (option .Value ))
413450
414451 // find a nice way to generate the name
415452 subField := CreateFormField ()
453+ subField .InitialValue = option .Value
416454 subField .Name = fmt .Sprintf ("%d" , i )
417- subField .Input .Name = fmt .Sprintf ("%s[%s]" , field .Input .Name , subField .Name )
418- subField .Input .Id = replacers .Replace (subField .Input .Name )
419455 subField .Label .Value = option .Label
420456 subField .Input .Type = "option"
421457 subField .Marshaller = marshallers .Marshaller
422458 subField .Unmarshaller = marshallers .Unmarshaller
423459
424460 marshal (subField , form )
425461
462+ subField .Input .Name = fmt .Sprintf ("%s[%s]" , field .Input .Name , subField .Name )
463+ subField .Input .Id = generateId (subField .Input .Name )
464+
465+ if field .reflect .Kind () == reflect .Slice {
466+ for i := 0 ; i < field .reflect .Len (); i ++ {
467+ v := field .reflect .Index (i )
468+
469+ if v .Equal (reflect .ValueOf (option .Value )) {
470+ subField .Input .Checked = true
471+ }
472+ }
473+
474+ } else {
475+ subField .Input .Checked = field .Input .Value == subField .Input .Value
476+ }
477+
426478 field .Children = append (field .Children , subField )
427479 }
428480
@@ -440,10 +492,11 @@ func selectUnmarshal(field *FormField, form *Form, values url.Values) error {
440492 field .Children [0 ].Unmarshaller (field , form , values )
441493 } else {
442494 slice := reflect .MakeSlice (reflect .SliceOf (field .reflect .Type ().Elem ()), 0 , 0 )
495+ value := reflect .Zero (field .reflect .Type ().Elem ())
443496
444497 for _ , valueStr := range values [field .Input .Id ] {
445- if value , ok := convert (valueStr , field . reflect . Type (). Elem (). Kind () ); ok {
446- slice = reflect .Append (slice , reflect .ValueOf (value ))
498+ if v , ok := StrToValue (valueStr , value ); ok {
499+ slice = reflect .Append (slice , reflect .ValueOf (v ))
447500 } else {
448501 // fmt.Printf("Unable to convert %s to %s\n", valueStr, field.reflect.Type().Elem())
449502 field .Errors = append (field .Errors , "Unable to convert value to the correct type" )
0 commit comments